* support/regression/tests/bitfields.c:
[fw/sdcc] / src / SDCCglue.c
1 /*-------------------------------------------------------------------------
2
3   SDCCglue.c - glues everything we have done together into one file.
4                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26 #include <time.h>
27 #include "newalloc.h"
28 #include <fcntl.h>
29 #include <sys/stat.h>
30 #include "dbuf_string.h"
31
32 #ifdef _WIN32
33 #include <io.h>
34 #else
35 #include <unistd.h>
36 #endif
37
38 symbol *interrupts[INTNO_MAX+1];
39
40 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *, bool check);
41 set *publics = NULL;            /* public variables */
42 set *externs = NULL;            /* Variables that are declared as extern */
43
44 unsigned maxInterrupts = 0;
45 int allocInfo = 1;
46 symbol *mainf;
47 int noInit = 0;                 /* no initialization */
48
49
50 char *
51 aopLiteralLong (value * val, int offset, int size)
52 {
53   union {
54     float f;
55     unsigned char c[4];
56   }
57   fl;
58
59   if (!val) {
60     // assuming we have been warned before
61     val = constCharVal (0);
62   }
63
64   /* if it is a float then it gets tricky */
65   /* otherwise it is fairly simple */
66   if (!IS_FLOAT (val->type)) {
67     unsigned long v = ulFromVal (val);
68
69     v >>= (offset * 8);
70     switch (size) {
71     case 1:
72       tsprintf (buffer, sizeof(buffer),
73           "!immedbyte", (unsigned int) v & 0xff);
74       break;
75     case 2:
76       tsprintf (buffer, sizeof(buffer),
77           "!immedword", (unsigned int) v & 0xffff);
78       break;
79     default:
80       /* Hmm.  Too big for now. */
81       assert (0);
82     }
83     return Safe_strdup (buffer);
84   }
85
86   /* PENDING: For now size must be 1 */
87   assert (size == 1);
88
89   /* it is type float */
90   fl.f = (float) floatFromVal (val);
91 #ifdef WORDS_BIGENDIAN
92   tsprintf (buffer, sizeof(buffer),
93       "!immedbyte", fl.c[3 - offset]);
94 #else
95   tsprintf (buffer, sizeof(buffer),
96       "!immedbyte", fl.c[offset]);
97 #endif
98   return Safe_strdup (buffer);
99 }
100
101 /*-----------------------------------------------------------------*/
102 /* aopLiteral - string from a literal value                        */
103 /*-----------------------------------------------------------------*/
104 char *
105 aopLiteral (value * val, int offset)
106 {
107   return aopLiteralLong (val, offset, 1);
108 }
109
110 /*-----------------------------------------------------------------*/
111 /* emitRegularMap - emit code for maps with no special cases       */
112 /*-----------------------------------------------------------------*/
113 static void
114 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
115 {
116   symbol *sym;
117   ast *ival = NULL;
118
119   if (!map)
120     return;
121
122   if (addPublics)
123     {
124       /* PENDING: special case here - should remove */
125       if (!strcmp (map->sname, CODE_NAME))
126         dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
127       else if (!strcmp (map->sname, DATA_NAME))
128         dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
129       else if (!strcmp (map->sname, HOME_NAME))
130         dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
131       else
132         dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
133     }
134
135   for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
136     {
137       symbol *newSym = NULL;
138
139       /* if extern then add it into the extern list */
140       if (IS_EXTERN (sym->etype))
141         {
142           addSetHead (&externs, sym);
143           continue;
144         }
145
146       /* if allocation required check is needed
147          then check if the symbol really requires
148          allocation only for local variables */
149
150       if (arFlag && !IS_AGGREGATE (sym->type) &&
151           !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
152           !sym->allocreq && sym->level)
153         continue;
154
155       /* for bitvar locals and parameters */
156       if (!arFlag && !sym->allocreq && sym->level
157           && !SPEC_ABSA (sym->etype))
158         {
159           continue;
160         }
161
162       /* if global variable & not static or extern
163          and addPublics allowed then add it to the public set */
164       if ((sym->level == 0 ||
165            (sym->_isparm && !IS_REGPARM (sym->etype))) &&
166           addPublics &&
167           !IS_STATIC (sym->etype) &&
168           (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : 1))
169         {
170           addSetHead (&publics, sym);
171         }
172
173       /* if extern then do nothing or is a function
174          then do nothing */
175       if (IS_FUNC (sym->type) && !(sym->isitmp))
176         continue;
177
178       /* print extra debug info if required */
179       if (options.debug)
180         {
181           if (!sym->level) /* global */
182             {
183               if (IS_STATIC (sym->etype))
184                 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
185               else
186                 dbuf_printf (&map->oBuf, "G$");     /* scope is global */
187             }
188           else
189             {
190               /* symbol is local */
191               dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
192             }
193           dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
194         }
195
196       /* if it has an initial value then do it only if
197          it is a global variable */
198       if (sym->ival && sym->level == 0)
199         {
200           if ((SPEC_OCLS (sym->etype) == xidata) && !SPEC_ABSA (sym->etype))
201             {
202               /* create a new "XINIT (CODE)" symbol, that will be emitted later
203                  in the static seg */
204               newSym=copySymbol (sym);
205               SPEC_OCLS(newSym->etype)=xinit;
206               SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
207               SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
208               if (IS_SPEC (newSym->type))
209                 SPEC_CONST (newSym->type) = 1;
210               else
211                 DCL_PTR_CONST (newSym->type) = 1;
212               SPEC_STAT(newSym->etype)=1;
213               resolveIvalSym(newSym->ival, newSym->type);
214
215               // add it to the "XINIT (CODE)" segment
216               addSet(&xinit->syms, newSym);
217
218               if (!SPEC_ABSA (sym->etype))
219                 {
220                   struct dbuf_s tmpBuf;
221
222                   dbuf_init(&tmpBuf, 4096);
223                   // before allocation we must parse the sym->ival tree
224                   // but without actually generating initialization code
225                   ++noAlloc;
226                   resolveIvalSym (sym->ival, sym->type);
227                   ++noInit;
228                   printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
229                   --noInit;
230                   --noAlloc;
231                   dbuf_destroy(&tmpBuf);
232                 }
233             }
234           else
235             {
236               if (IS_AGGREGATE (sym->type))
237                 {
238                   ival = initAggregates (sym, sym->ival, NULL);
239                 }
240               else
241                 {
242                   if (getNelements (sym->type, sym->ival)>1)
243                     {
244                       werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
245                     }
246                   ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
247                                   decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
248                 }
249               codeOutBuf = &statsg->oBuf;
250
251               if (ival)
252                 {
253                   // set ival's lineno to where the symbol was defined
254                   setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
255                   // check if this is not a constant expression
256                   if (!constExprTree (ival))
257                     {
258                       werror (E_CONST_EXPECTED, "found expression");
259                     // but try to do it anyway
260                     }
261                   allocInfo = 0;
262                   if (!astErrors (ival))
263                     eBBlockFromiCode (iCodeFromAst (ival));
264                   allocInfo = 1;
265                 }
266             }
267         }
268
269       /* if it has an absolute address then generate
270          an equate for this no need to allocate space */
271       if (SPEC_ABSA (sym->etype) && !sym->ival)
272         {
273           char *equ = "=";
274           if (options.debug) {
275             dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
276           }
277           if (TARGET_IS_XA51)
278             {
279               if (map == sfr)
280                 {
281                   equ = "sfr";
282                 }
283               else if (map == bit || map == sfrbit)
284                 {
285                   equ="bit";
286                 }
287             }
288           dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
289         }
290       else
291         {
292           int size = getSize (sym->type) + sym->flexArrayLength;
293           if (size == 0)
294             {
295               werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
296             }
297           /* allocate space */
298           if (options.debug)
299             {
300               dbuf_printf (&map->oBuf, "==.\n");
301             }
302           if (SPEC_ABSA (sym->etype))
303             {
304               dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
305             }
306           if (IS_STATIC (sym->etype) || sym->level)
307             dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
308           else
309             dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
310           dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
311         }
312       sym->ival = NULL;
313     }
314 }
315
316 /*-----------------------------------------------------------------*/
317 /* initPointer - pointer initialization code massaging             */
318 /*-----------------------------------------------------------------*/
319 value *
320 initPointer (initList * ilist, sym_link *toType)
321 {
322   value *val;
323   ast *expr;
324
325   if (!ilist) {
326       return valCastLiteral(toType, 0.0);
327   }
328
329   expr = list2expr (ilist);
330
331   if (!expr)
332     goto wrong;
333
334   /* try it the old way first */
335   if ((val = constExprValue (expr, FALSE)))
336     return val;
337
338   /* ( ptr + constant ) */
339   if (IS_AST_OP (expr) &&
340       (expr->opval.op == '+' || expr->opval.op == '-') &&
341       IS_AST_SYM_VALUE (expr->left) &&
342       (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
343       compareType(toType, expr->left->ftype) &&
344       IS_AST_LIT_VALUE (expr->right)) {
345     return valForCastAggr (expr->left, expr->left->ftype,
346                            expr->right,
347                            expr->opval.op);
348   }
349
350   /* (char *)&a */
351   if (IS_AST_OP(expr) && expr->opval.op==CAST &&
352       IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
353     if (compareType(toType, expr->left->ftype)!=1) {
354       werror (W_INIT_WRONG);
355       printFromToType(expr->left->ftype, toType);
356     }
357     // skip the cast ???
358     expr=expr->right;
359   }
360
361   /* no then we have to do these cludgy checks */
362   /* pointers can be initialized with address of
363      a variable or address of an array element */
364   if (IS_AST_OP (expr) && expr->opval.op == '&') {
365     /* address of symbol */
366     if (IS_AST_SYM_VALUE (expr->left)) {
367       val = AST_VALUE (expr->left);
368       val->type = newLink (DECLARATOR);
369       if (SPEC_SCLS (expr->left->etype) == S_CODE) {
370         DCL_TYPE (val->type) = CPOINTER;
371         DCL_PTR_CONST (val->type) = port->mem.code_ro;
372       }
373       else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
374         DCL_TYPE (val->type) = FPOINTER;
375       else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
376         DCL_TYPE (val->type) = PPOINTER;
377       else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
378         DCL_TYPE (val->type) = IPOINTER;
379       else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
380         DCL_TYPE (val->type) = EEPPOINTER;
381       else
382         DCL_TYPE (val->type) = POINTER;
383       val->type->next = expr->left->ftype;
384       val->etype = getSpec (val->type);
385       return val;
386     }
387
388     /* if address of indexed array */
389     if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
390       return valForArray (expr->left);
391
392     /* if address of structure element then
393        case 1. a.b ; */
394     if (IS_AST_OP (expr->left) &&
395         expr->left->opval.op == '.') {
396       return valForStructElem (expr->left->left,
397                                expr->left->right);
398     }
399
400     /* case 2. (&a)->b ;
401        (&some_struct)->element */
402     if (IS_AST_OP (expr->left) &&
403         expr->left->opval.op == PTR_OP &&
404         IS_ADDRESS_OF_OP (expr->left->left)) {
405       return valForStructElem (expr->left->left->left,
406                                expr->left->right);
407     }
408   }
409   /* case 3. (((char *) &a) +/- constant) */
410   if (IS_AST_OP (expr) &&
411       (expr->opval.op == '+' || expr->opval.op == '-') &&
412       IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
413       IS_AST_OP (expr->left->right) &&
414       expr->left->right->opval.op == '&' &&
415       IS_AST_LIT_VALUE (expr->right)) {
416
417     return valForCastAggr (expr->left->right->left,
418                            expr->left->left->opval.lnk,
419                            expr->right, expr->opval.op);
420
421   }
422   /* case 4. (char *)(array type) */
423   if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
424       IS_ARRAY(expr->right->ftype)) {
425
426     val = copyValue (AST_VALUE (expr->right));
427     val->type = newLink (DECLARATOR);
428     if (SPEC_SCLS (expr->right->etype) == S_CODE) {
429       DCL_TYPE (val->type) = CPOINTER;
430       DCL_PTR_CONST (val->type) = port->mem.code_ro;
431     }
432     else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
433       DCL_TYPE (val->type) = FPOINTER;
434     else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
435       DCL_TYPE (val->type) = PPOINTER;
436     else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
437       DCL_TYPE (val->type) = IPOINTER;
438     else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
439       DCL_TYPE (val->type) = EEPPOINTER;
440     else
441       DCL_TYPE (val->type) = POINTER;
442     val->type->next = expr->right->ftype->next;
443     val->etype = getSpec (val->type);
444     return val;
445   }
446  wrong:
447   if (expr)
448     werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
449   else
450     werror (E_INCOMPAT_PTYPES);
451   return NULL;
452
453 }
454
455 /*-----------------------------------------------------------------*/
456 /* printChar - formats and prints a characater string with DB      */
457 /*-----------------------------------------------------------------*/
458 void
459 printChar (struct dbuf_s * oBuf, char *s, int plen)
460 {
461   int i;
462   int len = plen;
463   int pplen = 0;
464   char buf[100];
465   char *p = buf;
466
467   while (len && pplen < plen)
468     {
469       i = 60;
470       while (i && pplen < plen)
471         {
472           if (*s < ' ' || *s == '\"' || *s=='\\')
473             {
474               *p = '\0';
475               if (p != buf)
476                 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
477               dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
478               p = buf;
479             }
480           else
481             {
482               *p = *s;
483               p++;
484             }
485           s++;
486           pplen++;
487           i--;
488         }
489       if (p != buf)
490         {
491           *p = '\0';
492           dbuf_tprintf (oBuf, "\t!ascii\n", buf);
493           p = buf;
494         }
495
496       if (len > 60)
497         len -= 60;
498       else
499         len = 0;
500     }
501   while (pplen < plen)
502     {
503       dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
504       pplen++;
505     }
506 }
507
508 /*-----------------------------------------------------------------*/
509 /* return the generic pointer high byte for a given pointer type.  */
510 /*-----------------------------------------------------------------*/
511 int
512 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
513 {
514   switch (p_type)
515     {
516     case IPOINTER:
517     case POINTER:
518       return GPTYPE_NEAR;
519     case GPOINTER:
520       werror (E_CANNOT_USE_GENERIC_POINTER,
521               iname ? iname : "<null>",
522               oname ? oname : "<null>");
523       exit (1);
524     case FPOINTER:
525       return GPTYPE_FAR;
526     case CPOINTER:
527       return GPTYPE_CODE;
528     case PPOINTER:
529       return GPTYPE_XSTACK;
530     default:
531       fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
532                p_type);
533       break;
534     }
535   return -1;
536 }
537
538
539 /*-----------------------------------------------------------------*/
540 /* printPointerType - generates ival for pointer type              */
541 /*-----------------------------------------------------------------*/
542 void
543 _printPointerType (struct dbuf_s * oBuf, const char *name)
544 {
545   if (options.model == MODEL_FLAT24)
546     {
547       if (port->little_endian)
548         dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
549       else
550         dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
551     }
552   else
553     {
554       if (port->little_endian)
555         dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
556       else
557         dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
558     }
559 }
560
561 /*-----------------------------------------------------------------*/
562 /* printPointerType - generates ival for pointer type              */
563 /*-----------------------------------------------------------------*/
564 void
565 printPointerType (struct dbuf_s * oBuf, const char *name)
566 {
567   _printPointerType (oBuf, name);
568   dbuf_printf (oBuf, "\n");
569 }
570
571 /*-----------------------------------------------------------------*/
572 /* printGPointerType - generates ival for generic pointer type     */
573 /*-----------------------------------------------------------------*/
574 void
575 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
576                    const unsigned int type)
577 {
578   _printPointerType (oBuf, iname);
579   dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
580 }
581
582 /*-----------------------------------------------------------------*/
583 /* printIvalType - generates ival for int/char                     */
584 /*-----------------------------------------------------------------*/
585 void
586 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
587 {
588   value *val;
589
590   /* if initList is deep */
591   if (ilist && (ilist->type == INIT_DEEP))
592     ilist = ilist->init.deep;
593
594   if (!(val = list2val (ilist))) {
595     // assuming a warning has been thrown
596     val = constCharVal (0);
597   }
598
599   /* check if the literal value is within bounds */
600   if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
601       !options.lessPedantic)
602     {
603       werror (W_LIT_OVERFLOW);
604     }
605
606   if (val->type != type) {
607     val = valCastLiteral(type, floatFromVal(val));
608   }
609
610   switch (getSize (type)) {
611   case 1:
612     if (!val)
613       dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
614     else
615       dbuf_tprintf (oBuf, "\t!dbs\n",
616                 aopLiteral (val, 0));
617     break;
618
619   case 2:
620     if (port->use_dw_for_init)
621       dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
622     else if (port->little_endian)
623       dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
624     else
625       dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
626     break;
627   case 4:
628     if (!val) {
629       dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
630       dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
631     }
632     else if (port->little_endian) {
633       dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
634                aopLiteral (val, 0), aopLiteral (val, 1),
635                aopLiteral (val, 2), aopLiteral (val, 3));
636     }
637     else {
638       dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
639                aopLiteral (val, 3), aopLiteral (val, 2),
640                aopLiteral (val, 1), aopLiteral (val, 0));
641     }
642     break;
643   }
644 }
645
646 /*-----------------------------------------------------------------*/
647 /* printIvalBitFields - generate initializer for bitfields         */
648 /*-----------------------------------------------------------------*/
649 static void
650 printIvalBitFields (symbol **sym, initList **ilist, struct dbuf_s * oBuf)
651 {
652   symbol *lsym = *sym;
653   initList *lilist = *ilist;
654   unsigned long ival = 0;
655   int size = 0;
656
657   while (lsym)
658     {
659
660       if (0 == SPEC_BLEN (lsym->etype))
661         {
662           /* bit-field structure member with a width of 0 */
663           lsym = lsym->next;
664           break;
665         }
666       else if (!SPEC_BUNNAMED (lsym->etype))
667         {
668           /* not an unnamed bit-field structure member */
669           value *val = list2val (lilist);
670           int bit_length = SPEC_BLEN (lsym->etype);
671
672           if (size)
673             {
674               if (bit_length > 8)
675                 size += (bit_length + 7) / 8;
676             }
677           else
678             size = (bit_length + 7) / 8;
679
680           /* check if the literal value is within bounds */
681           if (val &&
682             checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
683             !options.lessPedantic)
684             {
685               werror (W_LIT_OVERFLOW);
686             }
687
688           ival |= (ulFromVal (val) & ((1ul << bit_length) - 1ul)) << SPEC_BSTR (lsym->etype);
689           lilist = lilist ? lilist->next : NULL;
690         }
691       lsym = lsym->next;
692     }
693
694   switch (size)
695     {
696     case 1:
697       dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
698       break;
699
700     case 2:
701       dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
702       break;
703
704     case 4:
705       dbuf_tprintf (oBuf, "\t!dw  !constword,!constword\n",
706         (ival >> 16) & 0xffff, (ival & 0xffff));
707       break;
708     }
709   *sym = lsym;
710   *ilist = lilist;
711 }
712
713 /*-----------------------------------------------------------------*/
714 /* printIvalStruct - generates initial value for structures        */
715 /*-----------------------------------------------------------------*/
716 static void
717 printIvalStruct (symbol * sym, sym_link * type,
718                  initList * ilist, struct dbuf_s * oBuf)
719 {
720   symbol *sflds;
721   initList *iloop = NULL;
722
723   sflds = SPEC_STRUCT (type)->fields;
724
725   if (ilist)
726     {
727       if (ilist->type != INIT_DEEP)
728         {
729           werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
730           return;
731         }
732
733       iloop = ilist->init.deep;
734     }
735
736   if (SPEC_STRUCT (type)->type == UNION)
737     {
738       printIval (sym, sflds->type, iloop, oBuf, 1);
739       iloop = iloop ? iloop->next : NULL;
740     }
741   else
742     {
743       while (sflds)
744         {
745           if (IS_BITFIELD (sflds->type))
746             printIvalBitFields(&sflds, &iloop, oBuf);
747           else
748             {
749               printIval (sym, sflds->type, iloop, oBuf, 1);
750               sflds = sflds->next;
751               iloop = iloop ? iloop->next : NULL;
752             }
753         }
754     }
755
756   if (iloop)
757     werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
758 }
759
760 /*-----------------------------------------------------------------*/
761 /* printIvalChar - generates initital value for character array    */
762 /*-----------------------------------------------------------------*/
763 int
764 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
765 {
766   value *val;
767   unsigned int size = DCL_ELEM (type);
768
769   if (!s)
770     {
771       val = list2val (ilist);
772       /* if the value is a character string  */
773       if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
774         {
775           if (!size)
776             {
777               werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
778                 "size should never be 0");
779
780               /* we have not been given a size, but now we know it */
781               size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
782               /* but first check, if it's a flexible array */
783               if (sym && IS_STRUCT (sym->type))
784                 sym->flexArrayLength = size;
785               else
786                 DCL_ELEM (type) = size;
787             }
788
789           if (check && DCL_ELEM (val->type) > size)
790             werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
791
792           printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
793
794           return 1;
795         }
796       else
797         return 0;
798     }
799   else
800     printChar (oBuf, s, strlen (s) + 1);
801   return 1;
802 }
803
804 /*-----------------------------------------------------------------*/
805 /* printIvalArray - generates code for array initialization        */
806 /*-----------------------------------------------------------------*/
807 void
808 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
809                 struct dbuf_s * oBuf, bool check)
810 {
811   value *val;
812   initList *iloop;
813   unsigned int size = 0;
814
815   if (ilist) {
816     /* take care of the special   case  */
817     /* array of characters can be init  */
818     /* by a string                      */
819     if (IS_CHAR (type->next)) {
820       val = list2val(ilist);
821       if (!val) {
822         werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
823         return;
824       }
825       if (!IS_LITERAL(val->etype)) {
826         werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
827         return;
828       }
829       if (printIvalChar (sym, type,
830                          (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
831                          oBuf, SPEC_CVAL (sym->etype).v_char, check))
832         return;
833     }
834     /* not the special case             */
835     if (ilist->type != INIT_DEEP) {
836       werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
837       return;
838     }
839
840     for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
841       if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
842         werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
843         break;
844       }
845       printIval (sym, type->next, iloop, oBuf, TRUE);
846     }
847   }
848
849   if (DCL_ELEM(type)) {
850     // pad with zeros if needed
851     if (size<DCL_ELEM(type)) {
852       size = (DCL_ELEM(type) - size) * getSize(type->next);
853       while (size--) {
854         dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
855       }
856     }
857   } else {
858     /* we have not been given a size, but now we know it */
859     /* but first check, if it's a flexible array */
860     if (IS_STRUCT (sym->type))
861       sym->flexArrayLength = size * getSize (type->next);
862     else
863       DCL_ELEM (type) = size;
864   }
865
866   return;
867 }
868
869 /*-----------------------------------------------------------------*/
870 /* printIvalFuncPtr - generate initial value for function pointers */
871 /*-----------------------------------------------------------------*/
872 void
873 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
874 {
875   value *val;
876   int dLvl = 0;
877
878   if (ilist)
879     val = list2val (ilist);
880   else
881     val = valCastLiteral(type, 0.0);
882
883   if (!val) {
884     // an error has been thrown already
885     val = constCharVal (0);
886   }
887
888   if (IS_LITERAL(val->etype)) {
889     if (compareType(type, val->etype) == 0) {
890       werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
891       printFromToType (val->type, type);
892     }
893     printIvalCharPtr (NULL, type, val, oBuf);
894     return;
895   }
896
897   /* check the types   */
898   if ((dLvl = compareType (val->type, type->next)) <= 0)
899     {
900       dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
901       return;
902     }
903
904   /* now generate the name */
905   if (!val->sym)
906     {
907       if (port->use_dw_for_init)
908         {
909           dbuf_tprintf (oBuf, "\t!dws\n", val->name);
910         }
911       else
912         {
913           printPointerType (oBuf, val->name);
914         }
915     }
916   else if (port->use_dw_for_init)
917     {
918       dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
919     }
920   else
921     {
922       printPointerType (oBuf, val->sym->rname);
923     }
924
925   return;
926 }
927
928 /*-----------------------------------------------------------------*/
929 /* printIvalCharPtr - generates initial values for character pointers */
930 /*-----------------------------------------------------------------*/
931 int
932 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
933 {
934   int size = 0;
935
936   /* PENDING: this is _very_ mcs51 specific, including a magic
937      number...
938      It's also endian specific.
939    */
940   size = getSize (type);
941
942   if (val->name && strlen (val->name))
943     {
944       if (size == 1)            /* This appears to be Z80 specific?? */
945         {
946           dbuf_tprintf (oBuf,
947                     "\t!dbs\n", val->name);
948         }
949       else if (size == FPTRSIZE)
950         {
951           if (port->use_dw_for_init)
952             {
953               dbuf_tprintf (oBuf, "\t!dws\n", val->name);
954             }
955           else
956             {
957               printPointerType (oBuf, val->name);
958             }
959         }
960       else if (size == GPTRSIZE)
961         {
962           int type;
963           if (IS_PTR (val->type)) {
964             type = DCL_TYPE (val->type);
965           } else {
966             type = PTR_TYPE (SPEC_OCLS (val->etype));
967           }
968           if (val->sym && val->sym->isstrlit) {
969             // this is a literal string
970             type=CPOINTER;
971           }
972           printGPointerType (oBuf, val->name, sym->name, type);
973         }
974       else
975         {
976           fprintf (stderr, "*** internal error: unknown size in "
977                    "printIvalCharPtr.\n");
978         }
979     }
980   else
981     {
982       // these are literals assigned to pointers
983       switch (size)
984         {
985         case 1:
986           dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
987           break;
988         case 2:
989           if (port->use_dw_for_init)
990             dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
991           else if (port->little_endian)
992             dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
993                       aopLiteral (val, 0), aopLiteral (val, 1));
994           else
995             dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
996                       aopLiteral (val, 1), aopLiteral (val, 0));
997           break;
998         case 3:
999           if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1000             // non-zero mcs51 generic pointer
1001             werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1002           }
1003           if (port->little_endian) {
1004             dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1005                      aopLiteral (val, 0),
1006                      aopLiteral (val, 1),
1007                      aopLiteral (val, 2));
1008           } else {
1009             dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1010                      aopLiteral (val, 2),
1011                      aopLiteral (val, 1),
1012                      aopLiteral (val, 0));
1013           }
1014           break;
1015         case 4:
1016           if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1017             // non-zero ds390 generic pointer
1018             werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1019           }
1020           if (port->little_endian) {
1021             dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1022                      aopLiteral (val, 0),
1023                      aopLiteral (val, 1),
1024                      aopLiteral (val, 2),
1025                      aopLiteral (val, 3));
1026           } else {
1027             dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1028                      aopLiteral (val, 3),
1029                      aopLiteral (val, 2),
1030                      aopLiteral (val, 1),
1031                      aopLiteral (val, 0));
1032           }
1033           break;
1034         default:
1035           assert (0);
1036         }
1037     }
1038
1039   if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1040     addSet (&statsg->syms, val->sym);
1041   }
1042
1043   return 1;
1044 }
1045
1046 /*-----------------------------------------------------------------*/
1047 /* printIvalPtr - generates initial value for pointers             */
1048 /*-----------------------------------------------------------------*/
1049 void
1050 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1051 {
1052   value *val;
1053   int size;
1054
1055   /* if deep then   */
1056   if (ilist && (ilist->type == INIT_DEEP))
1057     ilist = ilist->init.deep;
1058
1059   /* function pointer     */
1060   if (IS_FUNC (type->next))
1061     {
1062       printIvalFuncPtr (type, ilist, oBuf);
1063       return;
1064     }
1065
1066   if (!(val = initPointer (ilist, type)))
1067     return;
1068
1069   /* if character pointer */
1070   if (IS_CHAR (type->next))
1071     if (printIvalCharPtr (sym, type, val, oBuf))
1072       return;
1073
1074   /* check the type      */
1075   if (compareType (type, val->type) == 0) {
1076     werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1077     printFromToType (val->type, type);
1078   }
1079
1080   /* if val is literal */
1081   if (IS_LITERAL (val->etype))
1082     {
1083       switch (getSize (type))
1084         {
1085         case 1:
1086           dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1087           break;
1088         case 2:
1089           if (port->use_dw_for_init)
1090             dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1091           else if (port->little_endian)
1092             dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1093           else
1094             dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1095           break;
1096         case 3: // how about '390??
1097           dbuf_printf (oBuf, "; generic printIvalPtr\n");
1098           if (port->little_endian)
1099             {
1100               dbuf_printf (oBuf, "\t.byte %s,%s",
1101                        aopLiteral (val, 0), aopLiteral (val, 1));
1102             }
1103           else
1104             {
1105               dbuf_printf (oBuf, "\t.byte %s,%s",
1106                        aopLiteral (val, 1), aopLiteral (val, 0));
1107             }
1108           if (IS_GENPTR (val->type))
1109             dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1110           else if (IS_PTR (val->type))
1111             dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1112           else
1113             dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1114         }
1115       return;
1116     }
1117
1118
1119   size = getSize (type);
1120
1121   if (size == 1)                /* Z80 specific?? */
1122     {
1123       dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1124     }
1125   else if (size == FPTRSIZE)
1126     {
1127       if (port->use_dw_for_init) {
1128         dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1129       } else {
1130         printPointerType (oBuf, val->name);
1131       }
1132     }
1133   else if (size == GPTRSIZE)
1134     {
1135       printGPointerType (oBuf, val->name, sym->name,
1136                          (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1137                           PTR_TYPE (SPEC_OCLS (val->etype))));
1138     }
1139   return;
1140 }
1141
1142 /*-----------------------------------------------------------------*/
1143 /* printIval - generates code for initial value                    */
1144 /*-----------------------------------------------------------------*/
1145 void
1146 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1147 {
1148   sym_link *itype;
1149
1150   /* if structure then    */
1151   if (IS_STRUCT (type))
1152     {
1153       printIvalStruct (sym, type, ilist, oBuf);
1154       return;
1155     }
1156
1157   /* if this is an array   */
1158   if (IS_ARRAY (type))
1159     {
1160       printIvalArray (sym, type, ilist, oBuf, check);
1161       return;
1162     }
1163
1164   if (ilist)
1165     {
1166       // not an aggregate, ilist must be a node
1167       if (ilist->type!=INIT_NODE) {
1168           // or a 1-element list
1169         if (ilist->init.deep->next) {
1170           werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1171                   sym->name);
1172         } else {
1173           ilist=ilist->init.deep;
1174         }
1175       }
1176
1177       // and the type must match
1178       itype=ilist->init.node->ftype;
1179
1180       if (compareType(type, itype)==0) {
1181         // special case for literal strings
1182         if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1183             // which are really code pointers
1184             IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1185           // no sweat
1186         } else {
1187           werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1188           printFromToType(itype, type);
1189         }
1190       }
1191     }
1192
1193   /* if this is a pointer */
1194   if (IS_PTR (type))
1195     {
1196       printIvalPtr (sym, type, ilist, oBuf);
1197       return;
1198     }
1199
1200   /* if type is SPECIFIER */
1201   if (IS_SPEC (type))
1202     {
1203       printIvalType (sym, type, ilist, oBuf);
1204       return;
1205     }
1206 }
1207
1208 /*-----------------------------------------------------------------*/
1209 /* emitStaticSeg - emitcode for the static segment                 */
1210 /*-----------------------------------------------------------------*/
1211 void
1212 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1213 {
1214   symbol *sym;
1215
1216   /* fprintf(out, "\t.area\t%s\n", map->sname); */
1217
1218   /* for all variables in this segment do */
1219   for (sym = setFirstItem (map->syms); sym;
1220        sym = setNextItem (map->syms))
1221     {
1222
1223       /* if it is "extern" then do nothing */
1224       if (IS_EXTERN (sym->etype))
1225         continue;
1226
1227       /* if it is not static add it to the public table */
1228       if (!IS_STATIC (sym->etype))
1229         {
1230           addSetHead (&publics, sym);
1231         }
1232
1233       /* print extra debug info if required */
1234       if (options.debug)
1235         {
1236           if (!sym->level)
1237             {                     /* global */
1238               if (IS_STATIC (sym->etype))
1239                 dbuf_printf (oBuf, "F%s$", moduleName);        /* scope is file */
1240               else
1241                 dbuf_printf (oBuf, "G$");      /* scope is global */
1242             }
1243           else
1244             {
1245               /* symbol is local */
1246               dbuf_printf (oBuf, "L%s$",
1247                            (sym->localof ? sym->localof->name : "-null-"));
1248             }
1249           dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1250         }
1251
1252       /* if it has an absolute address and no initializer */
1253       if (SPEC_ABSA (sym->etype) && !sym->ival)
1254         {
1255           if (options.debug)
1256             dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1257
1258           dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1259                    sym->rname,
1260                    SPEC_ADDR (sym->etype));
1261         }
1262       else
1263         {
1264           if (options.debug)
1265             dbuf_printf (oBuf, " == .\n");
1266
1267           /* if it has an initial value */
1268           if (sym->ival)
1269             {
1270               if (SPEC_ABSA (sym->etype))
1271                 {
1272                   dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1273                 }
1274               dbuf_printf (oBuf, "%s:\n", sym->rname);
1275               ++noAlloc;
1276               resolveIvalSym (sym->ival, sym->type);
1277               printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1278               --noAlloc;
1279               /* if sym is a simple string and sym->ival is a string,
1280                  WE don't need it anymore */
1281               if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1282                   IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1283                   list2val(sym->ival)->sym->isstrlit) {
1284                 freeStringSymbol(list2val(sym->ival)->sym);
1285               }
1286             }
1287           else {
1288               /* allocate space */
1289               int size = getSize (sym->type);
1290
1291               if (size==0) {
1292                   werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1293               }
1294               dbuf_printf (oBuf, "%s:\n", sym->rname);
1295               /* special case for character strings */
1296               if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1297                   SPEC_CVAL (sym->etype).v_char)
1298                   printChar (oBuf,
1299                              SPEC_CVAL (sym->etype).v_char,
1300                              size);
1301               else
1302                   dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1303             }
1304         }
1305     }
1306 }
1307
1308 /*-----------------------------------------------------------------*/
1309 /* emitMaps - emits the code for the data portion the code         */
1310 /*-----------------------------------------------------------------*/
1311 void
1312 emitMaps (void)
1313 {
1314   int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all  */
1315                                    /* ports but let's be conservative - EEP */
1316
1317   inInitMode++;
1318   /* no special considerations for the following
1319      data, idata & bit & xdata */
1320   emitRegularMap (data, TRUE, TRUE);
1321   emitRegularMap (idata, TRUE, TRUE);
1322   emitRegularMap (d_abs, TRUE, TRUE);
1323   emitRegularMap (i_abs, TRUE, TRUE);
1324   emitRegularMap (bit, TRUE, TRUE);
1325   emitRegularMap (pdata, TRUE, TRUE);
1326   emitRegularMap (xdata, TRUE, TRUE);
1327   emitRegularMap (x_abs, TRUE, TRUE);
1328   if (port->genXINIT) {
1329     emitRegularMap (xidata, TRUE, TRUE);
1330   }
1331   emitRegularMap (sfr, publicsfr, FALSE);
1332   emitRegularMap (sfrbit, publicsfr, FALSE);
1333   emitRegularMap (home, TRUE, FALSE);
1334   emitRegularMap (code, TRUE, FALSE);
1335
1336   if (options.const_seg) {
1337     dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1338   }
1339   emitStaticSeg (statsg, &code->oBuf);
1340   if (port->genXINIT) {
1341     dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1342     emitStaticSeg (xinit, &code->oBuf);
1343   }
1344   dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1345   emitStaticSeg (c_abs, &code->oBuf);
1346   inInitMode--;
1347 }
1348
1349 /*-----------------------------------------------------------------*/
1350 /* flushStatics - flush all currently defined statics out to file  */
1351 /*  and delete.  Temporary function                                */
1352 /*-----------------------------------------------------------------*/
1353 void
1354 flushStatics (void)
1355 {
1356   emitStaticSeg (statsg, codeOutBuf);
1357   statsg->syms = NULL;
1358 }
1359
1360 /*-----------------------------------------------------------------*/
1361 /* createInterruptVect - creates the interrupt vector              */
1362 /*-----------------------------------------------------------------*/
1363 void
1364 createInterruptVect (struct dbuf_s *vBuf)
1365 {
1366   mainf = newSymbol ("main", 0);
1367   mainf->block = 0;
1368
1369   /* only if the main function exists */
1370   if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1371     {
1372       if (!options.cc_only && !noAssemble && !options.c1mode)
1373         werror (E_NO_MAIN);
1374       return;
1375     }
1376
1377   /* if the main is only a prototype ie. no body then do nothing */
1378   if (!IFFUNC_HASBODY(mainf->type))
1379     {
1380       /* if ! compile only then main function should be present */
1381       if (!options.cc_only && !noAssemble)
1382         werror (E_NO_MAIN);
1383       return;
1384     }
1385
1386   dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1387   dbuf_printf (vBuf, "__interrupt_vect:\n");
1388
1389
1390   if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1391     {
1392       /* There's no such thing as a "generic" interrupt table header. */
1393       wassert(0);
1394     }
1395 }
1396
1397 char *iComments1 =
1398 {
1399   ";--------------------------------------------------------\n"
1400   "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1401
1402 char *iComments2 =
1403 {
1404   ";--------------------------------------------------------\n"};
1405
1406
1407 /*-----------------------------------------------------------------*/
1408 /* initialComments - puts in some initial comments                 */
1409 /*-----------------------------------------------------------------*/
1410 void
1411 initialComments (FILE * afile)
1412 {
1413   time_t t;
1414   time (&t);
1415   fprintf (afile, "%s", iComments1);
1416   fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1417            getBuildNumber(), getBuildDate(), getBuildEnvironment());
1418   fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1419   fprintf (afile, "%s", iComments2);
1420 }
1421
1422 /*-----------------------------------------------------------------*/
1423 /* printPublics - generates .global for publics                    */
1424 /*-----------------------------------------------------------------*/
1425 void
1426 printPublics (FILE * afile)
1427 {
1428   symbol *sym;
1429
1430   fprintf (afile, "%s", iComments2);
1431   fprintf (afile, "; Public variables in this module\n");
1432   fprintf (afile, "%s", iComments2);
1433
1434   for (sym = setFirstItem (publics); sym;
1435        sym = setNextItem (publics))
1436     tfprintf (afile, "\t!global\n", sym->rname);
1437 }
1438
1439 /*-----------------------------------------------------------------*/
1440 /* printExterns - generates .global for externs                    */
1441 /*-----------------------------------------------------------------*/
1442 void
1443 printExterns (FILE * afile)
1444 {
1445   symbol *sym;
1446
1447   fprintf (afile, "%s", iComments2);
1448   fprintf (afile, "; Externals used\n");
1449   fprintf (afile, "%s", iComments2);
1450
1451   for (sym = setFirstItem (externs); sym;
1452        sym = setNextItem (externs))
1453     tfprintf (afile, "\t!extern\n", sym->rname);
1454 }
1455
1456 /*-----------------------------------------------------------------*/
1457 /* emitOverlay - will emit code for the overlay stuff              */
1458 /*-----------------------------------------------------------------*/
1459 static void
1460 emitOverlay (struct dbuf_s * aBuf)
1461 {
1462   set *ovrset;
1463
1464   if (!elementsInSet (ovrSetSets))
1465     dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1466
1467   /* for each of the sets in the overlay segment do */
1468   for (ovrset = setFirstItem (ovrSetSets); ovrset;
1469        ovrset = setNextItem (ovrSetSets))
1470     {
1471
1472       symbol *sym;
1473
1474       if (elementsInSet (ovrset))
1475         {
1476           /* output the area informtion */
1477           dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name);     /* MOF */
1478         }
1479
1480       for (sym = setFirstItem (ovrset); sym;
1481            sym = setNextItem (ovrset))
1482         {
1483           /* if extern then it is in the publics table: do nothing */
1484           if (IS_EXTERN (sym->etype))
1485             continue;
1486
1487           /* if allocation required check is needed
1488              then check if the symbol really requires
1489              allocation only for local variables */
1490           if (!IS_AGGREGATE (sym->type) &&
1491               !(sym->_isparm && !IS_REGPARM (sym->etype))
1492               && !sym->allocreq && sym->level)
1493             continue;
1494
1495           /* if global variable & not static or extern
1496              and addPublics allowed then add it to the public set */
1497           if ((sym->_isparm && !IS_REGPARM (sym->etype))
1498               && !IS_STATIC (sym->etype))
1499             {
1500               addSetHead (&publics, sym);
1501             }
1502
1503           /* if extern then do nothing or is a function
1504              then do nothing */
1505           if (IS_FUNC (sym->type))
1506             continue;
1507
1508           /* print extra debug info if required */
1509           if (options.debug)
1510             {
1511               if (!sym->level)
1512                 {               /* global */
1513                   if (IS_STATIC (sym->etype))
1514                     dbuf_printf (aBuf, "F%s$", moduleName);        /* scope is file */
1515                   else
1516                     dbuf_printf (aBuf, "G$");      /* scope is global */
1517                 }
1518               else
1519                 /* symbol is local */
1520                 dbuf_printf (aBuf, "L%s$",
1521                          (sym->localof ? sym->localof->name : "-null-"));
1522               dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1523             }
1524
1525           /* if is has an absolute address then generate
1526              an equate for this no need to allocate space */
1527           if (SPEC_ABSA (sym->etype))
1528             {
1529
1530               if (options.debug)
1531                 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1532
1533               dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1534                        sym->rname,
1535                        SPEC_ADDR (sym->etype));
1536             }
1537           else
1538             {
1539               int size = getSize(sym->type);
1540
1541               if (size==0) {
1542                   werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1543               }
1544               if (options.debug)
1545                   dbuf_printf (aBuf, "==.\n");
1546
1547               /* allocate space */
1548               dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1549               dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1550           }
1551
1552         }
1553     }
1554 }
1555
1556 /*-----------------------------------------------------------------*/
1557 /* glue - the final glue that hold the whole thing together        */
1558 /*-----------------------------------------------------------------*/
1559 void
1560 glue (void)
1561 {
1562   struct dbuf_s vBuf;
1563   struct dbuf_s ovrBuf;
1564   FILE *asmFile;
1565   int mcs51_like;
1566
1567   dbuf_init (&vBuf, 4096);
1568   dbuf_init (&ovrBuf, 4096);
1569
1570   mcs51_like = (port->general.glue_up_main &&
1571     (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1572
1573   /* print the global struct definitions */
1574   if (options.debug)
1575     cdbStructBlock (0);
1576
1577   /* PENDING: this isn't the best place but it will do */
1578   if (port->general.glue_up_main)
1579     {
1580       /* create the interrupt vector table */
1581       createInterruptVect (&vBuf);
1582     }
1583
1584   /* emit code for the all the variables declared */
1585   emitMaps ();
1586   /* do the overlay segments */
1587   emitOverlay (&ovrBuf);
1588
1589   outputDebugSymbols ();
1590
1591   /* now put it all together into the assembler file */
1592   /* create the assembler file name */
1593
1594   /* -o option overrides default name? */
1595   if ((noAssemble || options.c1mode) && fullDstFileName)
1596     {
1597       strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1598     }
1599   else
1600     {
1601       strncpyz (scratchFileName, dstFileName, PATH_MAX);
1602       strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1603     }
1604
1605   if (!(asmFile = fopen (scratchFileName, "w")))
1606     {
1607       werror (E_FILE_OPEN_ERR, scratchFileName);
1608       exit (EXIT_FAILURE);
1609     }
1610
1611   /* initial comments */
1612   initialComments (asmFile);
1613
1614   /* print module name */
1615   tfprintf (asmFile, "\t!module\n", moduleName);
1616   if (mcs51_like)
1617     {
1618       fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1619
1620       switch(options.model)
1621         {
1622         case MODEL_SMALL:   fprintf (asmFile, " --model-small");   break;
1623         case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1624         case MODEL_MEDIUM:  fprintf (asmFile, " --model-medium");  break;
1625         case MODEL_LARGE:   fprintf (asmFile, " --model-large");   break;
1626         case MODEL_FLAT24:  fprintf (asmFile, " --model-flat24");  break;
1627         case MODEL_PAGE0:   fprintf (asmFile, " --model-page0");   break;
1628         default: break;
1629         }
1630       /*if(options.stackAuto)      fprintf (asmFile, " --stack-auto");*/
1631       if(options.useXstack)      fprintf (asmFile, " --xstack");
1632       /*if(options.intlong_rent)   fprintf (asmFile, " --int-long-rent");*/
1633       /*if(options.float_rent)     fprintf (asmFile, " --float-rent");*/
1634       if(options.noRegParams)    fprintf (asmFile, " --no-reg-params");
1635       if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1636       fprintf (asmFile, "\n");
1637     }
1638   else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1639     {
1640       fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1641     }
1642
1643   tfprintf (asmFile, "\t!fileprelude\n");
1644
1645   /* Let the port generate any global directives, etc. */
1646   if (port->genAssemblerPreamble)
1647     {
1648       port->genAssemblerPreamble (asmFile);
1649     }
1650
1651   /* print the global variables in this module */
1652   printPublics (asmFile);
1653   if (port->assembler.externGlobal)
1654     printExterns (asmFile);
1655
1656   if (( mcs51_like )
1657      ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1658     {
1659       /* copy the sfr segment */
1660       fprintf (asmFile, "%s", iComments2);
1661       fprintf (asmFile, "; special function registers\n");
1662       fprintf (asmFile, "%s", iComments2);
1663       dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1664     }
1665
1666   if (mcs51_like)
1667     {
1668       /* copy the sbit segment */
1669       fprintf (asmFile, "%s", iComments2);
1670       fprintf (asmFile, "; special function bits\n");
1671       fprintf (asmFile, "%s", iComments2);
1672       dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1673
1674       /*JCF: Create the areas for the register banks*/
1675       if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1676         {
1677           fprintf (asmFile, "%s", iComments2);
1678           fprintf (asmFile, "; overlayable register banks\n");
1679           fprintf (asmFile, "%s", iComments2);
1680           if (RegBankUsed[0])
1681             fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1682           if (RegBankUsed[1] || options.parms_in_bank1)
1683             fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1684           if (RegBankUsed[2])
1685             fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1686           if (RegBankUsed[3])
1687             fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1688         }
1689       if (BitBankUsed)
1690         {
1691           fprintf (asmFile, "%s", iComments2);
1692           fprintf (asmFile, "; overlayable bit register bank\n");
1693           fprintf (asmFile, "%s", iComments2);
1694           fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1695           fprintf (asmFile, "bits:\n\t.ds 1\n");
1696           fprintf (asmFile, "\tb0 = bits[0]\n");
1697           fprintf (asmFile, "\tb1 = bits[1]\n");
1698           fprintf (asmFile, "\tb2 = bits[2]\n");
1699           fprintf (asmFile, "\tb3 = bits[3]\n");
1700           fprintf (asmFile, "\tb4 = bits[4]\n");
1701           fprintf (asmFile, "\tb5 = bits[5]\n");
1702           fprintf (asmFile, "\tb6 = bits[6]\n");
1703           fprintf (asmFile, "\tb7 = bits[7]\n");
1704         }
1705     }
1706
1707   /* copy the data segment */
1708   fprintf (asmFile, "%s", iComments2);
1709   fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1710   fprintf (asmFile, "%s", iComments2);
1711   dbuf_write_and_destroy (&data->oBuf, asmFile);
1712
1713
1714   /* create the overlay segments */
1715   if (overlay)
1716     {
1717       fprintf (asmFile, "%s", iComments2);
1718       fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1719       fprintf (asmFile, "%s", iComments2);
1720       dbuf_write_and_destroy (&ovrBuf, asmFile);
1721     }
1722
1723   /* create the stack segment MOF */
1724   if (mainf && IFFUNC_HASBODY (mainf->type))
1725     {
1726       fprintf (asmFile, "%s", iComments2);
1727       fprintf (asmFile, "; Stack segment in internal ram \n");
1728       fprintf (asmFile, "%s", iComments2);
1729       fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1730                "__start__stack:\n\t.ds\t1\n\n");
1731     }
1732
1733   /* create the idata segment */
1734   if ((idata) && (mcs51_like))
1735     {
1736       fprintf (asmFile, "%s", iComments2);
1737       fprintf (asmFile, "; indirectly addressable internal ram data\n");
1738       fprintf (asmFile, "%s", iComments2);
1739       dbuf_write_and_destroy (&idata->oBuf, asmFile);
1740     }
1741
1742   /* create the absolute idata/data segment */
1743   if ((i_abs) && (mcs51_like))
1744     {
1745       fprintf (asmFile, "%s", iComments2);
1746       fprintf (asmFile, "; absolute internal ram data\n");
1747       fprintf (asmFile, "%s", iComments2);
1748       dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1749       dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1750     }
1751
1752   /* copy the bit segment */
1753   if (mcs51_like)
1754     {
1755       fprintf (asmFile, "%s", iComments2);
1756       fprintf (asmFile, "; bit data\n");
1757       fprintf (asmFile, "%s", iComments2);
1758       dbuf_write_and_destroy (&bit->oBuf, asmFile);
1759     }
1760
1761   /* copy paged external ram data */
1762   if (mcs51_like)
1763     {
1764       fprintf (asmFile, "%s", iComments2);
1765       fprintf (asmFile, "; paged external ram data\n");
1766       fprintf (asmFile, "%s", iComments2);
1767       dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1768     }
1769
1770   /* if external stack then reserve space for it */
1771   if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1772     {
1773       fprintf (asmFile, "%s", iComments2);
1774       fprintf (asmFile, "; external stack \n");
1775       fprintf (asmFile, "%s", iComments2);
1776       fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1777                "__start__xstack:\n\t.ds\t1\n\n");
1778     }
1779
1780   /* copy external ram data */
1781   if (mcs51_like)
1782     {
1783       fprintf (asmFile, "%s", iComments2);
1784       fprintf (asmFile, "; external ram data\n");
1785       fprintf (asmFile, "%s", iComments2);
1786       dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1787     }
1788
1789   /* create the absolute xdata segment */
1790   if (mcs51_like || TARGET_IS_HC08)
1791     {
1792       fprintf (asmFile, "%s", iComments2);
1793       fprintf (asmFile, "; absolute external ram data\n");
1794       fprintf (asmFile, "%s", iComments2);
1795       dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1796     }
1797
1798   /* copy external initialized ram data */
1799   fprintf (asmFile, "%s", iComments2);
1800   fprintf (asmFile, "; external initialized ram data\n");
1801   fprintf (asmFile, "%s", iComments2);
1802   dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1803
1804   /* If the port wants to generate any extra areas, let it do so. */
1805   if (port->extraAreas.genExtraAreaDeclaration)
1806     {
1807       port->extraAreas.genExtraAreaDeclaration(asmFile,
1808                                                mainf && IFFUNC_HASBODY(mainf->type));
1809     }
1810
1811   /* copy the interrupt vector table */
1812   if (mainf && IFFUNC_HASBODY (mainf->type))
1813     {
1814       fprintf (asmFile, "%s", iComments2);
1815       fprintf (asmFile, "; interrupt vector \n");
1816       fprintf (asmFile, "%s", iComments2);
1817       dbuf_write_and_destroy (&vBuf, asmFile);
1818     }
1819
1820   /* copy global & static initialisations */
1821   fprintf (asmFile, "%s", iComments2);
1822   fprintf (asmFile, "; global & static initialisations\n");
1823   fprintf (asmFile, "%s", iComments2);
1824
1825   /* Everywhere we generate a reference to the static_name area,
1826    * (which is currently only here), we immediately follow it with a
1827    * definition of the post_static_name area. This guarantees that
1828    * the post_static_name area will immediately follow the static_name
1829    * area.
1830    */
1831   tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1832   tfprintf (asmFile, "\t!area\n", port->mem.static_name);       /* MOF */
1833   tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1834   tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1835
1836   if (mainf && IFFUNC_HASBODY (mainf->type))
1837     {
1838       if (port->genInitStartup)
1839         {
1840            port->genInitStartup (asmFile);
1841         }
1842       else
1843         {
1844           assert (mcs51_like);
1845           fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1846           /* if external stack is specified then the
1847              higher order byte of the xdatalocation is
1848              going into P2 and the lower order going into
1849              spx */
1850           if (options.useXstack)
1851             {
1852               fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1853                        (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1854               fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1855                        (unsigned int) options.xdata_loc & 0xff);
1856             }
1857
1858           // This should probably be a port option, but I'm being lazy.
1859           // on the 400, the firmware boot loader gives us a valid stack
1860           // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1861           if (!TARGET_IS_DS400)
1862             {
1863               /* initialise the stack pointer.  JCF: aslink takes care of the location */
1864               fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n");     /* MOF */
1865             }
1866
1867           fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1868           fprintf (asmFile, "\tmov\ta,dpl\n");
1869           fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1870           fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1871           fprintf (asmFile, "__sdcc_init_data:\n");
1872
1873           // if the port can copy the XINIT segment to XISEG
1874           if (port->genXINIT)
1875             {
1876               port->genXINIT (asmFile);
1877             }
1878         }
1879     }
1880   dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1881
1882   if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1883     {
1884       /* This code is generated in the post-static area.
1885        * This area is guaranteed to follow the static area
1886        * by the ugly shucking and jiving about 20 lines ago.
1887        */
1888       tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1889       fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1890     }
1891
1892   fprintf (asmFile,
1893            "%s"
1894            "; Home\n"
1895            "%s", iComments2, iComments2);
1896   tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1897   dbuf_write_and_destroy (&home->oBuf, asmFile);
1898
1899   if (mainf && IFFUNC_HASBODY (mainf->type))
1900     {
1901       /* entry point @ start of HOME */
1902       fprintf (asmFile, "__sdcc_program_startup:\n");
1903
1904       /* put in jump or call to main */
1905       if (options.mainreturn)
1906         {
1907           fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l');   /* needed? */
1908           fprintf (asmFile, ";\treturn from main will return to caller\n");
1909         }
1910       else
1911         {
1912           fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1913           fprintf (asmFile, ";\treturn from main will lock up\n");
1914           fprintf (asmFile, "\tsjmp .\n");
1915         }
1916     }
1917   /* copy over code */
1918   fprintf (asmFile, "%s", iComments2);
1919   fprintf (asmFile, "; code\n");
1920   fprintf (asmFile, "%s", iComments2);
1921   tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1922   dbuf_write_and_destroy (&code->oBuf, asmFile);
1923
1924   if (port->genAssemblerEnd)
1925     {
1926       port->genAssemblerEnd (asmFile);
1927     }
1928   fclose (asmFile);
1929 }