* support/regression/tests/bitfields.c:
[fw/sdcc] / src / pic16 / glue.c
index d75dd6d6a9d77ddc19f9b11b60e4dfc46e15c9c4..2d1b53161aaf21710a6b391dacd890aecd352d36 100644 (file)
@@ -51,24 +51,21 @@ extern unsigned long pFile_isize;
 
 extern unsigned long pic16_countInstructions();
 set *pic16_localFunctions = NULL;
-set *rel_idataSymSet=NULL;
-set *fix_idataSymSet=NULL;
-
-extern DEFSETFUNC (closeTmpFiles);
-extern DEFSETFUNC (rmTmpFiles);
+set *rel_idataSymSet = NULL;
+set *fix_idataSymSet = NULL;
 
 extern void pic16_AnalyzeBanking (void);
-extern void pic16_OptimizeJumps ();
-extern void pic16_OptimizeBanksel ();
-extern void pic16_InlinepCode(void);
-extern void pic16_writeUsedRegs(FILE *);
+extern void pic16_OptimizeJumps (void);
+extern void pic16_OptimizeBanksel (void);
+extern void pic16_InlinepCode (void);
+extern void pic16_writeUsedRegs (FILE *);
 
 extern void initialComments (FILE * afile);
 extern void printPublics (FILE * afile);
 
-void  pic16_pCodeInitRegisters(void);
-pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
-extern void pic16_pCodeConstString(char *name, char *value, unsigned length);
+void  pic16_pCodeInitRegisters (void);
+pCodeOp *pic16_popCopyReg (pCodeOpReg *pc);
+extern void pic16_pCodeConstString (char *name, char *value, unsigned length);
 
 
 /*-----------------------------------------------------------------*/
@@ -776,14 +773,13 @@ pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 /* pic16_printIvalBitFields - generate initializer for bitfields   */
 /*-----------------------------------------------------------------*/
 static void
-pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
+pic16_printIvalBitFields (symbol **sym, initList **ilist, char ptype, void *p)
 {
-  value *val ;
   symbol *lsym = *sym;
-  initList *lilist = *ilist ;
+  initList *lilist = *ilist;
   unsigned long ival = 0;
+  int size = 0;
   unsigned long i;
-  int size =0;
 
 
 #if DEBUG_PRINTIVAL
@@ -791,31 +787,36 @@ pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
 #endif
 
 
-  do {
-    val = list2val(lilist);
-    if (size) {
-      if (SPEC_BLEN(lsym->etype) > 8) {
-        size += ((SPEC_BLEN (lsym->etype) / 8) +
-                 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
-      }
-    } else {
-      size = ((SPEC_BLEN (lsym->etype) / 8) +
-              (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+  while (lsym)
+    {
+      if (0 == SPEC_BLEN (lsym->etype))
+        {
+          /* bit-field structure member with a width of 0 */
+          lsym = lsym->next;
+          break;
+        }
+      else if (!SPEC_BUNNAMED (lsym->etype))
+        {
+          /* not an unnamed bit-field structure member */
+          value *val = list2val (lilist);
+          int bit_length = SPEC_BLEN (lsym->etype);
+
+          if (size)
+            {
+              if (bit_length > 8)
+                size += (bit_length + 7) / 8;
+            }
+          else
+            size = (bit_length + 7) / 8;
+
+          ival |= (ulFromVal (val) & ((1ul << bit_length) - 1ul)) << SPEC_BSTR (lsym->etype);
+          lilist = lilist->next;
+        }
+      lsym = lsym->next;
     }
-    i = (ulFromVal (val) & ((1ul << SPEC_BLEN (lsym->etype)) - 1ul));
-    i <<= SPEC_BSTR (lsym->etype);
-    ival |= i;
-    if (! ( lsym->next &&
-          (lilist && lilist->next) &&
-          (IS_BITFIELD(lsym->next->type)) &&
-          (SPEC_BSTR(lsym->next->etype)))) break;
-    lsym = lsym->next;
-    lilist = lilist->next;
-  } while (1);
-
-  for (i = 0; i < size; i++) {
-    pic16_emitDB(BYTE_IN_LONG(ival, i), ptype, p);
-  } // for
+
+  for (i = 0; i < size; i++)
+    pic16_emitDB (BYTE_IN_LONG (ival, i), ptype, p);
 
   *sym = lsym;
   *ilist = lilist;
@@ -839,27 +840,33 @@ pic16_printIvalStruct (symbol * sym, sym_link * type,
 
   sflds = SPEC_STRUCT (type)->fields;
 
-  if (ilist) {
-    if (ilist->type != INIT_DEEP) {
-      werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
-      return;
-    }
+  if (ilist)
+    {
+      if (ilist->type != INIT_DEEP)
+        {
+          werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
+          return;
+        }
 
-    iloop = ilist->init.deep;
-  }
+      iloop = ilist->init.deep;
+    }
 
-  for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
-//    fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
-    if (IS_BITFIELD(sflds->type)) {
-      pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
-    } else {
-      pic16_printIval (sym, sflds->type, iloop, ptype, p);
+  while (sflds)
+    {
+//      fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
+      if (IS_BITFIELD (sflds->type))
+        {
+          pic16_printIvalBitFields (&sflds, &iloop, ptype, p);
+        }
+      else
+        {
+          pic16_printIval (sym, sflds->type, iloop, ptype, p);
+          sflds = sflds->next;
+          iloop = iloop ? iloop->next : NULL;
+        }
     }
-  }
-  if (iloop) {
+  if (iloop)
     werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
-  }
-  return;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1221,68 +1228,76 @@ static void
 pic16emitStaticSeg (memmap * map)
 {
   symbol *sym;
-  static int didcode=0;
+  static int didcode = 0;
 
   //fprintf(stderr, "%s\n",__FUNCTION__);
 
-  pic16_initDB();
+  pic16_initDB ();
 
   /* for all variables in this segment do */
-  for (sym = setFirstItem (map->syms); sym;
-       sym = setNextItem (map->syms))
+  for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
     {
 
 #if 0
-        fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
-CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
-                map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
-                IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
-                IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
-        printTypeChain( sym->type, stderr );
-        fprintf(stderr, "\n");
+      fprintf (stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
+CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__, map->sname, sym->name, sym->used, SPEC_ABSA (sym->etype), IS_AGGREGATE (sym->type), IS_CODE (sym->etype), IN_CODESPACE (SPEC_OCLS (sym->etype)), IS_CONSTANT (sym->etype), IS_PTR_CONST (sym->etype), SPEC_CONST (sym->etype));
+      printTypeChain (sym->type, stderr);
+      fprintf (stderr, "\n");
 #endif
 
-        if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
-                pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
-                        (int) ulFromVal (list2val(sym->ival)));
+      if (SPEC_ABSA (sym->etype) && PIC16_IS_CONFIG_ADDRESS (SPEC_ADDR (sym->etype)))
+        {
+          pic16_assignConfigWordValue (SPEC_ADDR (sym->etype), (int) ulFromVal (list2val (sym->ival)));
 
-                continue;
+          continue;
         }
 
-        if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
-                pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
-                        (char) ulFromVal (list2val(sym->ival)));
+      if (SPEC_ABSA (sym->etype) && PIC16_IS_IDLOC_ADDRESS (SPEC_ADDR (sym->etype)))
+        {
+          pic16_assignIdByteValue (SPEC_ADDR (sym->etype), (char) ulFromVal (list2val (sym->ival)));
 
-                continue;
+          continue;
         }
 
-        /* if it is "extern" then do nothing */
-        if (IS_EXTERN (sym->etype)/* && !SPEC_ABSA(sym->etype)*/) {
-                checkAddSym(&externs, sym);
+      /* if it is "extern" then do nothing */
+      if (IS_EXTERN (sym->etype) /* && !SPEC_ABSA(sym->etype) */ )
+        {
+          checkAddSym (&externs, sym);
           continue;
         }
 
-        /* if it is not static add it to the public
-           table */
-        if (!IS_STATIC (sym->etype)) {
-                /* do not emit if it is a config word declaration */
-                checkAddSym(&publics, sym);
+      /* if it is not static add it to the public
+         table */
+      if (!IS_STATIC (sym->etype))
+        {
+          /* do not emit if it is a config word declaration */
+          checkAddSym (&publics, sym);
         }
 
       /* print extra debug info if required */
-      if (options.debug || sym->level == 0) {
+      if (options.debug || sym->level == 0)
+        {
           /* NOTE to me - cdbFile may be null in which case,
            * the sym name will be printed to stdout. oh well */
-           debugFile->writeSymbol(sym);
-      }
+          debugFile->writeSymbol (sym);
+        }
 
       /* if it has an absolute address */
-      if (SPEC_ABSA (sym->etype)) {
-//              fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
-//                      __FILE__, __LINE__, sym->name);
+      if (SPEC_ABSA (sym->etype))
+        {
+//        fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
+//                __FILE__, __LINE__, sym->name);
 
-          /* if it has an initial value */
-          if (sym->ival)
+          if (!sym->ival && IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char)
+            {
+              /* symbol has absolute address but no initial value */
+              /* special case for character strings */
+
+//            fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
+
+              pic16_pCodeConstString (sym->rname, SPEC_CVAL (sym->etype).v_char, getSize (sym->type));
+            }
+          else
             {
               pBlock *pb;
               symbol *asym;
@@ -1290,57 +1305,43 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
               pCode *pcf;
 
               /* symbol has absolute address and initial value */
-              noAlloc++;
+              ++noAlloc;
               resolveIvalSym (sym->ival, sym->type);
-              asym = newSymbol(sym->rname, 0);
-              abSym = Safe_calloc(1, sizeof(absSym));
-              strcpy(abSym->name, sym->rname);
-              abSym->address = SPEC_ADDR( sym->etype );
-              addSet(&absSymSet, abSym);
+              asym = newSymbol (sym->rname, 0);
+              abSym = Safe_calloc (1, sizeof (absSym));
+              strcpy (abSym->name, sym->rname);
+              abSym->address = SPEC_ADDR (sym->etype);
+              addSet (&absSymSet, abSym);
 
-              pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
-              pic16_addpBlock(pb);
+              pb = pic16_newpCodeChain (NULL, 'A', pic16_newpCodeCharP ("; Starting pCode block for absolute Ival"));
+              pic16_addpBlock (pb);
 
-              pcf = pic16_newpCodeFunction(moduleName, asym->name);
-              PCF(pcf)->absblock = 1;
+              pcf = pic16_newpCodeFunction (moduleName, asym->name);
+              PCF (pcf)->absblock = 1;
 
-              pic16_addpCode2pBlock(pb,pcf);
-              pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
+              pic16_addpCode2pBlock (pb, pcf);
+              pic16_addpCode2pBlock (pb, pic16_newpCodeLabel (sym->rname, -1));
               //fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
-              pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
-              pic16_flushDB('p', (void *)pb);
-
-              pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
-              noAlloc--;
-            }
-          else
-            {
-
-              /* symbol has absolute address but no initial value */
-
-              /* allocate space */
-              dbuf_printf (&code->oBuf, "%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) {
-
-//              fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
+              /* if it has an initial value */
+              if (sym->ival)
+                {
+                  pic16_printIval (sym, sym->type, sym->ival, 'p', (void *) pb);
+                  pic16_flushDB ('p', (void *) pb);
+                }
 
-                pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char, getSize(sym->type));
-              } else {
-                fprintf (stderr, "%s:%u(%s): do not know how to intialize symbol %s\n", __FILE__, __LINE__, __FUNCTION__, sym->rname);
-                assert(0);
-              }
+              pic16_addpCode2pBlock (pb, pic16_newpCodeFunction (NULL, NULL));
+              --noAlloc;
             }
-
-        } else {
-//              fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
-//                      __FILE__, __LINE__, sym->name);
+        }
+      else
+        {
+//        fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
+//               __FILE__, __LINE__, sym->name);
 
 
           /* if it has an initial value */
-          if (sym->ival) {
+          if (sym->ival)
+            {
               pBlock *pb;
 
               /* symbol doesn't have absolute address but has initial value */
@@ -1348,44 +1349,47 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
               ++noAlloc;
               resolveIvalSym (sym->ival, sym->type);
 
-              pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
-              pic16_addpBlock(pb);
+              pb = pic16_newpCodeChain (NULL, 'P', pic16_newpCodeCharP ("; Starting pCode block for Ival"));
+              pic16_addpBlock (pb);
 
-              if(!didcode) {
-                /* make sure that 'code' directive is emitted before, once */
-                pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
+              if (!didcode)
+                {
+                  /* make sure that 'code' directive is emitted before, once */
+                  pic16_addpCode2pBlock (pb, pic16_newpCodeAsmDir ("code", NULL));
 
-                didcode++;
-              }
+                  ++didcode;
+                }
 
-              pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
+              pic16_addpCode2pBlock (pb, pic16_newpCodeLabel (sym->rname, -1));
               //fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
-              pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
-              pic16_flushDB('p', (void *)pb);
+              pic16_printIval (sym, sym->type, sym->ival, 'p', (void *) pb);
+              pic16_flushDB ('p', (void *) pb);
               --noAlloc;
-            } else {
+            }
+          else
+            {
 
               /* symbol doesn't have absolute address and no initial value */
               /* allocate space */
 //            fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
               dbuf_printf (&code->oBuf, "%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) {
+              if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char)
+                {
 
-//              fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
+//                fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
 
-                pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char, getSize(sym->type));
-              } else {
-                assert(0);
-              }
+                  pic16_pCodeConstString (sym->rname, SPEC_CVAL (sym->etype).v_char, getSize (sym->type));
+                }
+              else
+                {
+                  assert (0);
+                }
             }
         }
     }
-
 }
 
-
 /*-----------------------------------------------------------------*/
 /* pic16_emitConfigRegs - emits the configuration registers              */
 /*-----------------------------------------------------------------*/
@@ -1474,7 +1478,7 @@ pic16initialComments (FILE * afile)
     if (pic16_mplab_comp) {
         fprintf(afile, "; * MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
     } // if
-    fprintf (afile, iComments2);
+    fprintf (afile, "%s", iComments2);
 
     if (options.debug) {
         fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n",
@@ -1744,7 +1748,7 @@ pic16glue ()
     if(pic16_options.dumpcalltree) {
       FILE *cFile;
 
-        sprintf(buffer, dstFileName);
+        sprintf(buffer, "%s", dstFileName);
         strcat(buffer, ".calltree");
         cFile = fopen(buffer, "w");
         pic16_printCallTree( cFile );
@@ -1762,9 +1766,9 @@ pic16glue ()
     /* now put it all together into the assembler file */
     /* create the assembler file name */
     if((noAssemble || options.c1mode)  && fullDstFileName) {
-      sprintf (buffer, fullDstFileName);
+      sprintf (buffer, "%s", fullDstFileName);
     } else {
-      sprintf (buffer, dstFileName);
+      sprintf (buffer, "%s", dstFileName);
       strcat (buffer, ".asm");
     }