* link/z80/lkgb.c,
[fw/sdcc] / src / pic16 / glue.c
index dcb109afcce5809790a44cb651ccc44219b80caa..43e01599e7671537eba4f08de82df1c18eb7a1b0 100644 (file)
 #include <string.h>
 
 
-#ifdef WORDS_BIGENDIAN
-  #define _ENDIAN(x)  (3-x)
-#else
-  #define _ENDIAN(x)  (x)
-#endif
-
-#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
 
 extern symbol *interrupts[256];
 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
@@ -809,6 +802,7 @@ void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *
     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;
@@ -817,19 +811,19 @@ void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *
   switch (size) {
   case 1:
        pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
-        break;
+       break;
 
   case 2:
        pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
        pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
-        break;
+    break;
 
   case 4: /* EEP: why is this db and not dw? */
        pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
        pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
        pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
        pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
-        break;
+    break;
   default:
        /* VR - only 1,2,4 size long can be handled???? Why? */
        fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
@@ -865,7 +859,7 @@ void pic16_printIvalStruct (symbol * sym, sym_link * type,
     iloop = ilist->init.deep;
   }
 
-  for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
+  for (; (sflds && iloop); 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);
@@ -879,6 +873,55 @@ void pic16_printIvalStruct (symbol * sym, sym_link * type,
   return;
 }
 
+/*-----------------------------------------------------------------*/
+/* printIvalUnion - generates initial value for unions             */
+/*-----------------------------------------------------------------*/
+void pic16_printIvalUnion (symbol * sym, sym_link * type,
+                 initList * ilist, char ptype, void *p)
+{
+  //symbol *sflds;
+  initList *iloop = NULL;
+  int i, size;
+
+
+#if DEBUG_PRINTIVAL
+  fprintf(stderr, "%s\n",__FUNCTION__);
+#endif
+
+  iloop = ilist;
+  i = 0;
+  while (iloop)
+  {
+    i++;
+    iloop = iloop->next;
+  } // while
+
+  size = -1;
+  if (type) size = SPEC_STRUCT(type)->size;
+
+  if (i == 1 && size >= 0 && size <= sizeof(long))
+  {
+    unsigned long val = (unsigned long)floatFromVal(list2val(ilist));
+    while (size--)
+    {
+      pic16_emitDB(val, ptype, p);
+      val >>= 8;
+    } // while
+    return;
+  } // if
+
+  fprintf( stderr, "INCOMPLETE SUPPORT FOR INITIALIZED union---FALLING BACK TO struct\n" );
+  fprintf( stderr, "This is a bug. Please file a bug-report with your source attached.\n" );
+  pic16_printIvalStruct( sym, type, ilist, ptype, p );
+}
+
+static int
+pic16_isUnion( symbol *sym, sym_link *type )
+{
+  if (type && SPEC_STRUCT(type)->type == UNION) return 1;
+  return 0;
+}
+
 /*--------------------------------------------------------------------------*/
 /* pic16_printIvalCharPtr - generates initial values for character pointers */
 /*--------------------------------------------------------------------------*/
@@ -1127,8 +1170,14 @@ void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptyp
   /* if structure then */
   if (IS_STRUCT (type))
     {
-//      fprintf(stderr,"%s struct\n",__FUNCTION__);
-      pic16_printIvalStruct (sym, type, ilist, ptype, p);
+      if (pic16_isUnion(sym, type))
+        {
+          //fprintf(stderr,"%s union\n",__FUNCTION__);
+          pic16_printIvalUnion (sym, type, ilist, ptype, p);
+       } else {
+          //fprintf(stderr,"%s struct\n",__FUNCTION__);
+          pic16_printIvalStruct (sym, type, ilist, ptype, p);
+        }
       return;
     }
 
@@ -1387,7 +1436,7 @@ void pic16_emitConfigRegs(FILE *of)
 {
   int i;
 
-       for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
+       for(i=0;i<=(pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart);i++)
                if(pic16->cwInfo.crInfo[i].emit)        //mask != -1)
                        fprintf (of, "\t__config 0x%x, 0x%hhx\n",
                                pic16->cwInfo.confAddrStart+i,
@@ -1398,7 +1447,7 @@ void pic16_emitIDRegs(FILE *of)
 {
   int i;
 
-       for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
+       for(i=0;i<=(pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart);i++)
                if(pic16->idInfo.irInfo[i].emit)
                        fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
                                pic16->idInfo.idAddrStart+i,
@@ -1460,13 +1509,16 @@ pic16initialComments (FILE * afile)
 {
        initialComments (afile);
        fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
+       if(xinst)
+         fprintf (afile, "; * Extended Instruction Set\n");
+         
        if(pic16_mplab_comp)
-               fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
+               fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
        fprintf (afile, iComments2);
 
        if(options.debug) {
-               fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
-                               SDCC_VERSION_STR, getBuildNumber() );
+               fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n",
+                               SDCC_VERSION_STR, getBuildNumber(), (!xinst?"":" {extended}") );
        }
 }