Update svn merge history.
[sdcc.git] / sdcc / src / SDCCglue.c
blob9e7e977f6fe4239461aafb4b0f6f9191109ad4dc
1 /*-------------------------------------------------------------------------
2 SDCCglue.c - glues everything we have done together into one file.
4 Copyright (C) 1998 Sandeep Dutta . sandeep.dutta@usa.net
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.
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.
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 -------------------------------------------------------------------------*/
21 #include "common.h"
22 #include <time.h>
23 #include "newalloc.h"
24 #include <fcntl.h>
25 #include <sys/stat.h>
26 #include "dbuf_string.h"
28 #ifdef _WIN32
29 #include <io.h>
30 #else
31 #include <unistd.h>
32 #endif
34 symbol *interrupts[INTNO_MAX + 1];
36 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *, bool check);
37 set *publics = NULL; /* public variables */
38 set *externs = NULL; /* Variables that are declared as extern */
39 set *strSym = NULL; /* string initializers */
40 set *ccpStr = NULL; /* char * const pointers with a string literal initializer */
42 unsigned maxInterrupts = 0;
43 int allocInfo = 1;
44 symbol *mainf;
45 int noInit = 0; /* no initialization */
48 char *
49 aopLiteralGptr (const char *name, const value *val)
51 unsigned long v = ulFromVal (val);
52 struct dbuf_s dbuf;
54 dbuf_init (&dbuf, 128);
56 v >>= ((GPTRSIZE - 1) * 8);
58 if (IS_FUNCPTR (val->type))
59 dbuf_tprintf (&dbuf, "!immedbyte", v | pointerTypeToGPByte (DCL_TYPE (val->type->next), val->name, name));
60 else if (IS_PTR (val->type) && !IS_GENPTR (val->type))
61 dbuf_tprintf (&dbuf, "!immedbyte", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, name));
62 else
63 dbuf_tprintf (&dbuf, "!immedbyte", (unsigned int) v & 0xff);
65 return dbuf_detach_c_str (&dbuf);
68 const char *
69 aopLiteralLong (value *val, int offset, int size)
71 unsigned long v;
72 struct dbuf_s dbuf;
74 if (!val)
76 // assuming we have been warned before
77 val = constCharVal (0);
80 dbuf_init (&dbuf, 128);
82 switch (size)
84 case 1:
85 v = byteOfVal (val, offset);
86 dbuf_tprintf (&dbuf, "!immedbyte", (unsigned int) v & 0xff);
87 break;
88 case 2:
89 v = byteOfVal (val, offset+1);
90 v = (v << 8) | byteOfVal (val, offset);
91 dbuf_tprintf (&dbuf, "!immedword", (unsigned int) v & 0xffff);
92 break;
93 case 3:
94 v = byteOfVal (val, offset+2);
95 v = (v << 8) | byteOfVal (val, offset+1);
96 v = (v << 8) | byteOfVal (val, offset);
97 // we don't have a !immedword24 yet for ds390
98 dbuf_printf (&dbuf, "#0x%06X", (unsigned int) v & 0xffffff);
99 break;
100 default:
101 /* Hmm. Too big for now. */
102 assert (0);
104 return dbuf_detach_c_str (&dbuf);
107 /*-----------------------------------------------------------------*/
108 /* aopLiteral - string from a literal value */
109 /*-----------------------------------------------------------------*/
110 const char *
111 aopLiteral (value *val, int offset)
113 return aopLiteralLong (val, offset, 1);
116 /*-----------------------------------------------------------------*/
117 /* emitDebugSym - emit label for debug symbol */
118 /*-----------------------------------------------------------------*/
119 static void
120 emitDebugSym (struct dbuf_s *oBuf, symbol * sym)
122 if (sym->level && sym->localof) /* symbol scope is local */
124 dbuf_printf (oBuf, "L%s.%s$", moduleName, sym->localof->name);
126 else if (IS_STATIC (sym->etype)) /* symbol scope is file */
128 dbuf_printf (oBuf, "F%s$", moduleName);
130 else /* symbol scope is global */
132 dbuf_printf (oBuf, "G$");
134 dbuf_printf (oBuf, "%s$%ld_%ld$%d", sym->name, sym->level / LEVEL_UNIT, sym->level % LEVEL_UNIT, sym->block);
137 /*-----------------------------------------------------------------*/
138 /* emitRegularMap - emit code for maps with no special cases */
139 /*-----------------------------------------------------------------*/
140 static void
141 emitRegularMap (memmap *map, bool addPublics, bool arFlag)
143 symbol *sym;
144 ast *ival = NULL;
146 if (!map)
147 return;
149 if (addPublics)
151 /* PENDING: special case here - should remove */
152 if (!strcmp (map->sname, CODE_NAME))
154 if (options.code_seg && strcmp (CODE_NAME, options.code_seg))
155 dbuf_tprintf (&map->oBuf, "\t!areacode\n", options.code_seg);
156 else
157 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
159 else if (!strcmp (map->sname, DATA_NAME))
161 if (options.data_seg && strcmp (DATA_NAME, options.data_seg))
162 dbuf_tprintf (&map->oBuf, "\t!areadata\n", options.data_seg);
163 else
164 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
166 else if (!strcmp (map->sname, HOME_NAME))
167 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
168 else
169 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
171 if (map->regsp)
172 dbuf_tprintf (&map->oBuf, "\t!org\n", 0);
175 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
177 symbol *newSym = NULL;
179 /* if allocation required check is needed
180 then check if the symbol really requires
181 allocation only for local variables */
183 if (arFlag && !IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level)
184 continue;
186 /* for bitvar locals and parameters */
187 if (!arFlag && !sym->allocreq && sym->level && !SPEC_ABSA (sym->etype))
189 continue;
192 /* if global variable & not static or extern
193 and addPublics allowed then add it to the public set */
194 if ((sym->level == 0 ||
195 (sym->_isparm && !IS_REGPARM (sym->etype) && !IS_STATIC (sym->localof->etype))) &&
196 addPublics &&
197 !IS_STATIC (sym->etype) &&
198 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : (!IS_EXTERN (sym->etype) || sym->ival)) &&
199 !(IFFUNC_ISINLINE (sym->type) && !IS_STATIC (sym->etype) && !IS_EXTERN (sym->etype)))
201 addSetHead (&publics, sym);
204 /* if extern then add it into the extern list */
205 if (IS_EXTERN (sym->etype) && !sym->ival)
207 addSetHead (&externs, sym);
208 continue;
211 /* if extern then do nothing or is a function
212 then do nothing */
213 if (IS_FUNC (sym->type) && !(sym->isitmp))
214 continue;
216 /* if it has an initial value then do it only if
217 it is a global variable */
218 if (sym->ival && sym->level == 0)
220 if ((SPEC_OCLS (sym->etype) == xidata || SPEC_OCLS (sym->etype) == initialized) && !SPEC_ABSA (sym->etype) && !SPEC_ADDRSPACE (sym->etype))
222 sym_link *t;
223 ast *ival = NULL;
224 symbol *tsym = copySymbol (sym);
226 // check for constant
227 if (IS_AGGREGATE (tsym->type))
229 ival = initAggregates (tsym, tsym->ival, NULL);
231 else
233 if (getNelements (tsym->type, tsym->ival) > 1)
235 werrorfl (tsym->fileDef, tsym->lineDef, W_EXCESS_INITIALIZERS, "scalar", tsym->name);
237 ival = newNode ('=', newAst_VALUE (symbolVal (tsym)),
238 decorateType (resolveSymbols (list2expr (tsym->ival)), RESULT_TYPE_NONE, true));
240 if (ival)
242 // No point trying to initialize by something that doesn't even make sense.
243 if (astErrors (ival))
244 continue;
246 // set ival's lineno to where the symbol was defined
247 setAstFileLine (ival, filename = tsym->fileDef, lineno = tsym->lineDef);
248 // check if this is not a constant expression
249 if (!constExprTree (ival))
251 werrorfl (ival->filename, ival->lineno, E_CONST_EXPECTED, "found expression");
252 continue; // Don't even try to do it anyway to avoid segfaults later.
256 /* create a new "XINIT (CODE)" symbol, that will be emitted later
257 in the static seg */
258 newSym = copySymbol (sym);
259 SPEC_OCLS (newSym->etype) = (SPEC_OCLS (sym->etype) == xidata) ? xinit : initializer;
260 SNPRINTF (newSym->name, sizeof (newSym->name), "__xinit_%s", sym->name);
261 SNPRINTF (newSym->rname, sizeof (newSym->rname), "__xinit_%s", sym->rname);
263 /* find the first non-array link */
264 t = newSym->type;
265 while (IS_ARRAY (t))
266 t = t->next;
267 if (IS_SPEC (t))
268 SPEC_CONST (t) = 1;
269 else
270 DCL_PTR_CONST (t) = 1;
271 SPEC_STAT (newSym->etype) = 1;
273 strSym = NULL;
274 ++noAlloc;
275 resolveIvalSym (newSym->ival, newSym->type);
276 --noAlloc;
278 // add it to the "XINIT (CODE)" segment
279 addSet ((SPEC_OCLS (sym->etype) == xidata) ? &xinit->syms : &initializer->syms, newSym);
281 if (!SPEC_ABSA (sym->etype))
283 struct dbuf_s tmpBuf;
284 symbol *ps = NULL;
285 set *tmpSym = NULL;
287 wassert(dbuf_init (&tmpBuf, 4096));
288 // before allocation we must parse the sym->ival tree
289 // but without actually generating initialization code
290 ++noAlloc;
291 resolveIvalSym (sym->ival, sym->type);
292 ++noInit;
293 printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
294 --noInit;
295 --noAlloc;
297 // delete redundant __str_%d symbols (initializer for char arrays)
298 for (ps = setFirstItem (statsg->syms); ps; ps = setNextItem (statsg->syms))
299 if (!strstr (tmpBuf.buf, ps->name) && isinSet (strSym, ps))
300 addSet (&tmpSym, ps);
301 for (ps = setFirstItem (tmpSym); ps; ps = setNextItem (tmpSym))
302 deleteSetItem (&statsg->syms, ps);
304 deleteSet (&tmpSym);
305 dbuf_destroy (&tmpBuf);
308 if (strSym)
309 deleteSet (&strSym);
311 else
313 if (IS_AGGREGATE (sym->type))
315 ival = initAggregates (sym, sym->ival, NULL);
317 else
319 if (getNelements (sym->type, sym->ival) > 1)
321 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
323 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
324 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE, true));
326 codeOutBuf = &statsg->oBuf;
328 if (ival && !astErrors (ival)) // No point trying to initialize by something that doesn't even make sense.
330 // set ival's lineno to where the symbol was defined
331 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
332 // check if this is not a constant expression
333 if (!constExprTree (ival))
335 werrorfl (ival->filename, ival->lineno, E_CONST_EXPECTED, "found expression");
336 // Don't try to do it anyway, as this is likely to result in a segfault in codegen later, especially if the expression contains function calls.
338 else
340 allocInfo = 0;
341 if (!astErrors (ival))
342 eBBlockFromiCode (iCodeFromAst (ival));
343 allocInfo = 1;
349 /* if it has an absolute address then generate
350 an equate for this no need to allocate space */
351 if (SPEC_ABSA (sym->etype) && !sym->ival)
353 char *equ = "=";
355 /* print extra debug info if required */
356 if (options.debug)
358 emitDebugSym (&map->oBuf, sym);
359 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
361 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
363 else
365 int size = getSize (sym->type) + sym->flexArrayLength;
366 if (size == 0)
368 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
370 /* allocate space */
371 if (SPEC_ABSA (sym->etype))
373 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
375 /* print extra debug info if required */
376 if (options.debug)
378 emitDebugSym (&map->oBuf, sym);
379 dbuf_printf (&map->oBuf, "==.\n");
381 if (IS_STATIC (sym->etype) || sym->level)
382 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
383 else
384 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
385 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
388 sym->ival = NULL;
392 /*-----------------------------------------------------------------*/
393 /* initValPointer - pointer initialization code massaging */
394 /*-----------------------------------------------------------------*/
395 value *
396 initValPointer (ast *expr)
398 value *val;
400 /* no then we have to do these kludgy checks */
401 /* pointers can be initialized with address of
402 a variable or address of an array element */
403 if (IS_ADDRESS_OF_OP (expr))
405 /* address of symbol */
406 if (IS_AST_SYM_VALUE (expr->left))
408 STORAGE_CLASS sclass = SPEC_SCLS (expr->left->etype);
409 memmap *oclass = SPEC_OCLS (expr->left->etype);
411 val = AST_VALUE (expr->left);
412 val->type = newLink (DECLARATOR);
413 if (sclass == S_CODE)
415 DCL_TYPE (val->type) = CPOINTER;
416 CodePtrPointsToConst (val->type);
418 else if (oclass)
419 DCL_TYPE (val->type) = oclass->ptrType;
420 else if (sclass == S_XDATA)
421 DCL_TYPE (val->type) = FPOINTER;
422 else if (sclass == S_DATA)
423 DCL_TYPE (val->type) = POINTER;
424 else if (sclass == S_IDATA)
425 DCL_TYPE (val->type) = IPOINTER;
426 else if (sclass == S_PDATA)
427 DCL_TYPE (val->type) = PPOINTER;
428 else if (sclass == S_XSTACK)
429 DCL_TYPE (val->type) = PPOINTER;
430 else if (sclass == S_EEPROM)
431 DCL_TYPE (val->type) = EEPPOINTER;
432 else
433 DCL_TYPE (val->type) = POINTER;
434 val->type->next = expr->left->ftype;
435 val->etype = getSpec (val->type);
436 return val;
439 /* if address of indexed array */
440 if (IS_ARRAY_OP (expr->left))
441 return valForArray (expr->left);
443 /* if address of structure element then
444 case 1. a.b ; */
445 if (IS_AST_OP (expr->left) && expr->left->opval.op == '.')
447 return valForStructElem (expr->left->left, expr->left->right);
450 /* case 2. (&a)->b ;
451 (&some_struct)->element */
452 if (IS_AST_OP (expr->left) && expr->left->opval.op == PTR_OP && IS_ADDRESS_OF_OP (expr->left->left))
454 return valForStructElem (expr->left->left->left, expr->left->right);
457 /* case 2.1. a->b */
458 if (IS_AST_OP (expr->left) && expr->left->opval.op == PTR_OP)
460 return valForStructElem (expr->left->left, expr->left->right);
464 /* case 3. (((char *) &a) +/- constant) */
465 if (IS_AST_OP (expr) &&
466 (expr->opval.op == '+' || expr->opval.op == '-') &&
467 IS_CAST_OP (expr->left) && IS_ADDRESS_OF_OP (expr->left->right) && IS_AST_LIT_VALUE (expr->right))
469 return valForCastAggr (expr->left->right->left, expr->left->left->opval.lnk, expr->right, expr->opval.op);
472 /* case 4. (array type) */
473 if (IS_AST_SYM_VALUE (expr) && IS_ARRAY (expr->ftype))
475 STORAGE_CLASS sclass = SPEC_SCLS (expr->etype);
476 memmap *oclass = SPEC_OCLS (expr->etype);
478 val = copyValue (AST_VALUE (expr));
479 val->type = newLink (DECLARATOR);
480 if (SPEC_SCLS (expr->etype) == S_CODE)
482 DCL_TYPE (val->type) = CPOINTER;
483 CodePtrPointsToConst (val->type);
485 else if (oclass)
486 DCL_TYPE (val->type) = oclass->ptrType;
487 else if (sclass == S_XDATA)
488 DCL_TYPE (val->type) = FPOINTER;
489 else if (sclass == S_DATA)
490 DCL_TYPE (val->type) = POINTER;
491 else if (sclass == S_IDATA)
492 DCL_TYPE (val->type) = IPOINTER;
493 else if (sclass == S_PDATA)
494 DCL_TYPE (val->type) = PPOINTER;
495 else if (sclass == S_XSTACK)
496 DCL_TYPE (val->type) = PPOINTER;
497 else if (sclass == S_EEPROM)
498 DCL_TYPE (val->type) = EEPPOINTER;
499 else
500 DCL_TYPE (val->type) = POINTER;
501 val->type->next = expr->ftype->next;
502 val->etype = getSpec (val->type);
503 return val;
506 /* if structure element then
507 case 5. a.b ; */
508 if (IS_AST_OP (expr) && expr->opval.op == '.')
510 return valForStructElem (expr->left, expr->right);
513 /* case 6. a->b ;
514 some_struct->element */
515 if (IS_AST_OP (expr) && expr->opval.op == PTR_OP)
517 ast *t = expr->left;
519 /*if (expr->left->left)
520 if (expr->left->left->left)
521 if (expr->left->left->opval.op == '[')
522 t = expr->left->left;
523 else
524 t = expr->left->left->left;
525 else
526 t = expr->left->left;
527 else
528 t = expr->left;*/
530 /* a more generic way of above code */
531 while (t->left != NULL && t->opval.op != '[')
532 t = t->left;
534 return valForStructElem (t, expr->right);
537 /* case 7. function name */
538 if (IS_AST_SYM_VALUE (expr) && IS_FUNC (expr->ftype))
540 return AST_VALUE (expr);
543 return NULL;
546 /*-----------------------------------------------------------------*/
547 /* initPointer - pointer initialization code massaging */
548 /*-----------------------------------------------------------------*/
549 value *
550 initPointer (initList *ilist, sym_link *toType, int showError)
552 value *val;
553 ast *expr;
555 if (!ilist)
557 return valCastLiteral (toType, 0.0, 0);
560 expr = list2expr (ilist);
562 if (!expr)
564 if (showError)
565 werror (E_CONST_EXPECTED);
566 return 0;
569 /* try it the old way first */
570 if ((val = constExprValue (expr, FALSE)))
571 return val;
573 /* ( ptr + constant ) */
574 if (IS_AST_OP (expr) &&
575 (expr->opval.op == '+' || expr->opval.op == '-') &&
576 IS_AST_SYM_VALUE (expr->left) &&
577 (IS_ARRAY (expr->left->ftype) || IS_PTR (expr->left->ftype)) &&
578 compareType (toType, expr->left->ftype, false) && IS_AST_LIT_VALUE (expr->right))
580 return valForCastAggr (expr->left, expr->left->ftype, expr->right, expr->opval.op);
583 /* (char *)(expr1) */
584 if (IS_CAST_OP (expr))
586 if (compareType (toType, expr->left->ftype, false) == 0 && showError)
588 werror (W_INIT_WRONG);
589 printFromToType (expr->left->ftype, toType);
591 val = initValPointer (expr->right);
592 if (val)
594 DECLARATOR_TYPE dcl_type = DCL_TYPE (val->type);
595 val->type = expr->left->ftype;
596 val->etype = getSpec (val->type);
597 if (IS_GENPTR (val->type))
598 DCL_TYPE (val->type) = dcl_type;
601 else
603 val = initValPointer (expr);
606 if (val)
607 return val;
609 if (showError)
611 if (expr)
612 werrorfl (expr->filename, expr->lineno, E_CONST_EXPECTED);
613 else
614 werror (E_CONST_EXPECTED);
616 return 0;
619 /*-----------------------------------------------------------------*/
620 /* printChar - formats and prints a UTF-8 character string with DB */
621 /*-----------------------------------------------------------------*/
622 void
623 printChar (struct dbuf_s *oBuf, const char *s, int plen)
625 int i;
626 int pplen = 0;
627 char buf[100];
628 char *p = buf;
630 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16) // Assembler does not support .ascii
632 while (pplen < plen)
634 if (isprint((unsigned char) *s))
635 dbuf_tprintf (oBuf, "\t!db !constbyte\t; %c\n", (unsigned char) *s, (unsigned char) *s);
636 else
637 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char) *s);
639 s++;
640 pplen++;
642 return;
645 while (pplen < plen)
647 i = 60;
648 while (i && pplen < plen)
650 if (!isprint((unsigned char) *s) || *s == '\"' || *s == '\\')
652 *p = '\0';
653 if (p != buf)
654 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
655 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char) *s);
656 p = buf;
657 i = 60;
659 else
661 *p = *s;
662 p++;
663 i--;
665 s++;
666 pplen++;
668 if (p != buf)
670 *p = '\0';
671 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
672 p = buf;
673 i = 60;
678 /*-----------------------------------------------------------------*/
679 /* printChar16 - formats and prints a UTF-16 character string with DB*/
680 /*-----------------------------------------------------------------*/
681 void
682 printChar16 (struct dbuf_s *oBuf, const TYPE_TARGET_UINT *s, int plen)
684 int pplen = 0;
686 while (pplen < plen)
688 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
690 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 0) & 0xff);
691 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 8) & 0xff);
693 else if (port->little_endian)
694 dbuf_printf (oBuf, "\t.byte %d,%d\n", (*s >> 0) & 0xff, (*s >> 8) & 0xff);
695 else
696 dbuf_printf (oBuf, "\t.byte %d,%d\n", (*s >> 8) & 0xff, (*s >> 0) & 0xff);
698 s++;
699 pplen++;
701 while (pplen < plen)
703 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
704 pplen++;
708 /*-----------------------------------------------------------------*/
709 /* printChar32 - formats and prints a UTF-32 character string with DB*/
710 /*-----------------------------------------------------------------*/
711 void
712 printChar32 (struct dbuf_s *oBuf, const TYPE_TARGET_ULONG *s, int plen)
714 int pplen = 0;
716 while (pplen < plen)
718 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
720 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 0) & 0xff);
721 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 8) & 0xff);
722 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 16) & 0xff);
723 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 24) & 0xff);
725 else if (port->little_endian)
726 dbuf_printf (oBuf, "\t.byte %d,%d,%d,%d\n", (*s >> 0) & 0xff, (*s >> 8) & 0xff, (*s >> 16) & 0xff, (*s >> 24) & 0xff);
727 else
728 dbuf_printf (oBuf, "\t.byte %d,%d,%d,%d\n", (*s >> 24) & 0xff, (*s >> 16) & 0xff, (*s >> 8) & 0xff,(*s >> 0) & 0xff);
730 s++;
731 pplen++;
733 while (pplen < plen)
735 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
736 pplen++;
740 /*-----------------------------------------------------------------*/
741 /* return the generic pointer high byte for a given pointer type. */
742 /*-----------------------------------------------------------------*/
744 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
746 switch (p_type)
748 case IPOINTER:
749 case POINTER:
750 return GPTYPE_NEAR;
751 case GPOINTER:
752 werror (W_USING_GENERIC_POINTER, iname ? iname : "<null>", oname ? oname : "<null>");
753 return -1;
754 case FPOINTER:
755 return GPTYPE_FAR;
756 case CPOINTER:
757 case FUNCTION:
758 return GPTYPE_CODE;
759 case PPOINTER:
760 return GPTYPE_XSTACK;
761 default:
762 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n", p_type);
763 exit (EXIT_FAILURE);
765 return -1;
768 /*-----------------------------------------------------------------*/
769 /* printIvalVal - generate ival according from value */
770 /*-----------------------------------------------------------------*/
771 static void printIvalVal(struct dbuf_s *oBuf, value *val, int size, bool newline)
773 if (size == 2 && port->use_dw_for_init)
775 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
776 return;
779 const bool use_ret = TARGET_PDK_LIKE && !TARGET_IS_PDK16;
781 if (!use_ret)
782 dbuf_printf (oBuf, "\t.byte ");
784 for (int i = 0; i < size; i++)
786 const char *inst;
787 const char *byte = aopLiteral (val, port->little_endian ? i : size - 1 - i);
788 if (use_ret)
789 inst = i != size - 1 ? "\tret %s\n" : "\tret %s";
790 else
791 inst = i != size - 1 ? "%s, " : "%s";
792 dbuf_printf (oBuf, inst, byte);
794 if (newline)
795 dbuf_printf (oBuf, "\n");
798 /*-----------------------------------------------------------------*/
799 /* _printPointerType - generates ival for pointer type */
800 /*-----------------------------------------------------------------*/
801 static void
802 _printPointerType (struct dbuf_s *oBuf, const char *name, int size)
804 wassert (!TARGET_PDK_LIKE);
806 if (size == 4)
808 if (port->little_endian)
809 dbuf_printf (oBuf, "\t.byte %s, (%s >> 8), (%s >> 16), (%s >> 24)", name, name, name, name);
810 else
811 dbuf_printf (oBuf, "\t.byte (%s >> 24), (%s >> 16), (%s >> 8), %s", name, name, name, name);
813 else if (size == 3)
815 if (port->little_endian)
816 dbuf_printf (oBuf, "\t.byte %s, (%s >> 8), (%s >> 16)", name, name, name);
817 else
818 dbuf_printf (oBuf, "\t.byte (%s >> 16), (%s >> 8), %s", name, name, name);
820 else
822 if (port->little_endian)
823 dbuf_printf (oBuf, "\t.byte %s, (%s >> 8)", name, name);
824 else
825 dbuf_printf (oBuf, "\t.byte (%s >> 8), %s", name, name);
829 /*-----------------------------------------------------------------*/
830 /* printPointerType - generates ival for pointer type */
831 /*-----------------------------------------------------------------*/
832 static void
833 printPointerType (struct dbuf_s *oBuf, const char *name)
835 _printPointerType (oBuf, name, (options.model == MODEL_FLAT24) ? 3 : 2);
836 dbuf_printf (oBuf, "\n");
839 /*-----------------------------------------------------------------*/
840 /* printGPointerType - generates ival for generic pointer type */
841 /*-----------------------------------------------------------------*/
842 static void
843 printGPointerType (struct dbuf_s *oBuf, const char *iname, const char *oname, int type)
845 int byte = pointerTypeToGPByte (type, iname, oname);
846 int size = (options.model == MODEL_FLAT24) ? 3 : 2;
847 if (byte == -1)
849 _printPointerType (oBuf, iname, size + 1);
850 dbuf_printf (oBuf, "\n");
852 else
854 _printPointerType (oBuf, iname, size);
855 dbuf_printf (oBuf, ",#0x%02x\n", byte);
859 /*-----------------------------------------------------------------*/
860 /* printIvalType - generates ival for int/char */
861 /*-----------------------------------------------------------------*/
862 void
863 printIvalType (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf)
865 value *val;
866 unsigned long ulVal = 0;
868 /* if initList is deep */
869 if (ilist && (ilist->type == INIT_DEEP))
870 ilist = ilist->init.deep;
872 if (!(val = list2val (ilist, FALSE)))
874 if (!!(val = initPointer (ilist, type, 0)))
876 int i, size = getSize (type), le = port->little_endian, top = (options.model == MODEL_FLAT24) ? 3 : 2;;
877 dbuf_printf (oBuf, "\t.byte ");
878 for (i = (le ? 0 : size - 1); le ? (i < size) : (i > -1); i += (le ? 1 : -1))
880 if (i == 0)
881 if (val->name && strlen (val->name) > 0)
882 dbuf_printf (oBuf, "%s", val->name);
883 else
884 dbuf_printf (oBuf, "#0x00");
885 else if (0 < i && i < top)
886 if (val->name && strlen (val->name) > 0)
887 dbuf_printf (oBuf, "(%s >> %d)", val->name, i * 8);
888 else
889 dbuf_printf (oBuf, "#0x00");
890 else
891 dbuf_printf (oBuf, "#0x00");
892 if (i == (le ? (size - 1) : 0))
893 dbuf_printf (oBuf, "\n");
894 else
895 dbuf_printf (oBuf, ", ");
897 return;
899 else
901 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
902 val = constCharVal (0);
906 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
908 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
909 val = constCharVal (0);
912 /* check if the literal value is within bounds */
913 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL)
915 werror (W_LIT_OVERFLOW);
918 if (val->type != type)
920 val = valCastLiteral (type, floatFromVal (val), (TYPE_TARGET_ULONGLONG) ullFromVal (val));
923 if (IS_INTEGRAL (val->type))
924 ulVal = ulFromVal (val);
926 switch (getSize (type))
928 case 1:
929 if (!val)
930 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
931 else
933 if (IS_UNSIGNED (val->type))
935 dbuf_tprintf (oBuf, "\t!dbs\t; %u", aopLiteral (val, 0), (unsigned int) ulVal);
937 else
939 dbuf_tprintf (oBuf, "\t!dbs\t; % d", aopLiteral (val, 0), (int) ulVal);
941 if (isalnum ((int) ulVal))
942 dbuf_tprintf (oBuf, "\t'%c'\n", (int) ulVal);
943 else
944 dbuf_tprintf (oBuf, "\n");
946 break;
948 case 2:
949 if (port->use_dw_for_init)
951 printIvalVal (oBuf, val, 2, true);
952 break;
954 printIvalVal (oBuf, val, 2, false);
955 if (IS_UNSIGNED (val->type))
956 dbuf_printf (oBuf, "\t; %u\n", (unsigned int) ulVal);
957 else
958 dbuf_printf (oBuf, "\t; % d\n", (int) ulVal);
959 break;
961 case 4:
962 if (!val)
964 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
965 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
967 else
969 printIvalVal (oBuf, val, 4, false);
971 if (IS_FLOAT (val->type))
973 dbuf_printf (oBuf, "\t; % e\n", floatFromVal (val));
975 else
977 if (IS_UNSIGNED (val->type))
978 dbuf_printf (oBuf, "\t; %u\n", (unsigned int) ulVal);
979 else
980 dbuf_printf (oBuf, "\t; % d\n", (int) ulVal);
983 break;
984 default:
985 printIvalVal (oBuf, val, getSize (type), true);
986 break;
990 /*-----------------------------------------------------------------*/
991 /* printIvalBitFields - generate initializer for bitfields */
992 /* return the number of bytes written */
993 /*-----------------------------------------------------------------*/
994 static unsigned int
995 printIvalBitFields (symbol ** sym, initList ** ilist, struct dbuf_s *oBuf)
997 symbol *lsym = *sym;
998 initList *lilist = *ilist;
999 unsigned long long ival = 0;
1000 unsigned size = 0;
1001 unsigned bit_start = 0;
1002 unsigned long int bytes_written = 0;
1004 while (lsym && IS_BITFIELD (lsym->type))
1006 unsigned bit_length = SPEC_BLEN (lsym->etype);
1007 if (0 == bit_length)
1009 /* bit-field structure member with a width of 0 */
1010 lsym = lsym->next;
1011 break;
1013 else if (!SPEC_BUNNAMED (lsym->etype))
1015 /* not an unnamed bit-field structure member */
1016 value *val = list2val (lilist, TRUE);
1018 if (val && val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1020 werrorfl (lilist->filename, lilist->lineno, E_CONST_EXPECTED);
1021 val = constCharVal (0);
1023 if (size)
1025 if (bit_length > 8)
1026 size += (bit_length + 7) / 8;
1028 else
1029 size = (bit_length + 7) / 8;
1031 /* check if the literal value is within bounds */
1032 if (val && checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL)
1034 werror (W_LIT_OVERFLOW);
1037 ival |= (ullFromVal (val) & (0xffffffffffffffffull >> (64 - bit_length))) << bit_start;
1038 lilist = lilist ? lilist->next : NULL;
1040 bit_start += bit_length;
1041 lsym = lsym->next;
1042 if (lsym && IS_BITFIELD (lsym->type) && (0 == SPEC_BSTR (lsym->etype)))
1044 /* a new integer */
1045 break;
1049 for (unsigned int i = 0; i < size ; i++)
1051 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
1052 dbuf_tprintf (oBuf, "\tret !constbyte\n", (unsigned)(((unsigned long long)ival >> i * 8) & 0xff));
1053 else
1054 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned)(((unsigned long long)ival >> i * 8) & 0xff));
1055 bytes_written++;
1058 *sym = lsym;
1059 *ilist = lilist;
1061 return (bytes_written);
1064 /*-----------------------------------------------------------------*/
1065 /* printIvalStruct - generates initial value for structures */
1066 /*-----------------------------------------------------------------*/
1067 static void
1068 printIvalStruct (symbol *sym, sym_link *type, initList *ilist, struct dbuf_s *oBuf)
1070 symbol *sflds;
1071 initList *iloop = NULL;
1072 unsigned int skip_holes = 0;
1074 sflds = SPEC_STRUCT (type)->fields;
1076 if (ilist)
1078 if (ilist->type != INIT_DEEP)
1080 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
1081 return;
1084 iloop = ilist->init.deep;
1087 if (SPEC_STRUCT (type)->type == UNION)
1089 int size;
1090 /* skip past holes, print value */
1091 while (iloop && iloop->type == INIT_HOLE)
1093 iloop = iloop->next;
1094 sflds = sflds->next;
1096 printIval (sym, sflds->type, iloop, oBuf, 1);
1097 /* pad out with zeros if necessary */
1098 size = getSize(type) - getSize(sflds->type);
1099 for ( ; size > 0 ; size-- )
1101 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
1103 /* advance past holes to find out if there were excess initializers */
1106 iloop = iloop ? iloop->next : NULL;
1107 sflds = sflds->next;
1109 while (iloop && iloop->type == INIT_HOLE);
1111 else
1113 // Hack to avoid the hack below (the one that fixed bug #2643) breaking zero-length bit-fields as first member of a struct (bug #3542).
1114 if(IS_BITFIELD (sflds->type) && !SPEC_BLEN (sflds->etype))
1115 sflds = sflds->next;
1117 while (sflds)
1119 unsigned int oldoffset = sflds->offset;
1121 if (IS_BITFIELD (sflds->type))
1122 printIvalBitFields (&sflds, &iloop, oBuf);
1123 else
1125 printIval (sym, sflds->type, iloop, oBuf, 1);
1126 sflds = sflds->next;
1127 iloop = iloop ? iloop->next : NULL;
1130 // Handle members from anonymous unions. Just a hack to fix bug #2643.
1131 while (sflds && sflds->offset == oldoffset)
1133 sflds = sflds->next;
1134 skip_holes++;
1138 while (skip_holes && iloop && iloop->type == INIT_HOLE)
1140 skip_holes--;
1141 iloop = iloop ? iloop->next : NULL;
1145 if (iloop)
1146 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
1149 /*-----------------------------------------------------------------*/
1150 /* printIvalChar - generates initital value for character array */
1151 /*-----------------------------------------------------------------*/
1153 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, const char *s, bool check)
1155 value *val;
1156 size_t size = DCL_ELEM(type);
1157 char *p;
1158 size_t asz;
1160 if (!s)
1162 val = list2val (ilist, TRUE);
1163 /* if the value is a character string */
1164 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
1166 if (!size)
1168 /* we have not been given a size, but now we know it */
1169 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
1170 /* but first check, if it's a flexible array */
1171 if (sym && IS_STRUCT (sym->type))
1172 sym->flexArrayLength = size;
1173 else
1174 DCL_ELEM (type) = size;
1177 if (check && DCL_ELEM (val->type) > size)
1178 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
1180 if (size > (asz = DCL_ELEM (val->type)) && !!(p = malloc (size)))
1182 memcpy (p, SPEC_CVAL (val->etype).v_char, asz);
1183 memset (p + asz, 0x00, size - asz);
1184 printChar (oBuf, p, size);
1185 free (p);
1187 else
1188 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
1190 return 1;
1192 else
1193 return 0;
1195 else
1196 printChar (oBuf, s, strlen (s) + 1);
1197 return 1;
1200 static size_t strLen16(const TYPE_TARGET_UINT *s)
1202 size_t l = 0;
1203 while(*s++)
1204 l++;
1206 return l;
1209 /*-----------------------------------------------------------------*/
1210 /* printIvalChar16 - generates initital value for character array */
1211 /*-----------------------------------------------------------------*/
1213 printIvalChar16 (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, const TYPE_TARGET_UINT *s, bool check)
1215 value *val;
1216 size_t size = DCL_ELEM(type);
1217 TYPE_TARGET_UINT *p;
1218 size_t asz;
1220 if (!s)
1222 val = list2val (ilist, TRUE);
1223 /* if the value is a character string */
1224 if (IS_ARRAY (val->type) && IS_INT (val->etype) && IS_UNSIGNED (val->etype) && !IS_LONG (val->etype))
1226 if (!size)
1228 /* we have not been given a size, but now we know it */
1229 size = strLen16 (SPEC_CVAL (val->etype).v_char16) + 1;
1230 /* but first check, if it's a flexible array */
1231 if (sym && IS_STRUCT (sym->type))
1232 sym->flexArrayLength = size;
1233 else
1234 DCL_ELEM (type) = size;
1237 if (check && DCL_ELEM (val->type) > size)
1238 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
1240 if (size > (asz = DCL_ELEM (val->type)) && !!(p = malloc (size * 2)))
1242 memcpy (p, SPEC_CVAL (val->etype).v_char16, asz * 2);
1243 memset (p + asz, 0x00, size * 2 - asz * 2);
1244 printChar16 (oBuf, p, size);
1245 free (p);
1247 else
1248 printChar16 (oBuf, SPEC_CVAL (val->etype).v_char16, size);
1250 return 1;
1252 else
1253 return 0;
1255 else
1256 printChar16 (oBuf, s, strLen16 (s) + 1);
1257 return 1;
1260 static size_t strLen32(const TYPE_TARGET_ULONG *s)
1262 size_t l = 0;
1263 while(*s++)
1264 l++;
1265 return l;
1268 /*-----------------------------------------------------------------*/
1269 /* printIvalChar32 - generates initital value for character array */
1270 /*-----------------------------------------------------------------*/
1272 printIvalChar32 (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, const TYPE_TARGET_ULONG *s, bool check)
1274 value *val;
1275 size_t size = DCL_ELEM(type);
1276 TYPE_TARGET_ULONG *p;
1277 size_t asz;
1279 if (!s)
1281 val = list2val (ilist, TRUE);
1282 /* if the value is a character string */
1283 if (IS_ARRAY (val->type) && IS_INT (val->etype) && IS_UNSIGNED (val->etype) && IS_LONG (val->etype))
1285 if (!size)
1287 /* we have not been given a size, but now we know it */
1288 size = strLen32 (SPEC_CVAL (val->etype).v_char32) + 1;
1289 /* but first check, if it's a flexible array */
1290 if (sym && IS_STRUCT (sym->type))
1291 sym->flexArrayLength = size;
1292 else
1293 DCL_ELEM (type) = size;
1296 if (check && DCL_ELEM (val->type) > size)
1297 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
1299 if (size > (asz = DCL_ELEM (val->type)) && !!(p = malloc (size * 4)))
1301 memcpy (p, SPEC_CVAL (val->etype).v_char32, asz * 4);
1302 memset (p + asz, 0x00, size * 4 - asz * 4);
1303 printChar32 (oBuf, p, size);
1304 free (p);
1306 else
1307 printChar32 (oBuf, SPEC_CVAL (val->etype).v_char32, size);
1309 return 1;
1311 else
1312 return 0;
1314 else
1315 printChar32 (oBuf, s, strLen32 (s) + 1);
1316 return 1;
1319 /*-----------------------------------------------------------------*/
1320 /* printIvalArray - generates code for array initialization */
1321 /*-----------------------------------------------------------------*/
1322 void
1323 printIvalArray (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, bool check)
1325 value *val;
1326 initList *iloop;
1327 unsigned int size = 0;
1329 if (ilist)
1331 /* take care of the special case */
1332 /* array of characters can be init */
1333 /* by a string */
1334 /* char *p = "abc"; */
1335 if ((IS_CHAR (type->next) || IS_INT (type->next)) && ilist->type == INIT_NODE)
1337 val = list2val (ilist, TRUE);
1338 if (!val)
1340 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
1341 return;
1343 if (!IS_LITERAL (val->etype))
1345 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
1346 return;
1348 if (IS_CHAR (type->next) && printIvalChar (sym, type, ilist, oBuf, SPEC_CVAL (sym->etype).v_char, check))
1349 return;
1350 if (IS_INT (type->next) && IS_UNSIGNED (type->next))
1352 if (!IS_LONG (type->next) && printIvalChar16 (sym, type, ilist, oBuf, SPEC_CVAL (sym->etype).v_char16, check))
1353 return;
1354 if (IS_LONG (type->next) && printIvalChar32 (sym, type, ilist, oBuf, SPEC_CVAL (sym->etype).v_char32, check))
1355 return;
1358 /* char *p = {"abc"}; */
1359 if ((IS_CHAR (type->next) || IS_INT (type->next)) && ilist->type == INIT_DEEP && ilist->init.deep && ilist->init.deep->type == INIT_NODE)
1361 val = list2val (ilist->init.deep, TRUE);
1362 if (!val)
1364 werrorfl (ilist->init.deep->filename, ilist->init.deep->lineno, E_INIT_STRUCT, sym->name);
1365 return;
1367 if (!IS_LITERAL (val->etype))
1369 werrorfl (ilist->init.deep->filename, ilist->init.deep->lineno, E_CONST_EXPECTED);
1370 return;
1372 if (IS_CHAR (type->next) && printIvalChar (sym, type, ilist->init.deep, oBuf, SPEC_CVAL (sym->etype).v_char, check))
1373 return;
1374 if (IS_INT (type->next) && IS_UNSIGNED (type->next))
1376 if (!IS_LONG (type->next) && printIvalChar16 (sym, type, ilist->init.deep, oBuf, SPEC_CVAL (sym->etype).v_char16, check))
1377 return;
1378 if (IS_LONG (type->next) && printIvalChar32 (sym, type, ilist->init.deep, oBuf, SPEC_CVAL (sym->etype).v_char32, check))
1379 return;
1383 /* not the special case */
1384 if (ilist->type != INIT_DEEP)
1386 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
1387 return;
1390 for (iloop = ilist->init.deep; iloop; iloop = iloop->next)
1392 if ((++size > DCL_ELEM (type)) && DCL_ELEM (type))
1394 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
1395 break;
1397 printIval (sym, type->next, iloop, oBuf, TRUE);
1401 if (DCL_ELEM (type))
1403 // pad with zeros if needed
1404 if (size < DCL_ELEM (type))
1406 size = (DCL_ELEM (type) - size) * getSize (type->next);
1407 while (size--)
1409 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
1413 else
1415 /* we have not been given a size, but now we know it */
1416 /* but first check, if it's a flexible array */
1417 if (IS_STRUCT (sym->type))
1418 sym->flexArrayLength = size * getSize (type->next);
1419 else
1420 DCL_ELEM (type) = size;
1423 return;
1426 /*-----------------------------------------------------------------*/
1427 /* printIvalFuncPtr - generate initial value for function pointers */
1428 /*-----------------------------------------------------------------*/
1429 void
1430 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s *oBuf)
1432 value *val;
1433 char *name;
1434 int size;
1436 if (ilist)
1437 val = list2val (ilist, TRUE);
1438 else
1439 val = valCastLiteral (type, 0.0, 0);
1441 if (!val)
1443 // an error has been thrown already
1444 val = constCharVal (0);
1447 if (IS_LITERAL (val->etype))
1449 if (compareType (type, val->type, false) == 0)
1451 if (ilist)
1452 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
1453 else
1454 werror (E_INCOMPAT_TYPES);
1455 printFromToType (val->type, type);
1457 printIvalCharPtr (NULL, type, val, oBuf);
1458 return;
1461 /* now generate the name */
1462 if (!val->sym)
1463 name = val->name;
1464 else
1465 name = val->sym->rname;
1467 size = getSize (type);
1469 if (size == FUNCPTRSIZE)
1471 if (TARGET_PDK_LIKE)
1473 dbuf_printf (oBuf, "\tret #<%s\n", name);
1474 dbuf_printf (oBuf, "\tret #>%s\n", name);
1476 else if (TARGET_IS_STM8 && FUNCPTRSIZE == 3)
1478 _printPointerType (oBuf, name, size);
1479 dbuf_printf (oBuf, "\n");
1481 else if (port->use_dw_for_init)
1483 dbuf_tprintf (oBuf, "\t!dws\n", name);
1485 else
1487 printPointerType (oBuf, name);
1490 else if (size == BFUNCPTRSIZE)
1492 _printPointerType (oBuf, name, size);
1493 dbuf_printf (oBuf, "\n");
1495 else
1497 wassertl (0, "Invalid function pointer size.");
1500 return;
1503 /*--------------------------------------------------------------------*/
1504 /* printIvalCharPtr - generates initial values for character pointers */
1505 /*--------------------------------------------------------------------*/
1507 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s *oBuf)
1509 int size = 0;
1510 char *p;
1512 if (val && !!(p = (char *) malloc (strlen (val->name) + 1)))
1514 strcpy (p, val->name);
1515 addSet (&ccpStr, p);
1518 /* PENDING: this is _very_ mcs51 specific, including a magic
1519 number...
1520 It's also endian specific.
1522 size = getSize (type);
1524 if (val->name && strlen (val->name))
1526 if (size == 1) /* This appears to be Z80 specific?? */
1528 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1530 else if (size == FARPTRSIZE)
1532 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
1534 dbuf_printf (oBuf, "\tret #<%s\n", val->name);
1535 dbuf_printf (oBuf, IN_CODESPACE (SPEC_OCLS (val->etype)) ? "\tret #>(%s + 0x8000)\n" : "\tret #0\n", val->name);
1537 else if (port->use_dw_for_init)
1538 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1539 else
1540 printPointerType (oBuf, val->name);
1542 else if (size == GPTRSIZE)
1544 int type;
1545 if (IS_PTR (val->type))
1547 type = DCL_TYPE (val->type);
1549 else
1551 type = PTR_TYPE (SPEC_OCLS (val->etype));
1553 if (val->sym && val->sym->isstrlit)
1555 // this is a literal string
1556 type = CPOINTER;
1558 printGPointerType (oBuf, val->name, sym->name, type);
1560 else
1562 fprintf (stderr, "*** internal error: unknown size in " "printIvalCharPtr.\n");
1565 else
1567 // these are literals assigned to pointers
1568 switch (size)
1570 case 1:
1571 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
1572 break;
1573 case 2:
1574 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
1576 dbuf_tprintf (oBuf, "\tret %s\n", aopLiteral (val, 0));
1577 dbuf_tprintf (oBuf, "\tret %s\n", aopLiteral (val, 1));
1579 else if (port->use_dw_for_init)
1580 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
1581 else if (port->little_endian)
1582 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1583 else
1584 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1585 break;
1586 case 3:
1587 if (IS_GENPTR (type) && GPTRSIZE > FARPTRSIZE && floatFromVal (val) != 0)
1589 if (!IS_PTR (val->type) && !IS_FUNC (val->type))
1591 // non-zero mcs51 generic pointer
1592 werrorfl (sym->fileDef, sym->lineDef, W_LITERAL_GENERIC);
1594 if (port->little_endian)
1595 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteralGptr (sym->name, val));
1596 else
1597 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteralGptr (sym->name, val), aopLiteral (val, 1), aopLiteral (val, 0));
1599 else
1601 if (port->little_endian)
1602 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2));
1603 else
1604 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteral (val, 2), aopLiteral (val, 1), aopLiteral (val, 0));
1606 break;
1607 case 4:
1608 if (IS_GENPTR (type) && GPTRSIZE > FARPTRSIZE && floatFromVal (val) != 0)
1610 if (!IS_PTR (val->type) && !IS_FUNC (val->type))
1612 // non-zero ds390 generic pointer
1613 werrorfl (sym->fileDef, sym->lineDef, W_LITERAL_GENERIC);
1615 if (port->little_endian)
1617 dbuf_printf (oBuf, "\t.byte %s,%s,%s", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2));
1618 if (IS_PTR (val->type) && !IS_GENPTR (val->type))
1619 dbuf_tprintf (oBuf, ",!immedbyte\n", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, sym->name));
1620 else
1621 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 3));
1623 else
1625 if (IS_PTR (val->type) && !IS_GENPTR (val->type))
1626 dbuf_tprintf (oBuf, "\t.byte !immedbyte\n", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, sym->name));
1627 else
1628 dbuf_printf (oBuf, "\t.byte %s\n", aopLiteral (val, 3));
1629 dbuf_printf (oBuf, ",%s,%s,%s", aopLiteral (val, 2), aopLiteral (val, 1), aopLiteral (val, 0));
1632 else
1634 if (port->little_endian)
1636 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1637 aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2), aopLiteral (val, 3));
1639 else
1641 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1642 aopLiteral (val, 3), aopLiteral (val, 2), aopLiteral (val, 1), aopLiteral (val, 0));
1645 break;
1646 default:
1647 assert (0);
1651 if (!noInit && val->sym && val->sym->isstrlit && !isinSet (statsg->syms, val->sym))
1653 addSet (&statsg->syms, val->sym);
1656 return 1;
1659 /*-----------------------------------------------------------------*/
1660 /* printIvalPtr - generates initial value for pointers */
1661 /*-----------------------------------------------------------------*/
1662 void
1663 printIvalPtr (symbol *sym, sym_link *type, initList *ilist, struct dbuf_s *oBuf)
1665 value *val;
1666 int size;
1668 /* if deep then */
1669 if (ilist && (ilist->type == INIT_DEEP))
1670 ilist = ilist->init.deep;
1672 /* function pointer */
1673 if (IS_FUNC (type->next))
1675 printIvalFuncPtr (type, ilist, oBuf);
1676 return;
1679 if (!(val = initPointer (ilist, type, 1)))
1680 return;
1682 /* if character pointer */
1683 if (IS_CHAR (type->next) || IS_INT (type->next) && IS_UNSIGNED (type->next))
1684 if (printIvalCharPtr (sym, type, val, oBuf))
1685 return;
1687 /* check the type */
1688 if (compareType (type, val->type, false) == 0)
1690 assert (ilist != NULL);
1691 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1692 printFromToType (val->type, type);
1695 const bool use_ret = TARGET_PDK_LIKE && !TARGET_IS_PDK16;
1697 /* if val is literal */
1698 if (IS_LITERAL (val->etype))
1700 switch (getSize (type))
1702 case 1:
1703 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1704 break;
1705 case 2:
1706 if (port->use_dw_for_init)
1707 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1708 else if (port->little_endian)
1710 if (use_ret)
1711 dbuf_tprintf (oBuf, "\tret %s\n\tret %s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1712 else
1713 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1715 else
1716 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1717 break;
1718 case 3:
1719 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1720 if (port->little_endian)
1721 dbuf_printf (oBuf, "\t.byte %s,%s", aopLiteral (val, 0), aopLiteral (val, 1));
1722 else
1723 dbuf_printf (oBuf, "\t.byte %s,%s", aopLiteral (val, 1), aopLiteral (val, 0));
1724 if (IS_GENPTR (val->type))
1725 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1726 else if (IS_PTR (val->type))
1727 dbuf_tprintf (oBuf, ",!immedbyte\n", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, sym->name));
1728 else
1729 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1730 break;
1731 case 4:
1732 if (TARGET_IS_DS390 || TARGET_IS_DS400)
1733 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2), aopLiteral (val, 3));
1734 else
1735 wassertl(0, "Printing pointer of invalid size");
1736 break;
1737 default:
1738 wassertl(0, "Printing pointer of invalid size");
1739 break;
1741 return;
1744 size = getSize (type);
1746 if (use_ret && size == 2)
1748 if (IN_CODESPACE (SPEC_OCLS (val->etype)))
1750 dbuf_printf (oBuf, "\tret #<%s\n", val->name);
1751 dbuf_printf (oBuf, "\tret #>(%s + 0x8000)\n", val->name);
1753 else
1755 dbuf_printf (oBuf, "\tret #%s\n", val->name);
1756 dbuf_printf (oBuf, "\tret #0\n");
1759 else if (size == 1) /* Z80 specific?? */
1761 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1763 else if (size == FARPTRSIZE)
1765 if (port->use_dw_for_init)
1766 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1767 else
1768 printPointerType (oBuf, val->name);
1770 else if (size == GPTRSIZE)
1772 printGPointerType (oBuf, val->name, sym->name,
1773 (IS_PTR (val->type) ? DCL_TYPE (val->type) : PTR_TYPE (SPEC_OCLS (val->etype))));
1776 return;
1779 /*-----------------------------------------------------------------*/
1780 /* printIval - generates code for initial value */
1781 /*-----------------------------------------------------------------*/
1782 void
1783 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, bool check)
1785 sym_link *itype;
1787 /* Handle designated initializers */
1788 if (ilist && ilist->type==INIT_DEEP)
1789 ilist = reorderIlist (type, ilist);
1791 /* If this is a hole, substitute an appropriate initializer. */
1792 if (ilist && ilist->type == INIT_HOLE)
1794 if (IS_AGGREGATE (type))
1796 ilist = newiList(INIT_DEEP, NULL); /* init w/ {} */
1798 else
1800 ast *ast = newAst_VALUE (constVal("0"));
1801 ast = decorateType (ast, RESULT_TYPE_NONE, true);
1802 ilist = newiList(INIT_NODE, ast);
1806 /* if structure then */
1807 if (IS_STRUCT (type))
1809 printIvalStruct (sym, type, ilist, oBuf);
1810 return;
1813 /* if this is an array */
1814 if (IS_ARRAY (type))
1816 printIvalArray (sym, type, ilist, oBuf, check);
1817 return;
1820 if (ilist)
1822 // not an aggregate, ilist must be a node
1823 if (ilist->type != INIT_NODE)
1825 // or a 1-element list
1826 if (ilist->init.deep->next)
1828 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
1830 else
1832 ilist = ilist->init.deep;
1836 // Give up here, to avoid reading invalid memory below.
1837 if (ilist->init.node->isError)
1838 goto ilist_done;
1840 // and the type must match
1841 itype = ilist->init.node->ftype;
1843 if (compareType (type, itype, false) == 0)
1845 // special case for literal strings
1846 if (IS_ARRAY (itype) && IS_CHAR (getSpec (itype)) &&
1847 // which are really code pointers
1848 IS_CODEPTR (type))
1850 // no sweat
1852 else if (IS_CODEPTR (type) && IS_FUNC (type->next)) /* function pointer */
1854 if (ilist)
1855 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
1856 else
1857 werror (E_INCOMPAT_TYPES);
1858 printFromToType (itype, type->next);
1860 else
1862 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1863 printFromToType (itype, type);
1867 ilist_done:
1869 /* if this is a pointer */
1870 if (IS_PTR (type))
1872 printIvalPtr (sym, type, ilist, oBuf);
1873 return;
1876 /* if type is SPECIFIER */
1877 if (IS_SPEC (type))
1879 printIvalType (sym, type, ilist, oBuf);
1880 return;
1884 /*-----------------------------------------------------------------*/
1885 /* emitStaticSeg - emitcode for the static segment */
1886 /*-----------------------------------------------------------------*/
1887 void
1888 emitStaticSeg (memmap *map, struct dbuf_s *oBuf)
1890 symbol *sym;
1891 set *tmpSet = NULL;
1893 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1894 //printf("emitStaticSeg %s\n", map->sname);
1895 /* eliminate redundant __str_%d (generated in stringToSymbol(), SDCCast.c) */
1896 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
1897 addSet (&tmpSet, sym);
1899 /* for all variables in this segment do */
1900 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
1901 {//printf("emit symbol %s\n", sym->name);
1902 /* if it is "extern" then do nothing */
1903 if (IS_EXTERN (sym->etype) && !sym->ival)
1904 continue;
1906 /* eliminate redundant __str_%d (generated in stringToSymbol(), SDCCast.c) */
1907 if (!isinSet (tmpSet, sym))
1909 const char *p;
1910 if (!ccpStr)
1911 continue;
1912 for (p = setFirstItem (ccpStr); p; p = setNextItem (ccpStr))
1913 if (strcmp (p, sym->name) == 0)
1914 break;
1915 if (!p)
1916 continue;
1919 /* if it is not static add it to the public table */
1920 if (!IS_STATIC (sym->etype))
1922 addSetHead (&publics, sym);
1925 /* if it has an absolute address and no initializer */
1926 if (SPEC_ABSA (sym->etype) && !sym->ival)
1928 if (options.debug)
1930 emitDebugSym (oBuf, sym);
1931 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1933 dbuf_printf (oBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype));
1935 else
1937 int size = getSize (sym->type);
1939 if (size == 0)
1941 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
1943 /* if it has an initial value */
1944 if (sym->ival)
1945 {//printf("ival.\n");
1946 if (SPEC_ABSA (sym->etype))
1948 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1950 else if (options.const_seg && map != xinit && map != initializer)
1951 dbuf_tprintf(&code->oBuf, "\t!area\n", options.const_seg);
1952 if (options.debug)
1954 emitDebugSym (oBuf, sym);
1955 dbuf_printf (oBuf, " == .\n");
1957 dbuf_printf (oBuf, "%s:\n", sym->rname);
1958 ++noAlloc;
1959 resolveIvalSym (sym->ival, sym->type);
1960 printIval (sym, sym->type, sym->ival, oBuf, (map != xinit && map != initializer));
1961 --noAlloc;
1962 /* if sym is a simple string and sym->ival is a string,
1963 WE don't need it anymore */
1964 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1965 IS_AST_SYM_VALUE (list2expr (sym->ival)) && list2val (sym->ival, TRUE)->sym->isstrlit)
1967 freeStringSymbol (list2val (sym->ival, TRUE)->sym);
1969 if (!SPEC_ABSA (sym->etype) && options.const_seg && map != xinit && map != initializer)
1970 dbuf_tprintf(oBuf, "\t!areacode\n", options.code_seg);
1972 else
1973 {//printf("no ival.\n");
1974 /* allocate space */
1975 if (options.debug)
1977 emitDebugSym (oBuf, sym);
1978 dbuf_printf (oBuf, " == .\n");
1980 /* special case for character strings */
1981 if (IS_ARRAY (sym->type) &&
1982 (IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char ||
1983 IS_INT (sym->type->next) && !IS_LONG (sym->type->next) && SPEC_CVAL (sym->etype).v_char16 ||
1984 IS_INT (sym->type->next) && IS_LONG (sym->type->next) && SPEC_CVAL (sym->etype).v_char32))
1986 if (options.const_seg)
1987 dbuf_tprintf(&code->oBuf, "\t!area\n", options.const_seg);
1988 dbuf_printf (oBuf, "%s:\n", sym->rname);
1989 if (IS_CHAR (sym->type->next))
1990 printChar (oBuf, SPEC_CVAL (sym->etype).v_char, size);
1991 else if (IS_INT (sym->type->next) && !IS_LONG (sym->type->next))
1992 printChar16 (oBuf, SPEC_CVAL (sym->etype).v_char16, size / 2);
1993 else if (IS_INT (sym->type->next) && IS_LONG (sym->type->next))
1994 printChar32 (oBuf, SPEC_CVAL (sym->etype).v_char32, size / 4);
1995 else
1996 wassert (0);
1997 if (options.const_seg)
1998 dbuf_tprintf(oBuf, "\t!areacode\n", options.code_seg);
2000 else
2002 dbuf_printf (oBuf, "%s:\n", sym->rname);
2003 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
2009 if (tmpSet)
2010 deleteSet (&tmpSet);
2011 if (ccpStr)
2013 char *p;
2014 for (p = setFirstItem (ccpStr); p; p = setNextItem (ccpStr))
2015 if (p)
2016 free (p);
2017 deleteSet (&ccpStr);
2021 /*-----------------------------------------------------------------*/
2022 /* emitMaps - emits the code for the data portion the code */
2023 /*-----------------------------------------------------------------*/
2024 void
2025 emitMaps (void)
2027 namedspacemap *nm;
2028 int publicsfr = TARGET_IS_MCS51 || TARGET_PDK_LIKE; /* Ideally, this should be true for all */
2029 /* ports but let's be conservative - EEP */
2031 inInitMode++;
2032 /* no special considerations for the following
2033 data, idata & bit & xdata */
2034 emitRegularMap (data, TRUE, TRUE);
2035 emitRegularMap (initialized, TRUE, TRUE);
2036 for (nm = namedspacemaps; nm; nm = nm->next)
2037 if (nm->is_const)
2039 dbuf_tprintf (&nm->map->oBuf, "\t!areacode\n", nm->map->sname);
2040 emitStaticSeg (nm->map, &nm->map->oBuf);
2042 else
2043 emitRegularMap (nm->map, TRUE, TRUE);
2044 emitRegularMap (idata, TRUE, TRUE);
2045 emitRegularMap (d_abs, TRUE, TRUE);
2046 emitRegularMap (i_abs, TRUE, TRUE);
2047 emitRegularMap (bit, TRUE, TRUE);
2048 emitRegularMap (pdata, TRUE, TRUE);
2049 emitRegularMap (xdata, TRUE, TRUE);
2050 emitRegularMap (x_abs, TRUE, TRUE);
2051 if (port->genXINIT)
2053 emitRegularMap (xidata, TRUE, TRUE);
2055 emitRegularMap (sfr, publicsfr, FALSE);
2056 emitRegularMap (sfrbit, publicsfr, FALSE);
2057 emitRegularMap (home, TRUE, FALSE);
2058 emitRegularMap (code, TRUE, FALSE);
2060 if (options.const_seg)
2061 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
2062 emitStaticSeg (statsg, &code->oBuf);
2064 if (port->genXINIT)
2066 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
2067 emitStaticSeg (xinit, &code->oBuf);
2069 if (initializer)
2071 dbuf_tprintf (&code->oBuf, "\t!area\n", initializer->sname);
2072 emitStaticSeg (initializer, &code->oBuf);
2074 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
2075 emitStaticSeg (c_abs, &code->oBuf);
2076 inInitMode--;
2079 /*-----------------------------------------------------------------*/
2080 /* flushStatics - flush all currently defined statics out to file */
2081 /* and delete. Temporary function */
2082 /*-----------------------------------------------------------------*/
2083 void
2084 flushStatics (void)
2086 if (!setFirstItem (statsg->syms))
2087 return;
2089 if (options.const_seg)
2090 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
2092 emitStaticSeg (statsg, codeOutBuf);
2093 statsg->syms = 0;
2095 if (options.const_seg)
2096 dbuf_tprintf (&code->oBuf, "\t!area\n", options.code_seg);
2099 /*-----------------------------------------------------------------*/
2100 /* createInterruptVect - creates the interrupt vector */
2101 /*-----------------------------------------------------------------*/
2102 void
2103 createInterruptVect (struct dbuf_s *vBuf)
2105 mainf = newSymbol ("main", 0);
2106 mainf->block = 0;
2108 /* only if the main function exists */
2109 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
2111 if (!options.cc_only && !options.no_assemble && !options.c1mode)
2112 werror (E_NO_MAIN);
2113 return;
2116 /* if the main is only a prototype ie. no body then do nothing */
2117 if (!IFFUNC_HASBODY (mainf->type))
2119 /* if ! compile only then main function should be present */
2120 if (!options.cc_only && !options.no_assemble)
2121 werror (E_NO_MAIN);
2122 return;
2125 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
2126 dbuf_printf (vBuf, "__interrupt_vect:\n");
2129 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
2131 /* There's no such thing as a "generic" interrupt table header. */
2132 wassert (0);
2136 char *iComments1 = {
2137 ";--------------------------------------------------------\n"
2138 "; File Created by SDCC : free open source ISO C Compiler\n"
2141 char *iComments2 = {
2142 ";--------------------------------------------------------\n"
2146 /*-----------------------------------------------------------------*/
2147 /* initialComments - puts in some initial comments */
2148 /*-----------------------------------------------------------------*/
2149 void
2150 initialComments (FILE *afile)
2152 fprintf (afile, "%s", iComments1);
2153 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s)\n", getBuildNumber (), getBuildEnvironment ());
2154 fprintf (afile, "%s", iComments2);
2157 /*-----------------------------------------------------------------*/
2158 /* printPublics - generates .global for publics */
2159 /*-----------------------------------------------------------------*/
2160 void
2161 printPublics (FILE * afile)
2163 symbol *sym;
2165 fprintf (afile, "%s", iComments2);
2166 fprintf (afile, "; Public variables in this module\n");
2167 fprintf (afile, "%s", iComments2);
2169 for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
2171 if (TARGET_Z80_LIKE && IFFUNC_BANKED(sym->type))
2173 /* TODO: use template for bank symbol generation */
2174 sprintf (buffer, "b%s", sym->rname);
2175 tfprintf (afile, "\t!global\n", buffer);
2177 tfprintf (afile, "\t!global\n", sym->rname);
2181 /*-----------------------------------------------------------------*/
2182 /* printExterns - generates .global for externs */
2183 /*-----------------------------------------------------------------*/
2184 void
2185 printExterns (FILE * afile)
2187 symbol *sym;
2189 fprintf (afile, "%s", iComments2);
2190 fprintf (afile, "; Externals used\n");
2191 fprintf (afile, "%s", iComments2);
2193 for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
2194 tfprintf (afile, "\t!extern\n", sym->rname);
2197 /*-----------------------------------------------------------------*/
2198 /* emitOverlay - will emit code for the overlay stuff */
2199 /*-----------------------------------------------------------------*/
2200 static void
2201 emitOverlay (struct dbuf_s *aBuf)
2203 set *ovrset;
2205 /* for each of the sets in the overlay segment do */
2206 for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets))
2208 symbol *sym;
2210 if (elementsInSet (ovrset))
2212 /* output the area information */
2213 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
2216 for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset))
2218 /* if extern then it is in the publics table: do nothing */
2219 if (IS_EXTERN (sym->etype))
2220 continue;
2222 /* if allocation required check is needed
2223 then check if the symbol really requires
2224 allocation only for local variables */
2225 if (!IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level)
2226 continue;
2228 /* if global variable & not static or extern
2229 and addPublics allowed then add it to the public set */
2230 if ((sym->_isparm && !IS_REGPARM (sym->etype)) && !IS_STATIC (sym->etype) && !IS_STATIC (sym->localof->etype))
2232 addSetHead (&publics, sym);
2235 /* if extern then do nothing or is a function
2236 then do nothing */
2237 if (IS_FUNC (sym->type))
2238 continue;
2240 /* if is has an absolute address then generate
2241 an equate for this no need to allocate space */
2242 if (SPEC_ABSA (sym->etype))
2244 /* print extra debug info if required */
2245 if (options.debug)
2247 emitDebugSym (aBuf, sym);
2248 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
2250 dbuf_printf (aBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype));
2252 else
2254 int size = getSize (sym->type);
2256 if (size == 0)
2258 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
2260 /* print extra debug info if required */
2261 if (options.debug)
2263 emitDebugSym (aBuf, sym);
2264 dbuf_printf (aBuf, "==.\n");
2267 /* allocate space */
2268 dbuf_tprintf (aBuf, "!slabeldef\n", sym->rname);
2269 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
2275 /*-----------------------------------------------------------------*/
2276 /* glue - the final glue that hold the whole thing together */
2277 /*-----------------------------------------------------------------*/
2278 void
2279 glue (void)
2281 struct dbuf_s vBuf;
2282 struct dbuf_s ovrBuf;
2283 struct dbuf_s asmFileName;
2284 FILE *asmFile;
2285 int mcs51_like;
2286 namedspacemap *nm;
2288 dbuf_init (&vBuf, 4096);
2289 dbuf_init (&ovrBuf, 4096);
2291 mcs51_like = (port->general.glue_up_main &&
2292 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_DS400));
2294 /* print the global struct definitions */
2295 if (options.debug)
2296 cdbStructBlock (0);
2298 /* PENDING: this isn't the best place but it will do */
2299 if (port->general.glue_up_main)
2301 /* create the interrupt vector table */
2302 createInterruptVect (&vBuf);
2305 /* emit code for the all the variables declared */
2306 emitMaps ();
2307 /* do the overlay segments */
2308 emitOverlay (&ovrBuf);
2310 outputDebugSymbols ();
2312 /* now put it all together into the assembler file */
2313 /* create the assembler file name */
2315 /* -o option overrides default name? */
2316 dbuf_init (&asmFileName, PATH_MAX);
2317 if ((options.no_assemble || options.c1mode) && fullDstFileName)
2319 dbuf_append_str (&asmFileName, fullDstFileName);
2321 else
2323 dbuf_append_str (&asmFileName, dstFileName);
2324 dbuf_append_str (&asmFileName, port->assembler.file_ext);
2327 if (!(asmFile = fopen (dbuf_c_str (&asmFileName), "w")))
2329 werror (E_OUTPUT_FILE_OPEN_ERR, dbuf_c_str (&asmFileName), strerror (errno));
2330 dbuf_destroy (&asmFileName);
2331 exit (EXIT_FAILURE);
2333 dbuf_destroy (&asmFileName);
2335 /* initial comments */
2336 initialComments (asmFile);
2338 /* print module name */
2339 tfprintf (asmFile, "\t!module\n", moduleName);
2341 // TODO: Move this stuff from here to port-specific genAssemblerStart?
2342 if (TARGET_IS_S08)
2343 fprintf (asmFile, "\t.cs08\n");
2344 else if (TARGET_IS_Z180)
2345 fprintf (asmFile, "\t.hd64\n");
2346 else if (TARGET_IS_R3KA)
2347 fprintf (asmFile, "\t.r3k\n");
2348 else if (TARGET_IS_EZ80_Z80)
2349 fprintf (asmFile, "\t.ez80\n");
2350 else if (TARGET_IS_Z80N)
2351 fprintf (asmFile, "\t.zxn\n");
2352 else if (TARGET_IS_R800)
2353 fprintf (asmFile, "\t.r800\n");
2354 else if (TARGET_IS_Z80 && options.allow_undoc_inst)
2355 fprintf (asmFile, "\t.allow_undocumented\n");
2357 tfprintf (asmFile, "\t!fileprelude\n");
2359 /* Let the port generate any global directives, etc. */
2360 if (port->genAssemblerStart)
2362 port->genAssemblerStart (asmFile);
2365 /* print the global variables in this module */
2366 printPublics (asmFile);
2367 if (port->assembler.externGlobal)
2368 printExterns (asmFile);
2370 if ((mcs51_like) || (TARGET_Z80_LIKE && !TARGET_IS_TLCS90) || TARGET_PDK_LIKE) /*.p.t.20030924 need to output SFR table for Z80 as well */
2372 /* copy the sfr segment */
2373 fprintf (asmFile, "%s", iComments2);
2374 fprintf (asmFile, "; special function registers\n");
2375 fprintf (asmFile, "%s", iComments2);
2376 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
2379 if (mcs51_like)
2381 /* copy the sbit segment */
2382 fprintf (asmFile, "%s", iComments2);
2383 fprintf (asmFile, "; special function bits\n");
2384 fprintf (asmFile, "%s", iComments2);
2385 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
2387 /*JCF: Create the areas for the register banks */
2388 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
2390 fprintf (asmFile, "%s", iComments2);
2391 fprintf (asmFile, "; overlayable register banks\n");
2392 fprintf (asmFile, "%s", iComments2);
2393 if (RegBankUsed[0])
2394 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
2395 if (RegBankUsed[1] || options.parms_in_bank1)
2396 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
2397 if (RegBankUsed[2])
2398 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
2399 if (RegBankUsed[3])
2400 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
2402 if (BitBankUsed)
2404 fprintf (asmFile, "%s", iComments2);
2405 fprintf (asmFile, "; overlayable bit register bank\n");
2406 fprintf (asmFile, "%s", iComments2);
2407 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
2408 fprintf (asmFile, "bits:\n\t.ds 1\n");
2409 fprintf (asmFile, "\tb0 = bits[0]\n");
2410 fprintf (asmFile, "\tb1 = bits[1]\n");
2411 fprintf (asmFile, "\tb2 = bits[2]\n");
2412 fprintf (asmFile, "\tb3 = bits[3]\n");
2413 fprintf (asmFile, "\tb4 = bits[4]\n");
2414 fprintf (asmFile, "\tb5 = bits[5]\n");
2415 fprintf (asmFile, "\tb6 = bits[6]\n");
2416 fprintf (asmFile, "\tb7 = bits[7]\n");
2420 /* copy the data segment */
2421 fprintf (asmFile, "%s", iComments2);
2422 if(!TARGET_MOS6502_LIKE) fprintf (asmFile, ";%s ram data\n", mcs51_like ? " internal" : "");
2423 else fprintf (asmFile, "; ZP ram data\n");
2424 fprintf (asmFile, "%s", iComments2);
2425 dbuf_write_and_destroy (&data->oBuf, asmFile);
2427 /* copy the initialized segment */
2428 if (initialized)
2430 fprintf (asmFile, "%s", iComments2);
2431 fprintf (asmFile, ";%s ram data\n", mcs51_like ? " internal" : "");
2432 fprintf (asmFile, "%s", iComments2);
2433 dbuf_write_and_destroy (&initialized->oBuf, asmFile);
2436 /* copy segments for named address spaces */
2437 for (nm = namedspacemaps; nm; nm = nm->next)
2439 fprintf (asmFile, "%s", iComments2);
2440 fprintf (asmFile, "; %s %s data\n", nm->name, nm->is_const ? "rom" : "ram");
2441 fprintf (asmFile, "%s", iComments2);
2442 dbuf_write_and_destroy (&nm->map->oBuf, asmFile);
2445 /* create the overlay segments */
2446 if (overlay)
2448 fprintf (asmFile, "%s", iComments2);
2449 fprintf (asmFile, "; overlayable items in%s ram\n", mcs51_like ? " internal" : "");
2450 fprintf (asmFile, "%s", iComments2);
2451 dbuf_write_and_destroy (&ovrBuf, asmFile);
2454 /* create the stack segment MOF */
2455 if (mainf && IFFUNC_HASBODY (mainf->type))
2457 fprintf (asmFile, "%s", iComments2);
2458 fprintf (asmFile, "; Stack segment in internal ram\n");
2459 fprintf (asmFile, "%s", iComments2);
2460 tfprintf (asmFile, "\t!area\n" "__start__stack:\n\t.ds\t1\n\n", "SSEG");
2463 /* create the idata segment */
2464 if (idata)
2466 fprintf (asmFile, "%s", iComments2);
2467 fprintf (asmFile, "; indirectly addressable internal ram data\n");
2468 fprintf (asmFile, "%s", iComments2);
2469 dbuf_write_and_destroy (&idata->oBuf, asmFile);
2472 /* create the absolute idata/data segment */
2473 if (d_abs || i_abs)
2475 fprintf (asmFile, "%s", iComments2);
2476 fprintf (asmFile, "; absolute%s ram data\n", mcs51_like ? " internal" : "");
2477 fprintf (asmFile, "%s", iComments2);
2478 if (d_abs)
2479 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
2480 if (i_abs)
2481 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
2484 /* copy the bit segment */
2485 if (bit)
2487 fprintf (asmFile, "%s", iComments2);
2488 fprintf (asmFile, "; bit data\n");
2489 fprintf (asmFile, "%s", iComments2);
2490 dbuf_write_and_destroy (&bit->oBuf, asmFile);
2493 /* copy paged external ram data */
2494 if (pdata)
2496 fprintf (asmFile, "%s", iComments2);
2497 fprintf (asmFile, "; paged external ram data\n");
2498 fprintf (asmFile, "%s", iComments2);
2499 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
2502 /* if external stack then reserve space for it */
2503 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
2505 fprintf (asmFile, "%s", iComments2);
2506 fprintf (asmFile, "; external stack\n");
2507 fprintf (asmFile, "%s", iComments2);
2508 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n" "__start__xstack:\n\t.ds\t1\n\n");
2511 /* copy external ram data */
2512 if (xdata && (mcs51_like || TARGET_MOS6502_LIKE ))
2514 fprintf (asmFile, "%s", iComments2);
2515 fprintf (asmFile, "; uninitialized external ram data\n");
2516 fprintf (asmFile, "%s", iComments2);
2517 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
2520 /* create the absolute xdata segment */
2521 if (x_abs)
2523 fprintf (asmFile, "%s", iComments2);
2524 fprintf (asmFile, "; absolute external ram data\n");
2525 fprintf (asmFile, "%s", iComments2);
2526 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
2529 /* copy external initialized ram data */
2530 if (xidata)
2532 fprintf (asmFile, "%s", iComments2);
2533 fprintf (asmFile, "; initialized external ram data\n");
2534 fprintf (asmFile, "%s", iComments2);
2535 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
2538 /* If the port wants to generate any extra areas, let it do so. */
2539 if (port->extraAreas.genExtraAreaDeclaration)
2541 port->extraAreas.genExtraAreaDeclaration (asmFile, mainf && IFFUNC_HASBODY (mainf->type));
2544 /* copy the interrupt vector table */
2545 if (mainf && IFFUNC_HASBODY (mainf->type))
2547 fprintf (asmFile, "%s", iComments2);
2548 fprintf (asmFile, "; interrupt vector\n");
2549 fprintf (asmFile, "%s", iComments2);
2550 dbuf_write_and_destroy (&vBuf, asmFile);
2553 /* copy global & static initialisations */
2554 fprintf (asmFile, "%s", iComments2);
2555 fprintf (asmFile, "; global & static initialisations\n");
2556 fprintf (asmFile, "%s", iComments2);
2558 /* Everywhere we generate a reference to the static_name area,
2559 * (which is currently only here), we immediately follow it with a
2560 * definition of the post_static_name area. This guarantees that
2561 * the post_static_name area will immediately follow the static_name
2562 * area.
2564 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
2565 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
2566 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
2567 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
2569 if (mainf && IFFUNC_HASBODY (mainf->type))
2571 if (port->genInitStartup)
2573 port->genInitStartup (asmFile);
2575 else
2577 assert (0);
2580 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
2582 /* STM8 / PDK14 note: there are no such instructions supported.
2583 Also, we don't need this logic as well. */
2584 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
2586 /* This code is generated in the post-static area.
2587 * This area is guaranteed to follow the static area
2588 * by the ugly shucking and jiving about 20 lines ago.
2590 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
2591 if(TARGET_IS_STM8)
2592 fprintf (asmFile, options.model == MODEL_LARGE ? "\tjpf\t__sdcc_program_startup\n" : "\tjp\t__sdcc_program_startup\n");
2593 else if (TARGET_IS_F8)
2594 fprintf (asmFile, "\tjp\t#__sdcc_program_startup\n");
2595 else if(TARGET_PDK_LIKE)
2596 fprintf (asmFile, "\tgoto\t__sdcc_program_startup\n");
2597 else
2598 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp ? 'a' : 'l');
2601 fprintf (asmFile, "%s" "; Home\n" "%s", iComments2, iComments2);
2602 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
2603 dbuf_write_and_destroy (&home->oBuf, asmFile);
2605 if (mainf && IFFUNC_HASBODY (mainf->type))
2607 /* STM8 note: there is no need to call main().
2608 Instead of that, it's address is specified in the
2609 interrupts table and always equals to 0x8080.
2612 /* entry point @ start of HOME */
2613 fprintf (asmFile, "__sdcc_program_startup:\n");
2615 /* put in jump or call to main */
2616 if(TARGET_IS_STM8)
2617 fprintf (asmFile, options.model == MODEL_LARGE ? "\tjpf\t_main\n" : "\tjp\t_main\n");
2618 else if(TARGET_IS_F8)
2619 fprintf (asmFile, "\tjp\t#_main\n");
2620 else if(TARGET_PDK_LIKE)
2621 fprintf (asmFile, "\tgoto\t_main\n");
2622 else
2623 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp ? 'a' : 'l'); /* needed? */
2624 fprintf (asmFile, ";\treturn from main will return to caller\n");
2626 /* copy over code */
2627 fprintf (asmFile, "%s", iComments2);
2628 fprintf (asmFile, "; code\n");
2629 fprintf (asmFile, "%s", iComments2);
2630 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
2631 dbuf_write_and_destroy (&code->oBuf, asmFile);
2633 if (port->genAssemblerEnd)
2635 port->genAssemblerEnd (asmFile);
2637 fclose (asmFile);
2640 /* will return 1 if the string is a part
2641 of a target specific keyword */
2643 isTargetKeyword (const char *s)
2645 int i;
2647 if (port->keywords == NULL)
2648 return 0;
2650 if (s[0] == '_' && s[1] == '_')
2652 /* Keywords in the port's array have either 0 or 1 underscore, */
2653 /* so skip over the appropriate number of chars when comparing */
2654 for (i = 0 ; port->keywords[i] ; i++ )
2656 if (port->keywords[i][0] == '_' &&
2657 strcmp(port->keywords[i],s+1) == 0)
2658 return 1;
2659 else if (strcmp(port->keywords[i],s+2) == 0)
2660 return 1;
2663 else
2665 for (i = 0 ; port->keywords[i] ; i++ )
2667 if (strcmp(port->keywords[i],s) == 0)
2668 return 1;
2672 return 0;