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