* src/SDCCmain.c: #fixed bug 2224960: sdcc -MM no working correctly
[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 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
650 {
651   value *val ;
652   symbol *lsym = *sym;
653   initList *lilist = *ilist ;
654   unsigned long ival = 0;
655   int size = 0;
656
657   do
658     {
659       unsigned long i;
660       val = list2val (lilist);
661       if (size)
662         {
663           if (SPEC_BLEN (lsym->etype) > 8)
664             {
665               size += ((SPEC_BLEN (lsym->etype) / 8) +
666                        (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
667             }
668         }
669       else
670         {
671           size = ((SPEC_BLEN (lsym->etype) / 8) +
672                   (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
673         }
674
675       /* check if the literal value is within bounds */
676       if (val &&
677         checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
678         !options.lessPedantic)
679         {
680           werror (W_LIT_OVERFLOW);
681         }
682
683       i = ulFromVal (val);
684       i &= (1 << SPEC_BLEN (lsym->etype)) - 1;
685       i <<= SPEC_BSTR (lsym->etype);
686       ival |= i;
687       if (!(lsym->next &&
688         (IS_BITFIELD (lsym->next->type)) &&
689         (SPEC_BSTR (lsym->next->etype))))
690         break;
691       lsym = lsym->next;
692       lilist = lilist ? lilist->next : NULL;
693     }
694   while (1);
695
696   switch (size)
697   {
698   case 1:
699     dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
700     break;
701
702   case 2:
703     dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
704     break;
705
706   case 4:
707     dbuf_tprintf (oBuf, "\t!dw  !constword,!constword\n",
708       (ival >> 16) & 0xffff, (ival & 0xffff));
709     break;
710   }
711   *sym = lsym;
712   *ilist = lilist;
713 }
714
715 /*-----------------------------------------------------------------*/
716 /* printIvalStruct - generates initial value for structures        */
717 /*-----------------------------------------------------------------*/
718 void
719 printIvalStruct (symbol * sym, sym_link * type,
720                  initList * ilist, struct dbuf_s * oBuf)
721 {
722   symbol *sflds;
723   initList *iloop = NULL;
724
725   sflds = SPEC_STRUCT (type)->fields;
726
727   if (ilist) {
728     if (ilist->type != INIT_DEEP) {
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     printIval (sym, sflds->type, iloop, oBuf, TRUE);
738     iloop = iloop ? iloop->next : NULL;
739   } else {
740     for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
741       if (IS_BITFIELD(sflds->type)) {
742         printIvalBitFields(&sflds, &iloop, oBuf);
743       } else {
744         printIval (sym, sflds->type, iloop, oBuf, TRUE);
745       }
746     }
747   }
748   if (iloop) {
749     werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
750   }
751   return;
752 }
753
754 /*-----------------------------------------------------------------*/
755 /* printIvalChar - generates initital value for character array    */
756 /*-----------------------------------------------------------------*/
757 int
758 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
759 {
760   value *val;
761   unsigned int size = DCL_ELEM (type);
762
763   if (!s)
764     {
765       val = list2val (ilist);
766       /* if the value is a character string  */
767       if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
768         {
769           if (!size)
770             {
771               /* we have not been given a size, but now we know it */
772               size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
773               /* but first check, if it's a flexible array */
774               if (sym && IS_STRUCT (sym->type))
775                 sym->flexArrayLength = size;
776               else
777                 DCL_ELEM (type) = size;
778             }
779
780           if (check && DCL_ELEM (val->type) > size)
781             werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
782
783           printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
784
785           return 1;
786         }
787       else
788         return 0;
789     }
790   else
791     printChar (oBuf, s, strlen (s) + 1);
792   return 1;
793 }
794
795 /*-----------------------------------------------------------------*/
796 /* printIvalArray - generates code for array initialization        */
797 /*-----------------------------------------------------------------*/
798 void
799 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
800                 struct dbuf_s * oBuf, bool check)
801 {
802   value *val;
803   initList *iloop;
804   unsigned int size = 0;
805
806   if (ilist) {
807     /* take care of the special   case  */
808     /* array of characters can be init  */
809     /* by a string                      */
810     if (IS_CHAR (type->next)) {
811       val = list2val(ilist);
812       if (!val) {
813         werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
814         return;
815       }
816       if (!IS_LITERAL(val->etype)) {
817         werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
818         return;
819       }
820       if (printIvalChar (sym, type,
821                          (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
822                          oBuf, SPEC_CVAL (sym->etype).v_char, check))
823         return;
824     }
825     /* not the special case             */
826     if (ilist->type != INIT_DEEP) {
827       werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
828       return;
829     }
830
831     for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
832       if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
833         werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
834         break;
835       }
836       printIval (sym, type->next, iloop, oBuf, TRUE);
837     }
838   }
839
840   if (DCL_ELEM(type)) {
841     // pad with zeros if needed
842     if (size<DCL_ELEM(type)) {
843       size = (DCL_ELEM(type) - size) * getSize(type->next);
844       while (size--) {
845         dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
846       }
847     }
848   } else {
849     /* we have not been given a size, but now we know it */
850     /* but first check, if it's a flexible array */
851     if (IS_STRUCT (sym->type))
852       sym->flexArrayLength = size * getSize (type->next);
853     else
854       DCL_ELEM (type) = size;
855   }
856
857   return;
858 }
859
860 /*-----------------------------------------------------------------*/
861 /* printIvalFuncPtr - generate initial value for function pointers */
862 /*-----------------------------------------------------------------*/
863 void
864 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
865 {
866   value *val;
867   int dLvl = 0;
868
869   if (ilist)
870     val = list2val (ilist);
871   else
872     val = valCastLiteral(type, 0.0);
873
874   if (!val) {
875     // an error has been thrown already
876     val = constCharVal (0);
877   }
878
879   if (IS_LITERAL(val->etype)) {
880     if (compareType(type, val->etype) == 0) {
881       werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
882       printFromToType (val->type, type);
883     }
884     printIvalCharPtr (NULL, type, val, oBuf);
885     return;
886   }
887
888   /* check the types   */
889   if ((dLvl = compareType (val->type, type->next)) <= 0)
890     {
891       dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
892       return;
893     }
894
895   /* now generate the name */
896   if (!val->sym)
897     {
898       if (port->use_dw_for_init)
899         {
900           dbuf_tprintf (oBuf, "\t!dws\n", val->name);
901         }
902       else
903         {
904           printPointerType (oBuf, val->name);
905         }
906     }
907   else if (port->use_dw_for_init)
908     {
909       dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
910     }
911   else
912     {
913       printPointerType (oBuf, val->sym->rname);
914     }
915
916   return;
917 }
918
919 /*-----------------------------------------------------------------*/
920 /* printIvalCharPtr - generates initial values for character pointers */
921 /*-----------------------------------------------------------------*/
922 int
923 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
924 {
925   int size = 0;
926
927   /* PENDING: this is _very_ mcs51 specific, including a magic
928      number...
929      It's also endian specific.
930    */
931   size = getSize (type);
932
933   if (val->name && strlen (val->name))
934     {
935       if (size == 1)            /* This appears to be Z80 specific?? */
936         {
937           dbuf_tprintf (oBuf,
938                     "\t!dbs\n", val->name);
939         }
940       else if (size == FPTRSIZE)
941         {
942           if (port->use_dw_for_init)
943             {
944               dbuf_tprintf (oBuf, "\t!dws\n", val->name);
945             }
946           else
947             {
948               printPointerType (oBuf, val->name);
949             }
950         }
951       else if (size == GPTRSIZE)
952         {
953           int type;
954           if (IS_PTR (val->type)) {
955             type = DCL_TYPE (val->type);
956           } else {
957             type = PTR_TYPE (SPEC_OCLS (val->etype));
958           }
959           if (val->sym && val->sym->isstrlit) {
960             // this is a literal string
961             type=CPOINTER;
962           }
963           printGPointerType (oBuf, val->name, sym->name, type);
964         }
965       else
966         {
967           fprintf (stderr, "*** internal error: unknown size in "
968                    "printIvalCharPtr.\n");
969         }
970     }
971   else
972     {
973       // these are literals assigned to pointers
974       switch (size)
975         {
976         case 1:
977           dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
978           break;
979         case 2:
980           if (port->use_dw_for_init)
981             dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
982           else if (port->little_endian)
983             dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
984                       aopLiteral (val, 0), aopLiteral (val, 1));
985           else
986             dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
987                       aopLiteral (val, 1), aopLiteral (val, 0));
988           break;
989         case 3:
990           if (IS_GENPTR(type) && floatFromVal(val)!=0) {
991             // non-zero mcs51 generic pointer
992             werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
993           }
994           if (port->little_endian) {
995             dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
996                      aopLiteral (val, 0),
997                      aopLiteral (val, 1),
998                      aopLiteral (val, 2));
999           } else {
1000             dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1001                      aopLiteral (val, 2),
1002                      aopLiteral (val, 1),
1003                      aopLiteral (val, 0));
1004           }
1005           break;
1006         case 4:
1007           if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1008             // non-zero ds390 generic pointer
1009             werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1010           }
1011           if (port->little_endian) {
1012             dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1013                      aopLiteral (val, 0),
1014                      aopLiteral (val, 1),
1015                      aopLiteral (val, 2),
1016                      aopLiteral (val, 3));
1017           } else {
1018             dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1019                      aopLiteral (val, 3),
1020                      aopLiteral (val, 2),
1021                      aopLiteral (val, 1),
1022                      aopLiteral (val, 0));
1023           }
1024           break;
1025         default:
1026           assert (0);
1027         }
1028     }
1029
1030   if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1031     addSet (&statsg->syms, val->sym);
1032   }
1033
1034   return 1;
1035 }
1036
1037 /*-----------------------------------------------------------------*/
1038 /* printIvalPtr - generates initial value for pointers             */
1039 /*-----------------------------------------------------------------*/
1040 void
1041 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1042 {
1043   value *val;
1044   int size;
1045
1046   /* if deep then   */
1047   if (ilist && (ilist->type == INIT_DEEP))
1048     ilist = ilist->init.deep;
1049
1050   /* function pointer     */
1051   if (IS_FUNC (type->next))
1052     {
1053       printIvalFuncPtr (type, ilist, oBuf);
1054       return;
1055     }
1056
1057   if (!(val = initPointer (ilist, type)))
1058     return;
1059
1060   /* if character pointer */
1061   if (IS_CHAR (type->next))
1062     if (printIvalCharPtr (sym, type, val, oBuf))
1063       return;
1064
1065   /* check the type      */
1066   if (compareType (type, val->type) == 0) {
1067     werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1068     printFromToType (val->type, type);
1069   }
1070
1071   /* if val is literal */
1072   if (IS_LITERAL (val->etype))
1073     {
1074       switch (getSize (type))
1075         {
1076         case 1:
1077           dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1078           break;
1079         case 2:
1080           if (port->use_dw_for_init)
1081             dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1082           else if (port->little_endian)
1083             dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1084           else
1085             dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1086           break;
1087         case 3: // how about '390??
1088           dbuf_printf (oBuf, "; generic printIvalPtr\n");
1089           if (port->little_endian)
1090             {
1091               dbuf_printf (oBuf, "\t.byte %s,%s",
1092                        aopLiteral (val, 0), aopLiteral (val, 1));
1093             }
1094           else
1095             {
1096               dbuf_printf (oBuf, "\t.byte %s,%s",
1097                        aopLiteral (val, 1), aopLiteral (val, 0));
1098             }
1099           if (IS_GENPTR (val->type))
1100             dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1101           else if (IS_PTR (val->type))
1102             dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1103           else
1104             dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1105         }
1106       return;
1107     }
1108
1109
1110   size = getSize (type);
1111
1112   if (size == 1)                /* Z80 specific?? */
1113     {
1114       dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1115     }
1116   else if (size == FPTRSIZE)
1117     {
1118       if (port->use_dw_for_init) {
1119         dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1120       } else {
1121         printPointerType (oBuf, val->name);
1122       }
1123     }
1124   else if (size == GPTRSIZE)
1125     {
1126       printGPointerType (oBuf, val->name, sym->name,
1127                          (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1128                           PTR_TYPE (SPEC_OCLS (val->etype))));
1129     }
1130   return;
1131 }
1132
1133 /*-----------------------------------------------------------------*/
1134 /* printIval - generates code for initial value                    */
1135 /*-----------------------------------------------------------------*/
1136 void
1137 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1138 {
1139   sym_link *itype;
1140
1141   /* if structure then    */
1142   if (IS_STRUCT (type))
1143     {
1144       printIvalStruct (sym, type, ilist, oBuf);
1145       return;
1146     }
1147
1148   /* if this is an array   */
1149   if (IS_ARRAY (type))
1150     {
1151       printIvalArray (sym, type, ilist, oBuf, check);
1152       return;
1153     }
1154
1155   if (ilist)
1156     {
1157       // not an aggregate, ilist must be a node
1158       if (ilist->type!=INIT_NODE) {
1159           // or a 1-element list
1160         if (ilist->init.deep->next) {
1161           werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1162                   sym->name);
1163         } else {
1164           ilist=ilist->init.deep;
1165         }
1166       }
1167
1168       // and the type must match
1169       itype=ilist->init.node->ftype;
1170
1171       if (compareType(type, itype)==0) {
1172         // special case for literal strings
1173         if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1174             // which are really code pointers
1175             IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1176           // no sweat
1177         } else {
1178           werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1179           printFromToType(itype, type);
1180         }
1181       }
1182     }
1183
1184   /* if this is a pointer */
1185   if (IS_PTR (type))
1186     {
1187       printIvalPtr (sym, type, ilist, oBuf);
1188       return;
1189     }
1190
1191   /* if type is SPECIFIER */
1192   if (IS_SPEC (type))
1193     {
1194       printIvalType (sym, type, ilist, oBuf);
1195       return;
1196     }
1197 }
1198
1199 /*-----------------------------------------------------------------*/
1200 /* emitStaticSeg - emitcode for the static segment                 */
1201 /*-----------------------------------------------------------------*/
1202 void
1203 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1204 {
1205   symbol *sym;
1206
1207   /* fprintf(out, "\t.area\t%s\n", map->sname); */
1208
1209   /* for all variables in this segment do */
1210   for (sym = setFirstItem (map->syms); sym;
1211        sym = setNextItem (map->syms))
1212     {
1213
1214       /* if it is "extern" then do nothing */
1215       if (IS_EXTERN (sym->etype))
1216         continue;
1217
1218       /* if it is not static add it to the public table */
1219       if (!IS_STATIC (sym->etype))
1220         {
1221           addSetHead (&publics, sym);
1222         }
1223
1224       /* print extra debug info if required */
1225       if (options.debug)
1226         {
1227           if (!sym->level)
1228             {                     /* global */
1229               if (IS_STATIC (sym->etype))
1230                 dbuf_printf (oBuf, "F%s$", moduleName);        /* scope is file */
1231               else
1232                 dbuf_printf (oBuf, "G$");      /* scope is global */
1233             }
1234           else
1235             {
1236               /* symbol is local */
1237               dbuf_printf (oBuf, "L%s$",
1238                            (sym->localof ? sym->localof->name : "-null-"));
1239             }
1240           dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1241         }
1242
1243       /* if it has an absolute address and no initializer */
1244       if (SPEC_ABSA (sym->etype) && !sym->ival)
1245         {
1246           if (options.debug)
1247             dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1248
1249           dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1250                    sym->rname,
1251                    SPEC_ADDR (sym->etype));
1252         }
1253       else
1254         {
1255           if (options.debug)
1256             dbuf_printf (oBuf, " == .\n");
1257
1258           /* if it has an initial value */
1259           if (sym->ival)
1260             {
1261               if (SPEC_ABSA (sym->etype))
1262                 {
1263                   dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1264                 }
1265               dbuf_printf (oBuf, "%s:\n", sym->rname);
1266               ++noAlloc;
1267               resolveIvalSym (sym->ival, sym->type);
1268               printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1269               --noAlloc;
1270               /* if sym is a simple string and sym->ival is a string,
1271                  WE don't need it anymore */
1272               if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1273                   IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1274                   list2val(sym->ival)->sym->isstrlit) {
1275                 freeStringSymbol(list2val(sym->ival)->sym);
1276               }
1277             }
1278           else {
1279               /* allocate space */
1280               int size = getSize (sym->type);
1281
1282               if (size==0) {
1283                   werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1284               }
1285               dbuf_printf (oBuf, "%s:\n", sym->rname);
1286               /* special case for character strings */
1287               if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1288                   SPEC_CVAL (sym->etype).v_char)
1289                   printChar (oBuf,
1290                              SPEC_CVAL (sym->etype).v_char,
1291                              size);
1292               else
1293                   dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1294             }
1295         }
1296     }
1297 }
1298
1299 /*-----------------------------------------------------------------*/
1300 /* emitMaps - emits the code for the data portion the code         */
1301 /*-----------------------------------------------------------------*/
1302 void
1303 emitMaps (void)
1304 {
1305   int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all  */
1306                                    /* ports but let's be conservative - EEP */
1307
1308   inInitMode++;
1309   /* no special considerations for the following
1310      data, idata & bit & xdata */
1311   emitRegularMap (data, TRUE, TRUE);
1312   emitRegularMap (idata, TRUE, TRUE);
1313   emitRegularMap (d_abs, TRUE, TRUE);
1314   emitRegularMap (i_abs, TRUE, TRUE);
1315   emitRegularMap (bit, TRUE, TRUE);
1316   emitRegularMap (pdata, TRUE, TRUE);
1317   emitRegularMap (xdata, TRUE, TRUE);
1318   emitRegularMap (x_abs, TRUE, TRUE);
1319   if (port->genXINIT) {
1320     emitRegularMap (xidata, TRUE, TRUE);
1321   }
1322   emitRegularMap (sfr, publicsfr, FALSE);
1323   emitRegularMap (sfrbit, publicsfr, FALSE);
1324   emitRegularMap (home, TRUE, FALSE);
1325   emitRegularMap (code, TRUE, FALSE);
1326
1327   if (options.const_seg) {
1328     dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1329   }
1330   emitStaticSeg (statsg, &code->oBuf);
1331   if (port->genXINIT) {
1332     dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1333     emitStaticSeg (xinit, &code->oBuf);
1334   }
1335   dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1336   emitStaticSeg (c_abs, &code->oBuf);
1337   inInitMode--;
1338 }
1339
1340 /*-----------------------------------------------------------------*/
1341 /* flushStatics - flush all currently defined statics out to file  */
1342 /*  and delete.  Temporary function                                */
1343 /*-----------------------------------------------------------------*/
1344 void
1345 flushStatics (void)
1346 {
1347   emitStaticSeg (statsg, codeOutBuf);
1348   statsg->syms = NULL;
1349 }
1350
1351 /*-----------------------------------------------------------------*/
1352 /* createInterruptVect - creates the interrupt vector              */
1353 /*-----------------------------------------------------------------*/
1354 void
1355 createInterruptVect (struct dbuf_s *vBuf)
1356 {
1357   mainf = newSymbol ("main", 0);
1358   mainf->block = 0;
1359
1360   /* only if the main function exists */
1361   if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1362     {
1363       if (!options.cc_only && !noAssemble && !options.c1mode)
1364         werror (E_NO_MAIN);
1365       return;
1366     }
1367
1368   /* if the main is only a prototype ie. no body then do nothing */
1369   if (!IFFUNC_HASBODY(mainf->type))
1370     {
1371       /* if ! compile only then main function should be present */
1372       if (!options.cc_only && !noAssemble)
1373         werror (E_NO_MAIN);
1374       return;
1375     }
1376
1377   dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1378   dbuf_printf (vBuf, "__interrupt_vect:\n");
1379
1380
1381   if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1382     {
1383       /* There's no such thing as a "generic" interrupt table header. */
1384       wassert(0);
1385     }
1386 }
1387
1388 char *iComments1 =
1389 {
1390   ";--------------------------------------------------------\n"
1391   "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1392
1393 char *iComments2 =
1394 {
1395   ";--------------------------------------------------------\n"};
1396
1397
1398 /*-----------------------------------------------------------------*/
1399 /* initialComments - puts in some initial comments                 */
1400 /*-----------------------------------------------------------------*/
1401 void
1402 initialComments (FILE * afile)
1403 {
1404   time_t t;
1405   time (&t);
1406   fprintf (afile, "%s", iComments1);
1407   fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1408            getBuildNumber(), getBuildDate(), getBuildEnvironment());
1409   fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1410   fprintf (afile, "%s", iComments2);
1411 }
1412
1413 /*-----------------------------------------------------------------*/
1414 /* printPublics - generates .global for publics                    */
1415 /*-----------------------------------------------------------------*/
1416 void
1417 printPublics (FILE * afile)
1418 {
1419   symbol *sym;
1420
1421   fprintf (afile, "%s", iComments2);
1422   fprintf (afile, "; Public variables in this module\n");
1423   fprintf (afile, "%s", iComments2);
1424
1425   for (sym = setFirstItem (publics); sym;
1426        sym = setNextItem (publics))
1427     tfprintf (afile, "\t!global\n", sym->rname);
1428 }
1429
1430 /*-----------------------------------------------------------------*/
1431 /* printExterns - generates .global for externs                    */
1432 /*-----------------------------------------------------------------*/
1433 void
1434 printExterns (FILE * afile)
1435 {
1436   symbol *sym;
1437
1438   fprintf (afile, "%s", iComments2);
1439   fprintf (afile, "; Externals used\n");
1440   fprintf (afile, "%s", iComments2);
1441
1442   for (sym = setFirstItem (externs); sym;
1443        sym = setNextItem (externs))
1444     tfprintf (afile, "\t!extern\n", sym->rname);
1445 }
1446
1447 /*-----------------------------------------------------------------*/
1448 /* emitOverlay - will emit code for the overlay stuff              */
1449 /*-----------------------------------------------------------------*/
1450 static void
1451 emitOverlay (struct dbuf_s * aBuf)
1452 {
1453   set *ovrset;
1454
1455   if (!elementsInSet (ovrSetSets))
1456     dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1457
1458   /* for each of the sets in the overlay segment do */
1459   for (ovrset = setFirstItem (ovrSetSets); ovrset;
1460        ovrset = setNextItem (ovrSetSets))
1461     {
1462
1463       symbol *sym;
1464
1465       if (elementsInSet (ovrset))
1466         {
1467           /* output the area informtion */
1468           dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name);     /* MOF */
1469         }
1470
1471       for (sym = setFirstItem (ovrset); sym;
1472            sym = setNextItem (ovrset))
1473         {
1474           /* if extern then it is in the publics table: do nothing */
1475           if (IS_EXTERN (sym->etype))
1476             continue;
1477
1478           /* if allocation required check is needed
1479              then check if the symbol really requires
1480              allocation only for local variables */
1481           if (!IS_AGGREGATE (sym->type) &&
1482               !(sym->_isparm && !IS_REGPARM (sym->etype))
1483               && !sym->allocreq && sym->level)
1484             continue;
1485
1486           /* if global variable & not static or extern
1487              and addPublics allowed then add it to the public set */
1488           if ((sym->_isparm && !IS_REGPARM (sym->etype))
1489               && !IS_STATIC (sym->etype))
1490             {
1491               addSetHead (&publics, sym);
1492             }
1493
1494           /* if extern then do nothing or is a function
1495              then do nothing */
1496           if (IS_FUNC (sym->type))
1497             continue;
1498
1499           /* print extra debug info if required */
1500           if (options.debug)
1501             {
1502               if (!sym->level)
1503                 {               /* global */
1504                   if (IS_STATIC (sym->etype))
1505                     dbuf_printf (aBuf, "F%s$", moduleName);        /* scope is file */
1506                   else
1507                     dbuf_printf (aBuf, "G$");      /* scope is global */
1508                 }
1509               else
1510                 /* symbol is local */
1511                 dbuf_printf (aBuf, "L%s$",
1512                          (sym->localof ? sym->localof->name : "-null-"));
1513               dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1514             }
1515
1516           /* if is has an absolute address then generate
1517              an equate for this no need to allocate space */
1518           if (SPEC_ABSA (sym->etype))
1519             {
1520
1521               if (options.debug)
1522                 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1523
1524               dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1525                        sym->rname,
1526                        SPEC_ADDR (sym->etype));
1527             }
1528           else
1529             {
1530               int size = getSize(sym->type);
1531
1532               if (size==0) {
1533                   werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1534               }
1535               if (options.debug)
1536                   dbuf_printf (aBuf, "==.\n");
1537
1538               /* allocate space */
1539               dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1540               dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1541           }
1542
1543         }
1544     }
1545 }
1546
1547 /*-----------------------------------------------------------------*/
1548 /* glue - the final glue that hold the whole thing together        */
1549 /*-----------------------------------------------------------------*/
1550 void
1551 glue (void)
1552 {
1553   struct dbuf_s vBuf;
1554   struct dbuf_s ovrBuf;
1555   FILE *asmFile;
1556   int mcs51_like;
1557
1558   dbuf_init (&vBuf, 4096);
1559   dbuf_init (&ovrBuf, 4096);
1560
1561   mcs51_like = (port->general.glue_up_main &&
1562     (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1563
1564   /* print the global struct definitions */
1565   if (options.debug)
1566     cdbStructBlock (0);
1567
1568   /* PENDING: this isn't the best place but it will do */
1569   if (port->general.glue_up_main)
1570     {
1571       /* create the interrupt vector table */
1572       createInterruptVect (&vBuf);
1573     }
1574
1575   /* emit code for the all the variables declared */
1576   emitMaps ();
1577   /* do the overlay segments */
1578   emitOverlay (&ovrBuf);
1579
1580   outputDebugSymbols ();
1581
1582   /* now put it all together into the assembler file */
1583   /* create the assembler file name */
1584
1585   /* -o option overrides default name? */
1586   if ((noAssemble || options.c1mode) && fullDstFileName)
1587     {
1588       strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1589     }
1590   else
1591     {
1592       strncpyz (scratchFileName, dstFileName, PATH_MAX);
1593       strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1594     }
1595
1596   if (!(asmFile = fopen (scratchFileName, "w")))
1597     {
1598       werror (E_FILE_OPEN_ERR, scratchFileName);
1599       exit (EXIT_FAILURE);
1600     }
1601
1602   /* initial comments */
1603   initialComments (asmFile);
1604
1605   /* print module name */
1606   tfprintf (asmFile, "\t!module\n", moduleName);
1607   if (mcs51_like)
1608     {
1609       fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1610
1611       switch(options.model)
1612         {
1613         case MODEL_SMALL:   fprintf (asmFile, " --model-small");   break;
1614         case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1615         case MODEL_MEDIUM:  fprintf (asmFile, " --model-medium");  break;
1616         case MODEL_LARGE:   fprintf (asmFile, " --model-large");   break;
1617         case MODEL_FLAT24:  fprintf (asmFile, " --model-flat24");  break;
1618         case MODEL_PAGE0:   fprintf (asmFile, " --model-page0");   break;
1619         default: break;
1620         }
1621       /*if(options.stackAuto)      fprintf (asmFile, " --stack-auto");*/
1622       if(options.useXstack)      fprintf (asmFile, " --xstack");
1623       /*if(options.intlong_rent)   fprintf (asmFile, " --int-long-rent");*/
1624       /*if(options.float_rent)     fprintf (asmFile, " --float-rent");*/
1625       if(options.noRegParams)    fprintf (asmFile, " --no-reg-params");
1626       if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1627       fprintf (asmFile, "\n");
1628     }
1629   else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1630     {
1631       fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1632     }
1633
1634   tfprintf (asmFile, "\t!fileprelude\n");
1635
1636   /* Let the port generate any global directives, etc. */
1637   if (port->genAssemblerPreamble)
1638     {
1639       port->genAssemblerPreamble (asmFile);
1640     }
1641
1642   /* print the global variables in this module */
1643   printPublics (asmFile);
1644   if (port->assembler.externGlobal)
1645     printExterns (asmFile);
1646
1647   if (( mcs51_like )
1648      ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1649     {
1650       /* copy the sfr segment */
1651       fprintf (asmFile, "%s", iComments2);
1652       fprintf (asmFile, "; special function registers\n");
1653       fprintf (asmFile, "%s", iComments2);
1654       dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1655     }
1656
1657   if (mcs51_like)
1658     {
1659       /* copy the sbit segment */
1660       fprintf (asmFile, "%s", iComments2);
1661       fprintf (asmFile, "; special function bits\n");
1662       fprintf (asmFile, "%s", iComments2);
1663       dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1664
1665       /*JCF: Create the areas for the register banks*/
1666       if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1667         {
1668           fprintf (asmFile, "%s", iComments2);
1669           fprintf (asmFile, "; overlayable register banks\n");
1670           fprintf (asmFile, "%s", iComments2);
1671           if (RegBankUsed[0])
1672             fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1673           if (RegBankUsed[1] || options.parms_in_bank1)
1674             fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1675           if (RegBankUsed[2])
1676             fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1677           if (RegBankUsed[3])
1678             fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1679         }
1680       if (BitBankUsed)
1681         {
1682           fprintf (asmFile, "%s", iComments2);
1683           fprintf (asmFile, "; overlayable bit register bank\n");
1684           fprintf (asmFile, "%s", iComments2);
1685           fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1686           fprintf (asmFile, "bits:\n\t.ds 1\n");
1687           fprintf (asmFile, "\tb0 = bits[0]\n");
1688           fprintf (asmFile, "\tb1 = bits[1]\n");
1689           fprintf (asmFile, "\tb2 = bits[2]\n");
1690           fprintf (asmFile, "\tb3 = bits[3]\n");
1691           fprintf (asmFile, "\tb4 = bits[4]\n");
1692           fprintf (asmFile, "\tb5 = bits[5]\n");
1693           fprintf (asmFile, "\tb6 = bits[6]\n");
1694           fprintf (asmFile, "\tb7 = bits[7]\n");
1695         }
1696     }
1697
1698   /* copy the data segment */
1699   fprintf (asmFile, "%s", iComments2);
1700   fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1701   fprintf (asmFile, "%s", iComments2);
1702   dbuf_write_and_destroy (&data->oBuf, asmFile);
1703
1704
1705   /* create the overlay segments */
1706   if (overlay)
1707     {
1708       fprintf (asmFile, "%s", iComments2);
1709       fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1710       fprintf (asmFile, "%s", iComments2);
1711       dbuf_write_and_destroy (&ovrBuf, asmFile);
1712     }
1713
1714   /* create the stack segment MOF */
1715   if (mainf && IFFUNC_HASBODY (mainf->type))
1716     {
1717       fprintf (asmFile, "%s", iComments2);
1718       fprintf (asmFile, "; Stack segment in internal ram \n");
1719       fprintf (asmFile, "%s", iComments2);
1720       fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1721                "__start__stack:\n\t.ds\t1\n\n");
1722     }
1723
1724   /* create the idata segment */
1725   if ((idata) && (mcs51_like))
1726     {
1727       fprintf (asmFile, "%s", iComments2);
1728       fprintf (asmFile, "; indirectly addressable internal ram data\n");
1729       fprintf (asmFile, "%s", iComments2);
1730       dbuf_write_and_destroy (&idata->oBuf, asmFile);
1731     }
1732
1733   /* create the absolute idata/data segment */
1734   if ((i_abs) && (mcs51_like))
1735     {
1736       fprintf (asmFile, "%s", iComments2);
1737       fprintf (asmFile, "; absolute internal ram data\n");
1738       fprintf (asmFile, "%s", iComments2);
1739       dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1740       dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1741     }
1742
1743   /* copy the bit segment */
1744   if (mcs51_like)
1745     {
1746       fprintf (asmFile, "%s", iComments2);
1747       fprintf (asmFile, "; bit data\n");
1748       fprintf (asmFile, "%s", iComments2);
1749       dbuf_write_and_destroy (&bit->oBuf, asmFile);
1750     }
1751
1752   /* copy paged external ram data */
1753   if (mcs51_like)
1754     {
1755       fprintf (asmFile, "%s", iComments2);
1756       fprintf (asmFile, "; paged external ram data\n");
1757       fprintf (asmFile, "%s", iComments2);
1758       dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1759     }
1760
1761   /* if external stack then reserve space for it */
1762   if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1763     {
1764       fprintf (asmFile, "%s", iComments2);
1765       fprintf (asmFile, "; external stack \n");
1766       fprintf (asmFile, "%s", iComments2);
1767       fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1768                "__start__xstack:\n\t.ds\t1\n\n");
1769     }
1770
1771   /* copy external ram data */
1772   if (mcs51_like)
1773     {
1774       fprintf (asmFile, "%s", iComments2);
1775       fprintf (asmFile, "; external ram data\n");
1776       fprintf (asmFile, "%s", iComments2);
1777       dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1778     }
1779
1780   /* create the absolute xdata segment */
1781   if (mcs51_like || TARGET_IS_HC08)
1782     {
1783       fprintf (asmFile, "%s", iComments2);
1784       fprintf (asmFile, "; absolute external ram data\n");
1785       fprintf (asmFile, "%s", iComments2);
1786       dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1787     }
1788
1789   /* copy external initialized ram data */
1790   fprintf (asmFile, "%s", iComments2);
1791   fprintf (asmFile, "; external initialized ram data\n");
1792   fprintf (asmFile, "%s", iComments2);
1793   dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1794
1795   /* If the port wants to generate any extra areas, let it do so. */
1796   if (port->extraAreas.genExtraAreaDeclaration)
1797     {
1798       port->extraAreas.genExtraAreaDeclaration(asmFile,
1799                                                mainf && IFFUNC_HASBODY(mainf->type));
1800     }
1801
1802   /* copy the interrupt vector table */
1803   if (mainf && IFFUNC_HASBODY (mainf->type))
1804     {
1805       fprintf (asmFile, "%s", iComments2);
1806       fprintf (asmFile, "; interrupt vector \n");
1807       fprintf (asmFile, "%s", iComments2);
1808       dbuf_write_and_destroy (&vBuf, asmFile);
1809     }
1810
1811   /* copy global & static initialisations */
1812   fprintf (asmFile, "%s", iComments2);
1813   fprintf (asmFile, "; global & static initialisations\n");
1814   fprintf (asmFile, "%s", iComments2);
1815
1816   /* Everywhere we generate a reference to the static_name area,
1817    * (which is currently only here), we immediately follow it with a
1818    * definition of the post_static_name area. This guarantees that
1819    * the post_static_name area will immediately follow the static_name
1820    * area.
1821    */
1822   tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1823   tfprintf (asmFile, "\t!area\n", port->mem.static_name);       /* MOF */
1824   tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1825   tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1826
1827   if (mainf && IFFUNC_HASBODY (mainf->type))
1828     {
1829       if (port->genInitStartup)
1830         {
1831            port->genInitStartup (asmFile);
1832         }
1833       else
1834         {
1835           assert (mcs51_like);
1836           fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1837           /* if external stack is specified then the
1838              higher order byte of the xdatalocation is
1839              going into P2 and the lower order going into
1840              spx */
1841           if (options.useXstack)
1842             {
1843               fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1844                        (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1845               fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1846                        (unsigned int) options.xdata_loc & 0xff);
1847             }
1848
1849           // This should probably be a port option, but I'm being lazy.
1850           // on the 400, the firmware boot loader gives us a valid stack
1851           // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1852           if (!TARGET_IS_DS400)
1853             {
1854               /* initialise the stack pointer.  JCF: aslink takes care of the location */
1855               fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n");     /* MOF */
1856             }
1857
1858           fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1859           fprintf (asmFile, "\tmov\ta,dpl\n");
1860           fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1861           fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1862           fprintf (asmFile, "__sdcc_init_data:\n");
1863
1864           // if the port can copy the XINIT segment to XISEG
1865           if (port->genXINIT)
1866             {
1867               port->genXINIT (asmFile);
1868             }
1869         }
1870     }
1871   dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1872
1873   if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1874     {
1875       /* This code is generated in the post-static area.
1876        * This area is guaranteed to follow the static area
1877        * by the ugly shucking and jiving about 20 lines ago.
1878        */
1879       tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1880       fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1881     }
1882
1883   fprintf (asmFile,
1884            "%s"
1885            "; Home\n"
1886            "%s", iComments2, iComments2);
1887   tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1888   dbuf_write_and_destroy (&home->oBuf, asmFile);
1889
1890   if (mainf && IFFUNC_HASBODY (mainf->type))
1891     {
1892       /* entry point @ start of HOME */
1893       fprintf (asmFile, "__sdcc_program_startup:\n");
1894
1895       /* put in jump or call to main */
1896       if (options.mainreturn)
1897         {
1898           fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l');   /* needed? */
1899           fprintf (asmFile, ";\treturn from main will return to caller\n");
1900         }
1901       else
1902         {
1903           fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1904           fprintf (asmFile, ";\treturn from main will lock up\n");
1905           fprintf (asmFile, "\tsjmp .\n");
1906         }
1907     }
1908   /* copy over code */
1909   fprintf (asmFile, "%s", iComments2);
1910   fprintf (asmFile, "; code\n");
1911   fprintf (asmFile, "%s", iComments2);
1912   tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1913   dbuf_write_and_destroy (&code->oBuf, asmFile);
1914
1915   if (port->genAssemblerEnd)
1916     {
1917       port->genAssemblerEnd (asmFile);
1918     }
1919   fclose (asmFile);
1920 }