Added two peepholes that simplify conditional jumps
[fw/sdcc] / src / pic / glue.c
index b63d7924ba1b33ba230c17520b23e382864be2d3..24ba689bf1921a8bf70b9dfde28654510c0e3ee6 100644 (file)
@@ -92,15 +92,15 @@ unsigned int pic14aopLiteral (value *val, int offset)
                 float f;
                 unsigned char c[4];
         } fl;
-        
+
         /* if it is a float then it gets tricky */
         /* otherwise it is fairly simple */
         if (!IS_FLOAT(val->type)) {
                 unsigned long v = ulFromVal (val);
-                
+
                 return ( (v >> (offset * 8)) & 0xff);
         }
-        
+
         /* it is type float */
         fl.f = (float) floatFromVal(val);
 #ifdef WORDS_BIGENDIAN
@@ -108,7 +108,7 @@ unsigned int pic14aopLiteral (value *val, int offset)
 #else
         return fl.c[offset];
 #endif
-        
+
 }
 
 #if 0
@@ -118,7 +118,7 @@ is_valid_identifier( const char *name )
   char a;
   if (!name) return 0;
   a = *name;
-  
+
   /* only accept [a-zA-Z_][a-zA-Z0-9_] */
   if (!((a >= 'a' && a <= 'z')
         || (a >= 'A' && a <= 'z')
@@ -244,7 +244,7 @@ pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf)
           }
           continue;
         }
-        
+
         if (max == -1 || addr > max) max = addr;
         if (min == -1 || addr < min) min = addr;
         //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
@@ -279,7 +279,7 @@ pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf)
           if (sym->ival) break;
       } // for
       if (sym) continue;
-      
+
       dbuf_printf (oBuf, "UD_abs_%s_%x\tudata_ovr\t0x%04x\n",
           moduleName, addr, addr);
       for (sym = setFirstItem (aliases); sym;
@@ -288,10 +288,10 @@ pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf)
         if (getSize(sym->type) > size) {
           size = getSize(sym->type);
         }
-        
+
         /* initialized values are handled somewhere else */
         if (sym->ival) continue;
-        
+
         /* emit STATUS as well as _STATUS, required for SFRs only */
         //dbuf_printf (oBuf, "%s\tres\t0\n", sym->name);
         dbuf_printf (oBuf, "%s\n", sym->rname);
@@ -315,27 +315,27 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 {
         symbol *sym;
         int bitvars = 0;;
-        
+
         /* print the area name */
         if (addPublics)
                 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
-        
+
         for (sym = setFirstItem (map->syms); sym;
         sym = setNextItem (map->syms)) {
-                
+
                 //printf("%s\n",sym->name);
 
                 /* ignore if config word */
                 if (SPEC_ABSA(sym->etype)
                     && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
                         continue;
-                
+
                 /* if extern then add it into the extern list */
                 if (IS_EXTERN (sym->etype)) {
                         addSetHead (&externs, sym);
                         continue;
                 }
-                
+
                 /* if allocation required check is needed
                 then check if the symbol really requires
                 allocation only for local variables */
@@ -343,7 +343,7 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                         !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
                         !sym->allocreq && sym->level)
                         continue;
-                
+
                 /* if global variable & not static or extern
                 and addPublics allowed then add it to the public set */
                 if ((sym->level == 0 ||
@@ -354,7 +354,7 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                         //fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name );
                         addSetHead (&publics, sym);
                 }
-                
+
                 // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
                 if (sym->_isparm)
                         continue;
@@ -380,14 +380,14 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                 /* absolute symbols are handled in pic14_constructAbsMap */
                 if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym))
                         continue;
-                
+
                 /* if it has an absolute address then generate
                 an equate for this no need to allocate space */
                 if (0 && SPEC_ABSA (sym->etype))
                 {
                         //if (options.debug || sym->level == 0)
                         //dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
-                        
+
                         dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
                                 sym->rname,
                                 SPEC_ADDR (sym->etype));
@@ -395,7 +395,7 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                 else
                 {
                         /* allocate space */
-                        
+
                         /* If this is a bit variable, then allocate storage after 8 bits have been declared */
                         /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
                         /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
@@ -407,7 +407,7 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                         {
                             if (!sym->ival) {
                                 emitSymbol (&map->oBuf,
-                                        sym->rname, 
+                                        sym->rname,
                                         NULL,
                                         getSize (sym->type) & 0xffff,
                                         SPEC_ABSA(sym->etype)
@@ -419,7 +419,7 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                 /*
                                 {
                                 int i, size;
-                                
+
                                   if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
                                   {
                                   for (i = 1; i < size; i++)
@@ -438,12 +438,12 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                     pic14_stringInSet(sym->name, &emitted, 1);
                     pic14_stringInSet(sym->rname, &emitted, 1);
                 }
-#if 0           
+#if 0
                 /* if it has a initial value then do it only if
                 it is a global variable */
                 if (sym->ival && sym->level == 0) {
                         ast *ival = NULL;
-                
+
                         if (IS_AGGREGATE (sym->type))
                                 ival = initAggregates (sym, sym->ival, NULL);
                         else
@@ -464,46 +464,46 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 /*-----------------------------------------------------------------*/
 /* printIvalType - generates ival for int/char                     */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
 {
         value *val;
         unsigned long ulval;
-        
+
         //fprintf(stderr, "%s\n",__FUNCTION__);
-        
+
         /* if initList is deep */
         if (ilist->type == INIT_DEEP)
                 ilist = ilist->init.deep;
-        
+
         if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
                 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
         }
-        
+
         if (!(val = list2val (ilist))) {
                 // assuming a warning has been thrown
-                val=constVal("0");
+                val = constCharVal (0);
         }
-        
+
         if (val->type != type) {
                 val = valCastLiteral(type, floatFromVal(val));
         }
-        
-        if(val) 
+
+        if(val)
                 ulval = ulFromVal (val);
         else
                 ulval =0;
-        
+
         switch (getSize (type)) {
         case 1:
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
                 break;
-                
+
         case 2:
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
                 break;
-                
+
         case 4:
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
@@ -516,25 +516,25 @@ printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
 /*-----------------------------------------------------------------*/
 /* printIvalBitFields - generate initializer for bitfields         */
 /*-----------------------------------------------------------------*/
-static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb ) 
+static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
 {
         value *val ;
         symbol *lsym = *sym;
         initList *lilist = *ilist ;
         unsigned long ival = 0;
         int size =0;
-        
-        
+
+
         do {
                 unsigned long i;
                 val = list2val(lilist);
                 if (size) {
                         if (SPEC_BLEN(lsym->etype) > 8) {
-                                size += ((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) + 
+                        size = ((SPEC_BLEN (lsym->etype) / 8) +
                                 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
                 }
                 i = ulFromVal (val);
@@ -551,7 +551,7 @@ static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
                 //tfprintf (oFile, "\t!db !constbyte\n",ival);
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
                 break;
-                
+
         case 2:
                 //tfprintf (oFile, "\t!dw !constword\n",ival);
                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
@@ -576,18 +576,18 @@ static void printIvalStruct (symbol * sym, sym_link * type, initList * ilist, pB
 {
         symbol *sflds;
         initList *iloop = NULL;
-        
+
         sflds = SPEC_STRUCT (type)->fields;
-        
+
         if (ilist) {
                 if (ilist->type != INIT_DEEP) {
                         werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
                         return;
                 }
-                
+
                 iloop = ilist->init.deep;
         }
-        
+
         for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
                 if (IS_BITFIELD(sflds->type)) {
                         printIvalBitFields(&sflds,&iloop,pb);
@@ -604,19 +604,19 @@ static void printIvalStruct (symbol * sym, sym_link * type, initList * ilist, pB
 /*-----------------------------------------------------------------*/
 /* printIvalChar - generates initital value for character array    */
 /*-----------------------------------------------------------------*/
-static int 
+static int
 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
 {
         value *val;
         int remain, ilen;
-        
+
         if(!pb)
                 return 0;
-        
+
         //fprintf(stderr, "%s\n",__FUNCTION__);
         if (!s)
         {
-                
+
                 val = list2val (ilist);
 
                 /* if the value is a character string  */
@@ -626,12 +626,12 @@ printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
 
                         if (!DCL_ELEM (type))
                                 DCL_ELEM (type) = ilen;
-                
+
                         /* emit string constant */
                         for (remain = 0; remain < ilen; remain++) {
                                 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain])));
                         }
-                        
+
                         /* fill array up to desired size */
                         if ((remain = (DCL_ELEM (type) - ilen)) > 0)
                                 while (remain--)
@@ -644,7 +644,7 @@ printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
         }
         else {
                 //printChar (oFile, s, strlen (s) + 1);
-                
+
                 for(remain=0; remain<(int)strlen(s); remain++) {
                         addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
                         //fprintf(stderr,"0x%02x ",s[remain]);
@@ -657,7 +657,7 @@ printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
 /*-----------------------------------------------------------------*/
 /* printIvalArray - generates code for array initialization        */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
                                 pBlock *pb)
 {
@@ -718,23 +718,23 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 /*-----------------------------------------------------------------*/
 extern value *initPointer (initList *, sym_link *toType);
 
-static void 
+static void
 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
 {
         value *val;
-        
+
         if (!ilist || !pb)
                 return;
-        
+
         fprintf (stderr, "FIXME: initializers for pointers...\n");
         printTypeChain (type, stderr);
-        
+
         fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
         fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
 
         if (ilist && (ilist->type == INIT_DEEP))
           ilist = ilist->init.deep;
-        
+
         /* function pointers */
         if (IS_FUNC (type->next))
         {
@@ -744,7 +744,7 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
 
         if (!(val = initPointer (ilist, type)))
                 return;
-        
+
         if (IS_CHAR (type->next))
         {
                 if (printIvalChar (type, ilist, pb, NULL)) return;
@@ -799,12 +799,12 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
 /*-----------------------------------------------------------------*/
 /* printIval - generates code for initial value                    */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
 {
         if (!ilist || !pb)
                 return;
-        
+
         /* if structure then    */
         if (IS_STRUCT (type))
         {
@@ -812,7 +812,7 @@ printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
                 printIvalStruct (sym, type, ilist, pb);
                 return;
         }
-        
+
         /* if this is an array   */
         if (IS_ARRAY (type))
         {
@@ -820,7 +820,7 @@ printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
                 printIvalArray (sym, type, ilist, pb);
                 return;
         }
-        
+
         /* if this is a pointer */
         if (IS_PTR (type))
         {
@@ -828,7 +828,7 @@ printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
                 printIvalPtr (sym, type, ilist, pb);
                 return;
         }
-        
+
         /* if type is SPECIFIER */
         if (IS_SPEC (type))
         {
@@ -848,11 +848,11 @@ static void
 pic14emitStaticSeg (memmap * map)
 {
         symbol *sym;
-        
+
         dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
-        
+
         //fprintf(stderr, "%s\n",__FUNCTION__);
-        
+
         /* for all variables in this segment do */
         for (sym = setFirstItem (map->syms); sym;
         sym = setNextItem (map->syms))
@@ -862,12 +862,12 @@ pic14emitStaticSeg (memmap * map)
                         addSetHead (&externs, sym);
                         continue;
                 }
-                
+
                 /* if it is not static add it to the public
                 table */
                 if (!IS_STATIC (sym->etype))
                         addSetHead (&publics, sym);
-                
+
                 /* print extra debug info if required */
                 if (options.debug || sym->level == 0)
                 {
@@ -883,15 +883,15 @@ pic14emitStaticSeg (memmap * map)
                                 dbuf_printf (&code->oBuf, "L%s_",
                                 (sym->localof ? sym->localof->name : "-null-"));
                         dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
-                        
+
                 }
-                
+
                 /* if it has an absolute address */
                 if (SPEC_ABSA (sym->etype))
                 {
                         if (options.debug || sym->level == 0)
                                 dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-                        
+
                         dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n",
                                 sym->rname,
                                 SPEC_ADDR (sym->etype));
@@ -900,13 +900,13 @@ pic14emitStaticSeg (memmap * map)
                 {
                         if (options.debug || sym->level == 0)
                                 dbuf_printf (&code->oBuf, " == .\n");
-                        
+
                         /* if it has an initial value */
                         if (sym->ival)
                         {
 #if 0
                                 pBlock *pb;
-                                
+
                                 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
                                 noAlloc++;
                                 resolveIvalSym (sym->ival, sym->type);
@@ -914,14 +914,14 @@ pic14emitStaticSeg (memmap * map)
                                 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
                                 addpBlock(pb);
                                 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
-                                
+
                                 printIval (sym, sym->type, sym->ival, pb);
                                 noAlloc--;
 #endif
                         }
                         else
                         {
-                                
+
                                 /* allocate space */
                                 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
                                 /* special case for character strings */
@@ -936,7 +936,7 @@ pic14emitStaticSeg (memmap * map)
                         }
                 }
         }
-        
+
 }
 #endif
 
@@ -973,7 +973,7 @@ pic14createInterruptVect (struct dbuf_s * vBuf)
 {
         mainf = newSymbol ("main", 0);
         mainf->block = 0;
-        
+
         /* only if the main function exists */
         if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
         {
@@ -983,7 +983,7 @@ pic14createInterruptVect (struct dbuf_s * vBuf)
                         fprintf(stderr,"WARNING: function 'main' undefined\n");
                 return;
         }
-        
+
         /* if the main is only a prototype ie. no body then do nothing */
         if (!IFFUNC_HASBODY(mainf->type))
         {
@@ -993,7 +993,7 @@ pic14createInterruptVect (struct dbuf_s * vBuf)
                         fprintf(stderr,"WARNING: function 'main' undefined\n");
                 return;
         }
-        
+
         dbuf_printf (vBuf, "%s", iComments2);
         dbuf_printf (vBuf, "; reset vector \n");
         dbuf_printf (vBuf, "%s", iComments2);
@@ -1014,7 +1014,7 @@ pic14initialComments (FILE * afile)
         initialComments (afile);
         fprintf (afile, "; PIC port for the 14-bit core\n");
         fprintf (afile, iComments2);
-        
+
 }
 
 int
@@ -1106,11 +1106,11 @@ static void
 pic14printExterns (FILE * afile)
 {
         symbol *sym;
-        
+
         fprintf (afile, "%s", iComments2);
         fprintf (afile, "; extern variables in this module\n");
         fprintf (afile, "%s", iComments2);
-        
+
         for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
                 pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
 }
@@ -1155,7 +1155,7 @@ pic14printPublics (FILE * afile)
 int
 pic14_operandsAllocatedInSameBank(const char *str1, const char *str2) {
     // see pic14printLocals
-    
+
     if (getenv("SDCC_PIC14_SPLIT_LOCALS")) {
         // no clustering applied, each register resides in its own bank
     } else {
@@ -1223,44 +1223,44 @@ static void
 pic14emitOverlay (struct dbuf_s * aBuf)
 {
         set *ovrset;
-        
+
         /*  if (!elementsInSet (ovrSetSets))*/
-        
+
         /* the hack below, fixes translates for devices which
         * only have udata_shr memory */
         dbuf_printf (aBuf, "%s\t%s\n",
                 (elementsInSet(ovrSetSets)?"":";"),
                 port->mem.overlay_name);
-        
+
         /* for each of the sets in the overlay segment do */
         for (ovrset = setFirstItem (ovrSetSets); ovrset;
         ovrset = setNextItem (ovrSetSets))
         {
-                
+
                 symbol *sym;
-                
+
                 if (elementsInSet (ovrset))
                 {
                 /* this dummy area is used to fool the assembler
                 otherwise the assembler will append each of these
                 declarations into one chunk and will not overlay
                         sad but true */
-                        
+
                         /* I don't think this applies to us. We are using gpasm.  CRF */
-                        
+
                         dbuf_printf (aBuf, ";\t.area _DUMMY\n");
                         /* output the area informtion */
                         dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name);   /* MOF */
                 }
-                
+
                 for (sym = setFirstItem (ovrset); sym;
                 sym = setNextItem (ovrset))
                 {
-                        
+
                         /* if extern then do nothing */
                         if (IS_EXTERN (sym->etype))
                                 continue;
-                        
+
                                 /* if allocation required check is needed
                                 then check if the symbol really requires
                         allocation only for local variables */
@@ -1268,18 +1268,18 @@ pic14emitOverlay (struct dbuf_s * aBuf)
                                 !(sym->_isparm && !IS_REGPARM (sym->etype))
                                 && !sym->allocreq && sym->level)
                                 continue;
-                        
+
                                 /* if global variable & not static or extern
                         and addPublics allowed then add it to the public set */
                         if ((sym->_isparm && !IS_REGPARM (sym->etype))
                                 && !IS_STATIC (sym->etype))
                                 addSetHead (&publics, sym);
-                        
+
                                 /* if extern then do nothing or is a function
                         then do nothing */
                         if (IS_FUNC (sym->type))
                                 continue;
-                        
+
                         /* print extra debug info if required */
                         if (options.debug || sym->level == 0)
                         {
@@ -1296,15 +1296,15 @@ pic14emitOverlay (struct dbuf_s * aBuf)
                                         (sym->localof ? sym->localof->name : "-null-"));
                                 dbuf_printf (aBuf, "%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 || sym->level == 0)
                                         dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-                                
+
                                 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
                                         sym->rname,
                                         SPEC_ADDR (sym->etype));
@@ -1313,12 +1313,12 @@ pic14emitOverlay (struct dbuf_s * aBuf)
                         {
                                 if (options.debug || sym->level == 0)
                                         dbuf_printf (aBuf, "==.\n");
-                                
+
                                 /* allocate space */
                                 dbuf_printf (aBuf, "%s:\n", sym->rname);
                                 dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
                         }
-                        
+
                 }
         }
 }
@@ -1337,11 +1337,11 @@ pic14_emitInterruptHandler (FILE * asmFile)
                 // Note: Do NOT name this code_interrupt to avoid nameclashes with
                 //       source files's code segment (interrupt.c -> code_interrupt)
                 fprintf (asmFile, "c_interrupt\t%s\t0x4\n", CODE_NAME);
-                
+
                 /* interrupt service routine */
                 fprintf (asmFile, "__sdcc_interrupt\n");
                 copypCode(asmFile, 'I');
-        }       
+        }
 }
 
 /*-----------------------------------------------------------------*/
@@ -1373,39 +1373,39 @@ picglue ()
 
 #if 0
         if (mainf && IFFUNC_HASBODY(mainf->type)) {
-                
+
                 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
                 addpBlock(pb);
-                
+
                 /* entry point @ start of CSEG */
                 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
                 /* put in the call to main */
                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
-                
+
                 if (options.mainreturn) {
-                        
+
                         addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
                         addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
-                        
+
                 } else {
-                        
+
                         addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
                         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
-                        
+
                 }
         }
-#endif  
-        
+#endif
+
         /* At this point we've got all the code in the form of pCode structures */
         /* Now it needs to be rearranged into the order it should be placed in the */
         /* code space */
-        
+
         movepBlock2Head('P');              // Last
         movepBlock2Head(code->dbName);
         movepBlock2Head('X');
         movepBlock2Head(statsg->dbName);   // First
-        
-        
+
+
         /* print the global struct definitions */
         if (options.debug)
                 cdbStructBlock (0);
@@ -1414,27 +1414,27 @@ picglue ()
         //pic14emitMaps ();
         /* do the overlay segments */
         pic14emitOverlay(&ovrBuf);
-        
+
         /* PENDING: this isnt the best place but it will do */
         if (port->general.glue_up_main) {
                 /* create the interrupt vector table */
                 pic14createInterruptVect (&vBuf);
         }
-        
+
         AnalyzepCode('*');
-        
+
         ReuseReg(); // ReuseReg where call tree permits
-        
+
         InlinepCode();
-        
+
         AnalyzepCode('*');
-        
+
         if (options.debug) pcode_test();
-        
-        
+
+
         /* now put it all together into the assembler file */
         /* create the assembler file name */
-        
+
         if ((noAssemble || options.c1mode) && fullDstFileName)
         {
                 sprintf (buffer, fullDstFileName);
@@ -1444,7 +1444,7 @@ picglue ()
                 sprintf (buffer, dstFileName);
                 strcat (buffer, ".asm");
         }
-        
+
         if (!(asmFile = fopen (buffer, "w"))) {
                 werror (E_FILE_OPEN_ERR, buffer);
                 exit (1);
@@ -1452,13 +1452,14 @@ picglue ()
 
         /* prepare statistics */
         resetpCodeStatistics ();
-        
+
         /* initial comments */
         pic14initialComments (asmFile);
-        
+
         /* print module name */
-        fprintf (asmFile, ";\t.module %s\n", moduleName);
-        
+        fprintf (asmFile, "%s\t.file\t\"%s\"\n",
+            options.debug ? "" : ";", fullSrcFileName);
+
         /* Let the port generate any global directives, etc. */
         if (port->genAssemblerPreamble)
         {
@@ -1467,18 +1468,18 @@ picglue ()
 
         /* print the global variables in this module */
         //pic14printPublics (asmFile);
-        
+
         /* print the extern variables in this module */
         //pic14printExterns (asmFile);
-        
+
         /* copy the sfr segment */
 #if 0
         fprintf (asmFile, "%s", iComments2);
         fprintf (asmFile, "; special function registers\n");
         fprintf (asmFile, "%s", iComments2);
         dbuf_write_and_destroy (&sfr->oBuf, asmFile);
-        
-        
+
+
         if (udata_section_name) {
                 sprintf(udata_name,"%s",udata_section_name);
         } else {
@@ -1499,24 +1500,24 @@ picglue ()
 
         /* print the locally defined variables in this module */
         writeUsedRegs(asmFile);
-        
+
         /* create the overlay segments */
         fprintf (asmFile, "%s", iComments2);
         fprintf (asmFile, "; overlayable items in internal ram \n");
-        fprintf (asmFile, "%s", iComments2);    
+        fprintf (asmFile, "%s", iComments2);
         dbuf_write_and_destroy (&ovrBuf, asmFile);
-        
+
 #if 0
-        
+
         /* create the stack segment MOF */
         if (mainf && IFFUNC_HASBODY(mainf->type)) {
                 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");
         }
-        
+
         /* create the idata segment */
         fprintf (asmFile, "%s", iComments2);
         fprintf (asmFile, "; indirectly addressable internal ram data\n");
@@ -1531,7 +1532,7 @@ picglue ()
                 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
                 fprintf (asmFile,";\t.ds 256\n");
         }
-        
+
         /* copy xtern ram data */
         fprintf (asmFile, "%s", iComments2);
         fprintf (asmFile, "; external ram data\n");
@@ -1539,7 +1540,7 @@ picglue ()
         dbuf_write_and_destroy (&xdata->oBuf, asmFile);
 
 #endif
-        
+
         /* copy the bit segment */
 #if 0
         fprintf (asmFile, "%s", iComments2);
@@ -1556,29 +1557,29 @@ picglue ()
 
         /* create interupt ventor handler */
         pic14_emitInterruptHandler (asmFile);
-        
+
         /* copy over code */
         fprintf (asmFile, "%s", iComments2);
         fprintf (asmFile, "; code\n");
         fprintf (asmFile, "%s", iComments2);
         fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
-        
+
         /* unknown */
         copypCode(asmFile, 'X');
-        
+
         /* _main function */
         copypCode(asmFile, 'M');
-        
+
         /* other functions */
         copypCode(asmFile, code->dbName);
-        
+
         /* unknown */
         copypCode(asmFile, 'P');
 
         dumppCodeStatistics (asmFile);
-        
+
         fprintf (asmFile,"\tend\n");
-        
+
         fclose (asmFile);
         pic14_debugLogClose();
 }
@@ -1653,7 +1654,7 @@ parseIvalAst (ast *node, int *inCodeSpace) {
 #define LEN 4096
     char *buffer = NULL;
     char *left, *right;
-    
+
     if (IS_AST_VALUE(node)) {
         value *val = AST_VALUE(node);
         symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
@@ -1668,11 +1669,11 @@ parseIvalAst (ast *node, int *inCodeSpace) {
         {
             *inCodeSpace = 1;
         }
-        
+
         DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
         if (IS_AST_LIT_VALUE(node)) {
             buffer = Safe_alloc(LEN);
-            SNPRINTF(buffer, LEN, "0x%lx", (long)AST_LIT_VALUE(node));
+            SNPRINTF(buffer, LEN, "0x%lx", AST_ULONG_VALUE (node));
         } else if (IS_AST_SYM_VALUE(node)) {
             assert ( AST_SYMBOL(node) );
             /*
@@ -1725,12 +1726,12 @@ parseIvalAst (ast *node, int *inCodeSpace) {
     } else {
         assert ( !"Invalid construct in initializer." );
     }
-    
+
     return (buffer);
 }
 
 /*
- * Emit the section preamble, absolute location (if any) and 
+ * Emit the section preamble, absolute location (if any) and
  * symbol name(s) for intialized data.
  */
 static int
@@ -1739,7 +1740,7 @@ emitIvalLabel(struct dbuf_s *oBuf, symbol *sym)
     char *segname;
     static int in_code = 0;
     static int sectionNr = 0;
-    
+
     if (sym) {
         // code or data space?
         if (IS_CODE(getSpec(sym->type))) {
@@ -1775,11 +1776,11 @@ emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size)
     int inCodeSpace = 0;
     char *str = NULL;
     int in_code;
-    
+
     assert (size <= sizeof(long));
     assert (!list || (list->type == INIT_NODE));
     node = list ? list->init.node : NULL;
-    
+
     in_code = emitIvalLabel(oBuf, sym);
     if (!in_code) dbuf_printf (oBuf, "\tdb\t");
 
@@ -1795,7 +1796,7 @@ emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size)
         dbuf_printf (oBuf, "\n");
         return;
     } // if
-    
+
     op = NULL;
     if (constExprTree(node) && (val = constExprValue(node, 0))) {
         op = operandFromValue(val);
@@ -1811,15 +1812,27 @@ emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size)
         assert ( !"Unhandled construct in intializer." );
     }
 
-    if (op) { 
+    if (op) {
         aopOp(op, NULL, 1);
         assert(AOP(op));
         //printOperand(op, of);
     }
-    
+
     for (i=0; i < size; i++) {
-        char *text = op ? aopGet(AOP(op), i, 0, 0)
+        char *text;
+
+        /*
+         * FIXME: This is hacky and needs some more thought.
+         */
+        if (op && IS_SYMOP(op) && IS_FUNC(OP_SYM_TYPE(op))) {
+            /* This branch is introduced to fix #1427663. */
+            PCOI(AOP(op)->aopu.pcop)->offset+=i;
+            text = get_op(AOP(op)->aopu.pcop, NULL, 0);
+            PCOI(AOP(op)->aopu.pcop)->offset-=i;
+        } else {
+            text = op ? aopGet(AOP(op), i, 0, 0)
             : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
+        } // if
         if (in_code) {
             dbuf_printf (oBuf, "\tretlw %s\n", text);
         } else {
@@ -1839,11 +1852,11 @@ static sym_link *
 matchIvalToUnion (initList *list, sym_link *type, int size)
 {
     symbol *sym;
-    
+
     assert (type);
 
     if (IS_PTR(type) || IS_CHAR(type) || IS_INT(type) || IS_LONG(type)
-            || IS_FLOAT(type)) 
+            || IS_FLOAT(type))
     {
         if (!list || (list->type == INIT_NODE)) {
             DEBUGprintf ("OK, simple type\n");
@@ -1873,13 +1886,13 @@ matchIvalToUnion (initList *list, sym_link *type, int size)
                 if (list) list = list->next;
                 sym = sym->next;
             } // while
-            
+
             // excess initializers?
             if (list) {
                 DEBUGprintf ("ERROR, excess initializers\n");
                 return (NULL);
             }
-            
+
             DEBUGprintf ("OK, struct\n");
             return (type);
         }
@@ -1955,20 +1968,20 @@ emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *li
         } // for i
         return;
     }
-    
+
     if (IS_FLOAT(my_type)) {
         // float, 32 bit
         DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
         emitIvals(oBuf, topsym, list, 0, size);
         return;
     }
-    
+
     if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
         // integral type, 8, 16, or 32 bit
         DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
         emitIvals(oBuf, topsym, list, 0, size);
         return;
-        
+
     } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
         // struct
         DEBUGprintf ("(struct, %d byte) handled below\n", size);
@@ -1982,7 +1995,7 @@ emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *li
             int len = 0;
             if (IS_BITFIELD(sym->type)) {
                 while (sym && IS_BITFIELD(sym->type)) {
-                    assert (!list || ((list->type == INIT_NODE) 
+                    assert (!list || ((list->type == INIT_NODE)
                                 && IS_AST_LIT_VALUE(list->init.node)));
                     lit = (long) (list ? list2int(list) : 0);
                     DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
@@ -1999,7 +2012,7 @@ emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *li
                 emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
                 topsym = NULL;
             } // if
-            
+
             if (sym) {
                 emitInitVal(oBuf, topsym, sym->type, list);
                 topsym = NULL;
@@ -2011,7 +2024,7 @@ emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *li
             assert ( !"Excess initializers." );
         } // if
         return;
-        
+
     } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
         // union
         DEBUGprintf ("(union, %d byte) handled below\n", size);
@@ -2029,11 +2042,11 @@ emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *li
             }
             return;
         } // if
-        
+
         assert ( !"No UNION member matches the initializer structure.");
     } else if (IS_BITFIELD(my_type)) {
         assert ( !"bitfields should only occur in structs..." );
-        
+
     } else {
         printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
         assert( !"Unhandled initialized type.");
@@ -2152,7 +2165,7 @@ showAllMemmaps(FILE *of)
         //DEBUGprintf ("memmap %i: %p\n", i, map);
         if (map) {
 #if 0
-            fprintf (stdout, ";  pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n", 
+            fprintf (stdout, ";  pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
                     map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
                     map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
                     map->codesp, map->regsp, map->syms);