1 /*-------------------------------------------------------------------------
2 SDCCglue.c - glues everything we have done together into one file.
3
4 Copyright (C) 1998 Sandeep Dutta . sandeep.dutta@usa.net
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
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"
27
28 #ifdef _WIN32
29 #include <io.h>
30 #else
31 #include <unistd.h>
32 #endif
33
34 symbol *interrupts[INTNO_MAX + 1];
35
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 */
41
42 unsigned maxInterrupts = 0;
43 int allocInfo = 1;
44 symbol *mainf;
45 int noInit = 0; /* no initialization */
46
47
48 char *
aopLiteralGptr(const char * name,value * val)49 aopLiteralGptr (const char * name, value * val)
50 {
51 unsigned long v = ulFromVal (val);
52 struct dbuf_s dbuf;
53
54 dbuf_init (&dbuf, 128);
55
56 v >>= ((GPTRSIZE - 1) * 8);
57
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);
64
65 return dbuf_detach_c_str (&dbuf);
66 }
67
68 const char *
aopLiteralLong(value * val,int offset,int size)69 aopLiteralLong (value *val, int offset, int size)
70 {
71 unsigned long v;
72 struct dbuf_s dbuf;
73
74 if (!val)
75 {
76 // assuming we have been warned before
77 val = constCharVal (0);
78 }
79
80 dbuf_init (&dbuf, 128);
81
82 switch (size)
83 {
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);
103 }
104 return dbuf_detach_c_str (&dbuf);
105 }
106
107 /*-----------------------------------------------------------------*/
108 /* aopLiteral - string from a literal value */
109 /*-----------------------------------------------------------------*/
110 const char *
aopLiteral(value * val,int offset)111 aopLiteral (value *val, int offset)
112 {
113 return aopLiteralLong (val, offset, 1);
114 }
115
116 /*-----------------------------------------------------------------*/
117 /* emitDebugSym - emit label for debug symbol */
118 /*-----------------------------------------------------------------*/
119 static void
emitDebugSym(struct dbuf_s * oBuf,symbol * sym)120 emitDebugSym (struct dbuf_s *oBuf, symbol * sym)
121 {
122 if (sym->level && sym->localof) /* symbol scope is local */
123 {
124 dbuf_printf (oBuf, "L%s.%s$", moduleName, sym->localof->name);
125 }
126 else if (IS_STATIC (sym->etype)) /* symbol scope is file */
127 {
128 dbuf_printf (oBuf, "F%s$", moduleName);
129 }
130 else /* symbol scope is global */
131 {
132 dbuf_printf (oBuf, "G$");
133 }
134 dbuf_printf (oBuf, "%s$%ld_%ld$%d", sym->name, sym->level / LEVEL_UNIT, sym->level % LEVEL_UNIT, sym->block);
135 }
136
137 /*-----------------------------------------------------------------*/
138 /* emitRegularMap - emit code for maps with no special cases */
139 /*-----------------------------------------------------------------*/
140 static void
emitRegularMap(memmap * map,bool addPublics,bool arFlag)141 emitRegularMap (memmap *map, bool addPublics, bool arFlag)
142 {
143 symbol *sym;
144 ast *ival = NULL;
145
146 if (!map)
147 return;
148
149 if (addPublics)
150 {
151 /* PENDING: special case here - should remove */
152 if (!strcmp (map->sname, CODE_NAME))
153 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
154 else if (!strcmp (map->sname, DATA_NAME))
155 {
156 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
157 if (options.data_seg && strcmp (DATA_NAME, options.data_seg))
158 dbuf_tprintf (&map->oBuf, "\t!area\n", options.data_seg);
159 }
160 else if (!strcmp (map->sname, HOME_NAME))
161 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
162 else
163 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
164
165 if (map->regsp)
166 dbuf_tprintf (&map->oBuf, "\t!org\n", 0);
167 }
168
169 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
170 {
171 symbol *newSym = NULL;
172
173 /* if allocation required check is needed
174 then check if the symbol really requires
175 allocation only for local variables */
176
177 if (arFlag && !IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level)
178 continue;
179
180 /* for bitvar locals and parameters */
181 if (!arFlag && !sym->allocreq && sym->level && !SPEC_ABSA (sym->etype))
182 {
183 continue;
184 }
185
186 /* if global variable & not static or extern
187 and addPublics allowed then add it to the public set */
188 if ((sym->level == 0 ||
189 (sym->_isparm && !IS_REGPARM (sym->etype) && !IS_STATIC (sym->localof->etype))) &&
190 addPublics &&
191 !IS_STATIC (sym->etype) &&
192 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : (!IS_EXTERN (sym->etype) || sym->ival)) &&
193 !(IFFUNC_ISINLINE (sym->type) && !IS_STATIC (sym->etype) && !IS_EXTERN (sym->etype)))
194 {
195 addSetHead (&publics, sym);
196 }
197
198 /* if extern then add it into the extern list */
199 if (IS_EXTERN (sym->etype) && !sym->ival)
200 {
201 addSetHead (&externs, sym);
202 continue;
203 }
204
205 /* if extern then do nothing or is a function
206 then do nothing */
207 if (IS_FUNC (sym->type) && !(sym->isitmp))
208 continue;
209
210 /* if it has an initial value then do it only if
211 it is a global variable */
212 if (sym->ival && sym->level == 0)
213 {
214 if ((SPEC_OCLS (sym->etype) == xidata || SPEC_OCLS (sym->etype) == initialized) && !SPEC_ABSA (sym->etype) && !SPEC_ADDRSPACE (sym->etype))
215 {
216 sym_link *t;
217 ast *ival = NULL;
218 symbol *tsym = copySymbol (sym);
219
220 // check for constant
221 if (IS_AGGREGATE (tsym->type))
222 {
223 ival = initAggregates (tsym, tsym->ival, NULL);
224 }
225 else
226 {
227 if (getNelements (tsym->type, tsym->ival) > 1)
228 {
229 werrorfl (tsym->fileDef, tsym->lineDef, W_EXCESS_INITIALIZERS, "scalar", tsym->name);
230 }
231 ival = newNode ('=', newAst_VALUE (symbolVal (tsym)),
232 decorateType (resolveSymbols (list2expr (tsym->ival)), RESULT_TYPE_NONE));
233 }
234 if (ival)
235 {
236 // set ival's lineno to where the symbol was defined
237 setAstFileLine (ival, filename = tsym->fileDef, lineno = tsym->lineDef);
238 // check if this is not a constant expression
239 if (!constExprTree (ival))
240 {
241 werrorfl (ival->filename, ival->lineno, E_CONST_EXPECTED, "found expression");
242 // but try to do it anyway
243 }
244 }
245
246 /* create a new "XINIT (CODE)" symbol, that will be emitted later
247 in the static seg */
248 newSym = copySymbol (sym);
249 SPEC_OCLS (newSym->etype) = (SPEC_OCLS (sym->etype) == xidata) ? xinit : initializer;
250 SNPRINTF (newSym->name, sizeof (newSym->name), "__xinit_%s", sym->name);
251 SNPRINTF (newSym->rname, sizeof (newSym->rname), "__xinit_%s", sym->rname);
252
253 /* find the first non-array link */
254 t = newSym->type;
255 while (IS_ARRAY (t))
256 t = t->next;
257 if (IS_SPEC (t))
258 SPEC_CONST (t) = 1;
259 else
260 DCL_PTR_CONST (t) = 1;
261 SPEC_STAT (newSym->etype) = 1;
262
263 strSym = NULL;
264 ++noAlloc;
265 resolveIvalSym (newSym->ival, newSym->type);
266 --noAlloc;
267
268 // add it to the "XINIT (CODE)" segment
269 addSet ((SPEC_OCLS (sym->etype) == xidata) ? &xinit->syms : &initializer->syms, newSym);
270
271 if (!SPEC_ABSA (sym->etype))
272 {
273 struct dbuf_s tmpBuf;
274 symbol *ps = NULL;
275 set *tmpSym = NULL;
276
277 wassert(dbuf_init (&tmpBuf, 4096));
278 // before allocation we must parse the sym->ival tree
279 // but without actually generating initialization code
280 ++noAlloc;
281 resolveIvalSym (sym->ival, sym->type);
282 ++noInit;
283 printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
284 --noInit;
285 --noAlloc;
286
287 // delete redundant __str_%d symbols (initializer for char arrays)
288 for (ps = setFirstItem (statsg->syms); ps; ps = setNextItem (statsg->syms))
289 if (!strstr (tmpBuf.buf, ps->name) && isinSet (strSym, ps))
290 addSet (&tmpSym, ps);
291 for (ps = setFirstItem (tmpSym); ps; ps = setNextItem (tmpSym))
292 deleteSetItem (&statsg->syms, ps);
293
294 deleteSet (&tmpSym);
295 dbuf_destroy (&tmpBuf);
296 }
297
298 if (strSym)
299 deleteSet (&strSym);
300 }
301 else
302 {
303 if (IS_AGGREGATE (sym->type))
304 {
305 ival = initAggregates (sym, sym->ival, NULL);
306 }
307 else
308 {
309 if (getNelements (sym->type, sym->ival) > 1)
310 {
311 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
312 }
313 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
314 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
315 }
316 codeOutBuf = &statsg->oBuf;
317
318 if (ival)
319 {
320 // set ival's lineno to where the symbol was defined
321 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
322 // check if this is not a constant expression
323 if (!constExprTree (ival))
324 {
325 werrorfl (ival->filename, ival->lineno, E_CONST_EXPECTED, "found expression");
326 // but try to do it anyway
327 }
328 allocInfo = 0;
329 if (!astErrors (ival))
330 eBBlockFromiCode (iCodeFromAst (ival));
331 allocInfo = 1;
332 }
333 }
334 }
335
336 /* if it has an absolute address then generate
337 an equate for this no need to allocate space */
338 if (SPEC_ABSA (sym->etype) && !sym->ival)
339 {
340 char *equ = "=";
341
342 /* print extra debug info if required */
343 if (options.debug)
344 {
345 emitDebugSym (&map->oBuf, sym);
346 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
347 }
348 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
349 }
350 else
351 {
352 int size = getSize (sym->type) + sym->flexArrayLength;
353 if (size == 0)
354 {
355 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
356 }
357 /* allocate space */
358 if (SPEC_ABSA (sym->etype))
359 {
360 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
361 }
362 /* print extra debug info if required */
363 if (options.debug)
364 {
365 emitDebugSym (&map->oBuf, sym);
366 dbuf_printf (&map->oBuf, "==.\n");
367 }
368 if (IS_STATIC (sym->etype) || sym->level)
369 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
370 else
371 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
372 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
373 }
374
375 sym->ival = NULL;
376 }
377 }
378
379 /*-----------------------------------------------------------------*/
380 /* initValPointer - pointer initialization code massaging */
381 /*-----------------------------------------------------------------*/
382 value *
initValPointer(ast * expr)383 initValPointer (ast *expr)
384 {
385 value *val;
386
387 /* no then we have to do these kludgy checks */
388 /* pointers can be initialized with address of
389 a variable or address of an array element */
390 if (IS_ADDRESS_OF_OP (expr))
391 {
392 /* address of symbol */
393 if (IS_AST_SYM_VALUE (expr->left))
394 {
395 STORAGE_CLASS sclass = SPEC_SCLS (expr->left->etype);
396 memmap *oclass = SPEC_OCLS (expr->left->etype);
397
398 val = AST_VALUE (expr->left);
399 val->type = newLink (DECLARATOR);
400 if (sclass == S_CODE)
401 {
402 DCL_TYPE (val->type) = CPOINTER;
403 CodePtrPointsToConst (val->type);
404 }
405 else if (oclass)
406 DCL_TYPE (val->type) = oclass->ptrType;
407 else if (sclass == S_XDATA)
408 DCL_TYPE (val->type) = FPOINTER;
409 else if (sclass == S_DATA)
410 DCL_TYPE (val->type) = POINTER;
411 else if (sclass == S_IDATA)
412 DCL_TYPE (val->type) = IPOINTER;
413 else if (sclass == S_PDATA)
414 DCL_TYPE (val->type) = PPOINTER;
415 else if (sclass == S_XSTACK)
416 DCL_TYPE (val->type) = PPOINTER;
417 else if (sclass == S_EEPROM)
418 DCL_TYPE (val->type) = EEPPOINTER;
419 else
420 DCL_TYPE (val->type) = POINTER;
421 val->type->next = expr->left->ftype;
422 val->etype = getSpec (val->type);
423 return val;
424 }
425
426 /* if address of indexed array */
427 if (IS_ARRAY_OP (expr->left))
428 return valForArray (expr->left);
429
430 /* if address of structure element then
431 case 1. a.b ; */
432 if (IS_AST_OP (expr->left) && expr->left->opval.op == '.')
433 {
434 return valForStructElem (expr->left->left, expr->left->right);
435 }
436
437 /* case 2. (&a)->b ;
438 (&some_struct)->element */
439 if (IS_AST_OP (expr->left) && expr->left->opval.op == PTR_OP && IS_ADDRESS_OF_OP (expr->left->left))
440 {
441 return valForStructElem (expr->left->left->left, expr->left->right);
442 }
443
444 /* case 2.1. a->b */
445 if (IS_AST_OP (expr->left) && expr->left->opval.op == PTR_OP)
446 {
447 return valForStructElem (expr->left->left, expr->left->right);
448 }
449 }
450
451 /* case 3. (((char *) &a) +/- constant) */
452 if (IS_AST_OP (expr) &&
453 (expr->opval.op == '+' || expr->opval.op == '-') &&
454 IS_CAST_OP (expr->left) && IS_ADDRESS_OF_OP (expr->left->right) && IS_AST_LIT_VALUE (expr->right))
455 {
456 return valForCastAggr (expr->left->right->left, expr->left->left->opval.lnk, expr->right, expr->opval.op);
457 }
458
459 /* case 4. (array type) */
460 if (IS_AST_SYM_VALUE (expr) && IS_ARRAY (expr->ftype))
461 {
462 STORAGE_CLASS sclass = SPEC_SCLS (expr->etype);
463 memmap *oclass = SPEC_OCLS (expr->etype);
464
465 val = copyValue (AST_VALUE (expr));
466 val->type = newLink (DECLARATOR);
467 if (SPEC_SCLS (expr->etype) == S_CODE)
468 {
469 DCL_TYPE (val->type) = CPOINTER;
470 CodePtrPointsToConst (val->type);
471 }
472 else if (oclass)
473 DCL_TYPE (val->type) = oclass->ptrType;
474 else if (sclass == S_XDATA)
475 DCL_TYPE (val->type) = FPOINTER;
476 else if (sclass == S_DATA)
477 DCL_TYPE (val->type) = POINTER;
478 else if (sclass == S_IDATA)
479 DCL_TYPE (val->type) = IPOINTER;
480 else if (sclass == S_PDATA)
481 DCL_TYPE (val->type) = PPOINTER;
482 else if (sclass == S_XSTACK)
483 DCL_TYPE (val->type) = PPOINTER;
484 else if (sclass == S_EEPROM)
485 DCL_TYPE (val->type) = EEPPOINTER;
486 else
487 DCL_TYPE (val->type) = POINTER;
488 val->type->next = expr->ftype->next;
489 val->etype = getSpec (val->type);
490 return val;
491 }
492
493 /* if structure element then
494 case 5. a.b ; */
495 if (IS_AST_OP (expr) && expr->opval.op == '.')
496 {
497 return valForStructElem (expr->left, expr->right);
498 }
499
500 /* case 6. a->b ;
501 some_struct->element */
502 if (IS_AST_OP (expr) && expr->opval.op == PTR_OP)
503 {
504 ast *t = expr->left;
505
506 /*if (expr->left->left)
507 if (expr->left->left->left)
508 if (expr->left->left->opval.op == '[')
509 t = expr->left->left;
510 else
511 t = expr->left->left->left;
512 else
513 t = expr->left->left;
514 else
515 t = expr->left;*/
516
517 /* a more generic way of above code */
518 while (t->left != NULL && t->opval.op != '[')
519 t = t->left;
520
521 return valForStructElem (t, expr->right);
522 }
523
524 /* case 7. function name */
525 if (IS_AST_SYM_VALUE (expr) && IS_FUNC (expr->ftype))
526 {
527 return AST_VALUE (expr);
528 }
529
530 return NULL;
531 }
532
533 /*-----------------------------------------------------------------*/
534 /* initPointer - pointer initialization code massaging */
535 /*-----------------------------------------------------------------*/
536 value *
initPointer(initList * ilist,sym_link * toType,int showError)537 initPointer (initList *ilist, sym_link *toType, int showError)
538 {
539 value *val;
540 ast *expr;
541
542 if (!ilist)
543 {
544 return valCastLiteral (toType, 0.0, 0);
545 }
546
547 expr = list2expr (ilist);
548
549 if (!expr)
550 {
551 if (showError)
552 werror (E_CONST_EXPECTED);
553 return 0;
554 }
555
556 /* try it the old way first */
557 if ((val = constExprValue (expr, FALSE)))
558 return val;
559
560 /* ( ptr + constant ) */
561 if (IS_AST_OP (expr) &&
562 (expr->opval.op == '+' || expr->opval.op == '-') &&
563 IS_AST_SYM_VALUE (expr->left) &&
564 (IS_ARRAY (expr->left->ftype) || IS_PTR (expr->left->ftype)) &&
565 compareType (toType, expr->left->ftype) && IS_AST_LIT_VALUE (expr->right))
566 {
567 return valForCastAggr (expr->left, expr->left->ftype, expr->right, expr->opval.op);
568 }
569
570 /* (char *)(expr1) */
571 if (IS_CAST_OP (expr))
572 {
573 if (compareType (toType, expr->left->ftype) == 0 && showError)
574 {
575 werror (W_INIT_WRONG);
576 printFromToType (expr->left->ftype, toType);
577 }
578 val = initValPointer (expr->right);
579 if (val)
580 {
581 DECLARATOR_TYPE dcl_type = DCL_TYPE (val->type);
582 val->type = expr->left->ftype;
583 val->etype = getSpec (val->type);
584 if (IS_GENPTR (val->type))
585 DCL_TYPE (val->type) = dcl_type;
586 }
587 }
588 else
589 {
590 val = initValPointer (expr);
591 }
592
593 if (val)
594 return val;
595
596 if (showError)
597 {
598 if (expr)
599 werrorfl (expr->filename, expr->lineno, E_CONST_EXPECTED);
600 else
601 werror (E_CONST_EXPECTED);
602 }
603 return 0;
604 }
605
606 /*-----------------------------------------------------------------*/
607 /* printChar - formats and prints a UTF-8 character string with DB */
608 /*-----------------------------------------------------------------*/
609 void
printChar(struct dbuf_s * oBuf,const char * s,int plen)610 printChar (struct dbuf_s *oBuf, const char *s, int plen)
611 {
612 int i;
613 int pplen = 0;
614 char buf[100];
615 char *p = buf;
616
617 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16) // Assembler does not support .ascii
618 {
619 while (pplen < plen)
620 {
621 if (isprint((unsigned char) *s))
622 dbuf_tprintf (oBuf, "\t!db !constbyte\t; %c\n", (unsigned char) *s, (unsigned char) *s);
623 else
624 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char) *s);
625
626 s++;
627 pplen++;
628 }
629 return;
630 }
631
632 while (pplen < plen)
633 {
634 i = 60;
635 while (i && pplen < plen)
636 {
637 if (!isprint((unsigned char) *s) || *s == '\"' || *s == '\\')
638 {
639 *p = '\0';
640 if (p != buf)
641 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
642 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char) *s);
643 p = buf;
644 i = 60;
645 }
646 else
647 {
648 *p = *s;
649 p++;
650 i--;
651 }
652 s++;
653 pplen++;
654 }
655 if (p != buf)
656 {
657 *p = '\0';
658 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
659 p = buf;
660 i = 60;
661 }
662 }
663 }
664
665 /*-----------------------------------------------------------------*/
666 /* printChar16 - formats and prints a UTF-16 character string with DB*/
667 /*-----------------------------------------------------------------*/
668 void
printChar16(struct dbuf_s * oBuf,const TYPE_TARGET_UINT * s,int plen)669 printChar16 (struct dbuf_s *oBuf, const TYPE_TARGET_UINT *s, int plen)
670 {
671 int pplen = 0;
672
673 while (pplen < plen)
674 {
675 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
676 {
677 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 0) & 0xff);
678 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 8) & 0xff);
679 }
680 else if (port->little_endian)
681 dbuf_printf (oBuf, "\t.byte %d,%d\n", (*s >> 0) & 0xff, (*s >> 8) & 0xff);
682 else
683 dbuf_printf (oBuf, "\t.byte %d,%d\n", (*s >> 8) & 0xff, (*s >> 0) & 0xff);
684
685 s++;
686 pplen++;
687 }
688 while (pplen < plen)
689 {
690 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
691 pplen++;
692 }
693 }
694
695 /*-----------------------------------------------------------------*/
696 /* printChar32 - formats and prints a UTF-32 character string with DB*/
697 /*-----------------------------------------------------------------*/
698 void
printChar32(struct dbuf_s * oBuf,const TYPE_TARGET_ULONG * s,int plen)699 printChar32 (struct dbuf_s *oBuf, const TYPE_TARGET_ULONG *s, int plen)
700 {
701 int pplen = 0;
702
703 while (pplen < plen)
704 {
705 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
706 {
707 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 0) & 0xff);
708 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 8) & 0xff);
709 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 16) & 0xff);
710 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (*s >> 24) & 0xff);
711 }
712 else if (port->little_endian)
713 dbuf_printf (oBuf, "\t.byte %d,%d,%d,%d\n", (*s >> 0) & 0xff, (*s >> 8) & 0xff, (*s >> 16) & 0xff, (*s >> 24) & 0xff);
714 else
715 dbuf_printf (oBuf, "\t.byte %d,%d,%d,%d\n", (*s >> 24) & 0xff, (*s >> 16) & 0xff, (*s >> 8) & 0xff,(*s >> 0) & 0xff);
716
717 s++;
718 pplen++;
719 }
720 while (pplen < plen)
721 {
722 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
723 pplen++;
724 }
725 }
726
727 /*-----------------------------------------------------------------*/
728 /* return the generic pointer high byte for a given pointer type. */
729 /*-----------------------------------------------------------------*/
730 int
pointerTypeToGPByte(const int p_type,const char * iname,const char * oname)731 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
732 {
733 switch (p_type)
734 {
735 case IPOINTER:
736 case POINTER:
737 return GPTYPE_NEAR;
738 case GPOINTER:
739 werror (W_USING_GENERIC_POINTER, iname ? iname : "<null>", oname ? oname : "<null>");
740 return -1;
741 case FPOINTER:
742 return GPTYPE_FAR;
743 case CPOINTER:
744 case FUNCTION:
745 return GPTYPE_CODE;
746 case PPOINTER:
747 return GPTYPE_XSTACK;
748 default:
749 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n", p_type);
750 exit (EXIT_FAILURE);
751 }
752 return -1;
753 }
754
755 /*-----------------------------------------------------------------*/
756 /* printIvalVal - generate ival according from value */
757 /*-----------------------------------------------------------------*/
printIvalVal(struct dbuf_s * oBuf,value * val,int size,bool newline)758 static void printIvalVal(struct dbuf_s *oBuf, value *val, int size, bool newline)
759 {
760 if (size == 2 && port->use_dw_for_init)
761 {
762 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
763 return;
764 }
765
766 const bool use_ret = TARGET_PDK_LIKE && !TARGET_IS_PDK16;
767
768 if (!use_ret)
769 dbuf_printf (oBuf, "\t.byte ");
770
771 for (int i = 0; i < size; i++)
772 {
773 const char *inst;
774 const char *byte = aopLiteral (val, port->little_endian ? i : size - 1 - i);
775 if (use_ret)
776 inst = i != size - 1 ? "\tret %s\n" : "\tret %s";
777 else
778 inst = i != size - 1 ? "%s, " : "%s";
779 dbuf_printf (oBuf, inst, byte);
780 }
781 if (newline)
782 dbuf_printf (oBuf, "\n");
783 }
784
785 /*-----------------------------------------------------------------*/
786 /* _printPointerType - generates ival for pointer type */
787 /*-----------------------------------------------------------------*/
788 static void
_printPointerType(struct dbuf_s * oBuf,const char * name,int size)789 _printPointerType (struct dbuf_s *oBuf, const char *name, int size)
790 {
791 wassert (!TARGET_PDK_LIKE);
792
793 if (size == 4)
794 {
795 if (port->little_endian)
796 dbuf_printf (oBuf, "\t.byte %s, (%s >> 8), (%s >> 16), (%s >> 24)", name, name, name, name);
797 else
798 dbuf_printf (oBuf, "\t.byte (%s >> 24), (%s >> 16), (%s >> 8), %s", name, name, name, name);
799 }
800 else if (size == 3)
801 {
802 if (port->little_endian)
803 dbuf_printf (oBuf, "\t.byte %s, (%s >> 8), (%s >> 16)", name, name, name);
804 else
805 dbuf_printf (oBuf, "\t.byte (%s >> 16), (%s >> 8), %s", name, name, name);
806 }
807 else
808 {
809 if (port->little_endian)
810 dbuf_printf (oBuf, "\t.byte %s, (%s >> 8)", name, name);
811 else
812 dbuf_printf (oBuf, "\t.byte (%s >> 8), %s", name, name);
813 }
814 }
815
816 /*-----------------------------------------------------------------*/
817 /* printPointerType - generates ival for pointer type */
818 /*-----------------------------------------------------------------*/
819 static void
printPointerType(struct dbuf_s * oBuf,const char * name)820 printPointerType (struct dbuf_s *oBuf, const char *name)
821 {
822 _printPointerType (oBuf, name, (options.model == MODEL_FLAT24) ? 3 : 2);
823 dbuf_printf (oBuf, "\n");
824 }
825
826 /*-----------------------------------------------------------------*/
827 /* printGPointerType - generates ival for generic pointer type */
828 /*-----------------------------------------------------------------*/
829 static void
printGPointerType(struct dbuf_s * oBuf,const char * iname,const char * oname,int type)830 printGPointerType (struct dbuf_s *oBuf, const char *iname, const char *oname, int type)
831 {
832 int byte = pointerTypeToGPByte (type, iname, oname);
833 int size = (options.model == MODEL_FLAT24) ? 3 : 2;
834 if (byte == -1)
835 {
836 _printPointerType (oBuf, iname, size + 1);
837 dbuf_printf (oBuf, "\n");
838 }
839 else
840 {
841 _printPointerType (oBuf, iname, size);
842 dbuf_printf (oBuf, ",#0x%02x\n", byte);
843 }
844 }
845
846 /*-----------------------------------------------------------------*/
847 /* printIvalType - generates ival for int/char */
848 /*-----------------------------------------------------------------*/
849 void
printIvalType(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf)850 printIvalType (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf)
851 {
852 value *val;
853 unsigned long ulVal = 0;
854
855 /* if initList is deep */
856 if (ilist && (ilist->type == INIT_DEEP))
857 ilist = ilist->init.deep;
858
859 if (!(val = list2val (ilist, FALSE)))
860 {
861 if (!!(val = initPointer (ilist, type, 0)))
862 {
863 int i, size = getSize (type), le = port->little_endian, top = (options.model == MODEL_FLAT24) ? 3 : 2;;
864 dbuf_printf (oBuf, "\t.byte ");
865 for (i = (le ? 0 : size - 1); le ? (i < size) : (i > -1); i += (le ? 1 : -1))
866 {
867 if (i == 0)
868 if (val->name && strlen (val->name) > 0)
869 dbuf_printf (oBuf, "%s", val->name);
870 else
871 dbuf_printf (oBuf, "#0x00");
872 else if (0 < i && i < top)
873 if (val->name && strlen (val->name) > 0)
874 dbuf_printf (oBuf, "(%s >> %d)", val->name, i * 8);
875 else
876 dbuf_printf (oBuf, "#0x00");
877 else
878 dbuf_printf (oBuf, "#0x00");
879 if (i == (le ? (size - 1) : 0))
880 dbuf_printf (oBuf, "\n");
881 else
882 dbuf_printf (oBuf, ", ");
883 }
884 return;
885 }
886 else
887 {
888 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
889 val = constCharVal (0);
890 }
891 }
892
893 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
894 {
895 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
896 val = constCharVal (0);
897 }
898
899 /* check if the literal value is within bounds */
900 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL)
901 {
902 werror (W_LIT_OVERFLOW);
903 }
904
905 if (val->type != type)
906 {
907 val = valCastLiteral (type, floatFromVal (val), (TYPE_TARGET_ULONGLONG) ullFromVal (val));
908 }
909
910 if (IS_INTEGRAL (val->type))
911 ulVal = ulFromVal (val);
912
913 switch (getSize (type))
914 {
915 case 1:
916 if (!val)
917 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
918 else
919 {
920 if (IS_UNSIGNED (val->type))
921 {
922 dbuf_tprintf (oBuf, "\t!dbs\t; %u", aopLiteral (val, 0), (unsigned int) ulVal);
923 }
924 else
925 {
926 dbuf_tprintf (oBuf, "\t!dbs\t; % d", aopLiteral (val, 0), (int) ulVal);
927 }
928 if (isalnum ((int) ulVal))
929 dbuf_tprintf (oBuf, "\t'%c'\n", (int) ulVal);
930 else
931 dbuf_tprintf (oBuf, "\n");
932 }
933 break;
934
935 case 2:
936 if (port->use_dw_for_init)
937 {
938 printIvalVal (oBuf, val, 2, true);
939 break;
940 }
941 printIvalVal (oBuf, val, 2, false);
942 if (IS_UNSIGNED (val->type))
943 dbuf_printf (oBuf, "\t; %u\n", (unsigned int) ulVal);
944 else
945 dbuf_printf (oBuf, "\t; % d\n", (int) ulVal);
946 break;
947
948 case 4:
949 if (!val)
950 {
951 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
952 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
953 }
954 else
955 {
956 printIvalVal (oBuf, val, 4, false);
957
958 if (IS_FLOAT (val->type))
959 {
960 dbuf_printf (oBuf, "\t; % e\n", floatFromVal (val));
961 }
962 else
963 {
964 if (IS_UNSIGNED (val->type))
965 dbuf_printf (oBuf, "\t; %u\n", (unsigned int) ulVal);
966 else
967 dbuf_printf (oBuf, "\t; % d\n", (int) ulVal);
968 }
969 }
970 break;
971 case 8:
972 printIvalVal (oBuf, val, 8, true); // TODO: Print value as comment. Does dbuf_printf support long long even on MSVC?
973 break;
974 default:
975 wassertl (0, "Attempting to initialize integer of non-handled size.");
976 }
977 }
978
979 /*-----------------------------------------------------------------*/
980 /* printIvalBitFields - generate initializer for bitfields */
981 /* return the number of bytes written */
982 /*-----------------------------------------------------------------*/
983 static unsigned int
printIvalBitFields(symbol ** sym,initList ** ilist,struct dbuf_s * oBuf)984 printIvalBitFields (symbol ** sym, initList ** ilist, struct dbuf_s *oBuf)
985 {
986 symbol *lsym = *sym;
987 initList *lilist = *ilist;
988 unsigned long ival = 0;
989 unsigned size = 0;
990 unsigned bit_start = 0;
991 unsigned long int bytes_written = 0;
992
993 while (lsym && IS_BITFIELD (lsym->type))
994 {
995 unsigned bit_length = SPEC_BLEN (lsym->etype);
996 if (0 == bit_length)
997 {
998 /* bit-field structure member with a width of 0 */
999 lsym = lsym->next;
1000 break;
1001 }
1002 else if (!SPEC_BUNNAMED (lsym->etype))
1003 {
1004 /* not an unnamed bit-field structure member */
1005 value *val = list2val (lilist, TRUE);
1006
1007 if (val && val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1008 {
1009 werrorfl (lilist->filename, lilist->lineno, E_CONST_EXPECTED);
1010 val = constCharVal (0);
1011 }
1012 if (size)
1013 {
1014 if (bit_length > 8)
1015 size += (bit_length + 7) / 8;
1016 }
1017 else
1018 size = (bit_length + 7) / 8;
1019
1020 /* check if the literal value is within bounds */
1021 if (val && checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL)
1022 {
1023 werror (W_LIT_OVERFLOW);
1024 }
1025
1026 ival |= (ulFromVal (val) & ((1ul << bit_length) - 1ul)) << bit_start;
1027 lilist = lilist ? lilist->next : NULL;
1028 }
1029 bit_start += bit_length;
1030 lsym = lsym->next;
1031 if (lsym && IS_BITFIELD (lsym->type) && (0 == SPEC_BSTR (lsym->etype)))
1032 {
1033 /* a new integer */
1034 break;
1035 }
1036 }
1037
1038 switch (size)
1039 {
1040 case 0:
1041 dbuf_tprintf (oBuf, "\n");
1042 break;
1043
1044 case 1:
1045 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
1046 bytes_written++;
1047 break;
1048
1049 case 2:
1050 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
1051 {
1052 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (ival & 0xff));
1053 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ((ival >> 8) & 0xff));
1054 }
1055 else
1056 dbuf_tprintf (oBuf, "\t!db !constbyte, !constbyte\n", (ival & 0xff), (ival >> 8) & 0xff);
1057 bytes_written += 2;
1058 break;
1059
1060 case 4:
1061 dbuf_tprintf (oBuf, "\t!db !constbyte, !constbyte, !constbyte, !constbyte\n",
1062 (ival & 0xff), (ival >> 8) & 0xff, (ival >> 16) & 0xff, (ival >> 24) & 0xff);
1063 bytes_written += 4;
1064 break;
1065 default:
1066 wassert (0);
1067 }
1068 *sym = lsym;
1069 *ilist = lilist;
1070
1071 return (bytes_written);
1072 }
1073
1074 /*-----------------------------------------------------------------*/
1075 /* printIvalStruct - generates initial value for structures */
1076 /*-----------------------------------------------------------------*/
1077 static void
printIvalStruct(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf)1078 printIvalStruct (symbol *sym, sym_link *type, initList *ilist, struct dbuf_s *oBuf)
1079 {
1080 symbol *sflds;
1081 initList *iloop = NULL;
1082 unsigned int skip_holes = 0;
1083
1084 sflds = SPEC_STRUCT (type)->fields;
1085
1086 if (ilist)
1087 {
1088 if (ilist->type != INIT_DEEP)
1089 {
1090 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
1091 return;
1092 }
1093
1094 iloop = ilist->init.deep;
1095 }
1096
1097 if (SPEC_STRUCT (type)->type == UNION)
1098 {
1099 int size;
1100 /* skip past holes, print value */
1101 while (iloop && iloop->type == INIT_HOLE)
1102 {
1103 iloop = iloop->next;
1104 sflds = sflds->next;
1105 }
1106 printIval (sym, sflds->type, iloop, oBuf, 1);
1107 /* pad out with zeros if necessary */
1108 size = getSize(type) - getSize(sflds->type);
1109 for ( ; size > 0 ; size-- )
1110 {
1111 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
1112 }
1113 /* advance past holes to find out if there were excess initializers */
1114 do
1115 {
1116 iloop = iloop ? iloop->next : NULL;
1117 sflds = sflds->next;
1118 }
1119 while (iloop && iloop->type == INIT_HOLE);
1120 }
1121 else
1122 {
1123 while (sflds)
1124 {
1125 unsigned int oldoffset = sflds->offset;
1126
1127 if (IS_BITFIELD (sflds->type))
1128 printIvalBitFields (&sflds, &iloop, oBuf);
1129 else
1130 {
1131 printIval (sym, sflds->type, iloop, oBuf, 1);
1132 sflds = sflds->next;
1133 iloop = iloop ? iloop->next : NULL;
1134 }
1135
1136 // Handle members from anonymous unions. Just a hack to fix bug #2643.
1137 while (sflds && sflds->offset == oldoffset)
1138 {
1139 sflds = sflds->next;
1140 skip_holes++;
1141 }
1142 }
1143
1144 while (skip_holes && iloop && iloop->type == INIT_HOLE)
1145 {
1146 skip_holes--;
1147 iloop = iloop ? iloop->next : NULL;
1148 }
1149 }
1150
1151 if (iloop)
1152 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
1153 }
1154
1155 /*-----------------------------------------------------------------*/
1156 /* printIvalChar - generates initital value for character array */
1157 /*-----------------------------------------------------------------*/
1158 int
printIvalChar(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf,const char * s,bool check)1159 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, const char *s, bool check)
1160 {
1161 value *val;
1162 size_t size = DCL_ELEM(type);
1163 char *p;
1164 size_t asz;
1165
1166 if (!s)
1167 {
1168 val = list2val (ilist, TRUE);
1169 /* if the value is a character string */
1170 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
1171 {
1172 if (!size)
1173 {
1174 /* we have not been given a size, but now we know it */
1175 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
1176 /* but first check, if it's a flexible array */
1177 if (sym && IS_STRUCT (sym->type))
1178 sym->flexArrayLength = size;
1179 else
1180 DCL_ELEM (type) = size;
1181 }
1182
1183 if (check && DCL_ELEM (val->type) > size)
1184 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
1185
1186 if (size > (asz = DCL_ELEM (val->type)) && !!(p = malloc (size)))
1187 {
1188 memcpy (p, SPEC_CVAL (val->etype).v_char, asz);
1189 memset (p + asz, 0x00, size - asz);
1190 printChar (oBuf, p, size);
1191 free (p);
1192 }
1193 else
1194 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
1195
1196 return 1;
1197 }
1198 else
1199 return 0;
1200 }
1201 else
1202 printChar (oBuf, s, strlen (s) + 1);
1203 return 1;
1204 }
1205
strLen16(const TYPE_TARGET_UINT * s)1206 static size_t strLen16(const TYPE_TARGET_UINT *s)
1207 {
1208 size_t l = 0;
1209 while(*s++)
1210 l++;
1211
1212 return l;
1213 }
1214
1215 /*-----------------------------------------------------------------*/
1216 /* printIvalChar16 - generates initital value for character array */
1217 /*-----------------------------------------------------------------*/
1218 int
printIvalChar16(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf,const TYPE_TARGET_UINT * s,bool check)1219 printIvalChar16 (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, const TYPE_TARGET_UINT *s, bool check)
1220 {
1221 value *val;
1222 size_t size = DCL_ELEM(type);
1223 TYPE_TARGET_UINT *p;
1224 size_t asz;
1225
1226 if (!s)
1227 {
1228 val = list2val (ilist, TRUE);
1229 /* if the value is a character string */
1230 if (IS_ARRAY (val->type) && IS_INT (val->etype) && IS_UNSIGNED (val->etype) && !IS_LONG (val->etype))
1231 {
1232 if (!size)
1233 {
1234 /* we have not been given a size, but now we know it */
1235 size = strLen16 (SPEC_CVAL (val->etype).v_char16) + 1;
1236 /* but first check, if it's a flexible array */
1237 if (sym && IS_STRUCT (sym->type))
1238 sym->flexArrayLength = size;
1239 else
1240 DCL_ELEM (type) = size;
1241 }
1242
1243 if (check && DCL_ELEM (val->type) > size)
1244 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
1245
1246 if (size > (asz = DCL_ELEM (val->type)) && !!(p = malloc (size * 2)))
1247 {
1248 memcpy (p, SPEC_CVAL (val->etype).v_char16, asz * 2);
1249 memset (p + asz, 0x00, size * 2 - asz * 2);
1250 printChar16 (oBuf, p, size);
1251 free (p);
1252 }
1253 else
1254 printChar16 (oBuf, SPEC_CVAL (val->etype).v_char16, size);
1255
1256 return 1;
1257 }
1258 else
1259 return 0;
1260 }
1261 else
1262 printChar16 (oBuf, s, strLen16 (s) + 1);
1263 return 1;
1264 }
1265
strLen32(const TYPE_TARGET_ULONG * s)1266 static size_t strLen32(const TYPE_TARGET_ULONG *s)
1267 {
1268 size_t l = 0;
1269 while(*s++)
1270 l++;
1271 return l;
1272 }
1273
1274 /*-----------------------------------------------------------------*/
1275 /* printIvalChar32 - generates initital value for character array */
1276 /*-----------------------------------------------------------------*/
1277 int
printIvalChar32(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf,const TYPE_TARGET_ULONG * s,bool check)1278 printIvalChar32 (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, const TYPE_TARGET_ULONG *s, bool check)
1279 {
1280 value *val;
1281 size_t size = DCL_ELEM(type);
1282 TYPE_TARGET_ULONG *p;
1283 size_t asz;
1284
1285 if (!s)
1286 {
1287 val = list2val (ilist, TRUE);
1288 /* if the value is a character string */
1289 if (IS_ARRAY (val->type) && IS_INT (val->etype) && IS_UNSIGNED (val->etype) && IS_LONG (val->etype))
1290 {
1291 if (!size)
1292 {
1293 /* we have not been given a size, but now we know it */
1294 size = strLen32 (SPEC_CVAL (val->etype).v_char32) + 1;
1295 /* but first check, if it's a flexible array */
1296 if (sym && IS_STRUCT (sym->type))
1297 sym->flexArrayLength = size;
1298 else
1299 DCL_ELEM (type) = size;
1300 }
1301
1302 if (check && DCL_ELEM (val->type) > size)
1303 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
1304
1305 if (size > (asz = DCL_ELEM (val->type)) && !!(p = malloc (size * 4)))
1306 {
1307 memcpy (p, SPEC_CVAL (val->etype).v_char32, asz * 4);
1308 memset (p + asz, 0x00, size * 4 - asz * 4);
1309 printChar32 (oBuf, p, size);
1310 free (p);
1311 }
1312 else
1313 printChar32 (oBuf, SPEC_CVAL (val->etype).v_char32, size);
1314
1315 return 1;
1316 }
1317 else
1318 return 0;
1319 }
1320 else
1321 printChar32 (oBuf, s, strLen32 (s) + 1);
1322 return 1;
1323 }
1324
1325 /*-----------------------------------------------------------------*/
1326 /* printIvalArray - generates code for array initialization */
1327 /*-----------------------------------------------------------------*/
1328 void
printIvalArray(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf,bool check)1329 printIvalArray (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, bool check)
1330 {
1331 value *val;
1332 initList *iloop;
1333 unsigned int size = 0;
1334
1335 if (ilist)
1336 {
1337 /* take care of the special case */
1338 /* array of characters can be init */
1339 /* by a string */
1340 /* char *p = "abc"; */
1341 if ((IS_CHAR (type->next) || IS_INT (type->next)) && ilist->type == INIT_NODE)
1342 {
1343 val = list2val (ilist, TRUE);
1344 if (!val)
1345 {
1346 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
1347 return;
1348 }
1349 if (!IS_LITERAL (val->etype))
1350 {
1351 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
1352 return;
1353 }
1354 if (IS_CHAR (type->next) && printIvalChar (sym, type, ilist, oBuf, SPEC_CVAL (sym->etype).v_char, check))
1355 return;
1356 if (IS_INT (type->next) && IS_UNSIGNED (type->next))
1357 {
1358 if (!IS_LONG (type->next) && printIvalChar16 (sym, type, ilist, oBuf, SPEC_CVAL (sym->etype).v_char16, check))
1359 return;
1360 if (IS_LONG (type->next) && printIvalChar32 (sym, type, ilist, oBuf, SPEC_CVAL (sym->etype).v_char32, check))
1361 return;
1362 }
1363 }
1364 /* char *p = {"abc"}; */
1365 if ((IS_CHAR (type->next) || IS_INT (type->next)) && ilist->type == INIT_DEEP && ilist->init.deep && ilist->init.deep->type == INIT_NODE)
1366 {
1367 val = list2val (ilist->init.deep, TRUE);
1368 if (!val)
1369 {
1370 werrorfl (ilist->init.deep->filename, ilist->init.deep->lineno, E_INIT_STRUCT, sym->name);
1371 return;
1372 }
1373 if (!IS_LITERAL (val->etype))
1374 {
1375 werrorfl (ilist->init.deep->filename, ilist->init.deep->lineno, E_CONST_EXPECTED);
1376 return;
1377 }
1378 if (IS_CHAR (type->next) && printIvalChar (sym, type, ilist->init.deep, oBuf, SPEC_CVAL (sym->etype).v_char, check))
1379 return;
1380 if (IS_INT (type->next) && IS_UNSIGNED (type->next))
1381 {
1382 if (!IS_LONG (type->next) && printIvalChar16 (sym, type, ilist->init.deep, oBuf, SPEC_CVAL (sym->etype).v_char16, check))
1383 return;
1384 if (IS_LONG (type->next) && printIvalChar32 (sym, type, ilist->init.deep, oBuf, SPEC_CVAL (sym->etype).v_char32, check))
1385 return;
1386 }
1387 }
1388
1389 /* not the special case */
1390 if (ilist->type != INIT_DEEP)
1391 {
1392 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
1393 return;
1394 }
1395
1396 for (iloop = ilist->init.deep; iloop; iloop = iloop->next)
1397 {
1398 if ((++size > DCL_ELEM (type)) && DCL_ELEM (type))
1399 {
1400 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
1401 break;
1402 }
1403 printIval (sym, type->next, iloop, oBuf, TRUE);
1404 }
1405 }
1406
1407 if (DCL_ELEM (type))
1408 {
1409 // pad with zeros if needed
1410 if (size < DCL_ELEM (type))
1411 {
1412 size = (DCL_ELEM (type) - size) * getSize (type->next);
1413 while (size--)
1414 {
1415 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
1416 }
1417 }
1418 }
1419 else
1420 {
1421 /* we have not been given a size, but now we know it */
1422 /* but first check, if it's a flexible array */
1423 if (IS_STRUCT (sym->type))
1424 sym->flexArrayLength = size * getSize (type->next);
1425 else
1426 DCL_ELEM (type) = size;
1427 }
1428
1429 return;
1430 }
1431
1432 /*-----------------------------------------------------------------*/
1433 /* printIvalFuncPtr - generate initial value for function pointers */
1434 /*-----------------------------------------------------------------*/
1435 void
printIvalFuncPtr(sym_link * type,initList * ilist,struct dbuf_s * oBuf)1436 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s *oBuf)
1437 {
1438 value *val;
1439 char *name;
1440 int size;
1441
1442 if (ilist)
1443 val = list2val (ilist, TRUE);
1444 else
1445 val = valCastLiteral (type, 0.0, 0);
1446
1447 if (!val)
1448 {
1449 // an error has been thrown already
1450 val = constCharVal (0);
1451 }
1452
1453 if (IS_LITERAL (val->etype))
1454 {
1455 if (compareType (type, val->type) == 0)
1456 {
1457 if (ilist)
1458 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
1459 else
1460 werror (E_INCOMPAT_TYPES);
1461 printFromToType (val->type, type);
1462 }
1463 printIvalCharPtr (NULL, type, val, oBuf);
1464 return;
1465 }
1466
1467 /* now generate the name */
1468 if (!val->sym)
1469 name = val->name;
1470 else
1471 name = val->sym->rname;
1472
1473 size = getSize (type);
1474
1475 if (size == FUNCPTRSIZE)
1476 {
1477 if (TARGET_PDK_LIKE)
1478 {
1479 dbuf_printf (oBuf, "\tret #<%s\n", name);
1480 dbuf_printf (oBuf, "\tret #>%s\n", name);
1481 }
1482 else if (TARGET_IS_STM8 && FUNCPTRSIZE == 3)
1483 {
1484 _printPointerType (oBuf, name, size);
1485 dbuf_printf (oBuf, "\n");
1486 }
1487 else if (port->use_dw_for_init)
1488 {
1489 dbuf_tprintf (oBuf, "\t!dws\n", name);
1490 }
1491 else
1492 {
1493 printPointerType (oBuf, name);
1494 }
1495 }
1496 else if (size == BFUNCPTRSIZE)
1497 {
1498 _printPointerType (oBuf, name, size);
1499 dbuf_printf (oBuf, "\n");
1500 }
1501 else
1502 {
1503 wassertl (0, "Invalid function pointer size.");
1504 }
1505
1506 return;
1507 }
1508
1509 /*--------------------------------------------------------------------*/
1510 /* printIvalCharPtr - generates initial values for character pointers */
1511 /*--------------------------------------------------------------------*/
1512 int
printIvalCharPtr(symbol * sym,sym_link * type,value * val,struct dbuf_s * oBuf)1513 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s *oBuf)
1514 {
1515 int size = 0;
1516 char *p;
1517
1518 if (val && !!(p = (char *) malloc (strlen (val->name) + 1)))
1519 {
1520 strcpy (p, val->name);
1521 addSet (&ccpStr, p);
1522 }
1523
1524 /* PENDING: this is _very_ mcs51 specific, including a magic
1525 number...
1526 It's also endian specific.
1527 */
1528 size = getSize (type);
1529
1530 if (val->name && strlen (val->name))
1531 {
1532 if (size == 1) /* This appears to be Z80 specific?? */
1533 {
1534 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1535 }
1536 else if (size == FARPTRSIZE)
1537 {
1538 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
1539 {
1540 dbuf_printf (oBuf, "\tret #<%s\n", val->name);
1541 dbuf_printf (oBuf, IN_CODESPACE (SPEC_OCLS (val->etype)) ? "\tret #>(%s + 0x8000)\n" : "\tret #0\n", val->name);
1542 }
1543 else if (port->use_dw_for_init)
1544 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1545 else
1546 printPointerType (oBuf, val->name);
1547 }
1548 else if (size == GPTRSIZE)
1549 {
1550 int type;
1551 if (IS_PTR (val->type))
1552 {
1553 type = DCL_TYPE (val->type);
1554 }
1555 else
1556 {
1557 type = PTR_TYPE (SPEC_OCLS (val->etype));
1558 }
1559 if (val->sym && val->sym->isstrlit)
1560 {
1561 // this is a literal string
1562 type = CPOINTER;
1563 }
1564 printGPointerType (oBuf, val->name, sym->name, type);
1565 }
1566 else
1567 {
1568 fprintf (stderr, "*** internal error: unknown size in " "printIvalCharPtr.\n");
1569 }
1570 }
1571 else
1572 {
1573 // these are literals assigned to pointers
1574 switch (size)
1575 {
1576 case 1:
1577 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
1578 break;
1579 case 2:
1580 if (TARGET_PDK_LIKE && !TARGET_IS_PDK16)
1581 {
1582 dbuf_tprintf (oBuf, "\tret %s\n", aopLiteral (val, 0));
1583 dbuf_tprintf (oBuf, "\tret %s\n", aopLiteral (val, 1));
1584 }
1585 else if (port->use_dw_for_init)
1586 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
1587 else if (port->little_endian)
1588 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1589 else
1590 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1591 break;
1592 case 3:
1593 if (IS_GENPTR (type) && GPTRSIZE > FARPTRSIZE && floatFromVal (val) != 0)
1594 {
1595 if (!IS_PTR (val->type) && !IS_FUNC (val->type))
1596 {
1597 // non-zero mcs51 generic pointer
1598 werrorfl (sym->fileDef, sym->lineDef, W_LITERAL_GENERIC);
1599 }
1600 if (port->little_endian)
1601 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteralGptr (sym->name, val));
1602 else
1603 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteralGptr (sym->name, val), aopLiteral (val, 1), aopLiteral (val, 0));
1604 }
1605 else
1606 {
1607 if (port->little_endian)
1608 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2));
1609 else
1610 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n", aopLiteral (val, 2), aopLiteral (val, 1), aopLiteral (val, 0));
1611 }
1612 break;
1613 case 4:
1614 if (IS_GENPTR (type) && GPTRSIZE > FARPTRSIZE && floatFromVal (val) != 0)
1615 {
1616 if (!IS_PTR (val->type) && !IS_FUNC (val->type))
1617 {
1618 // non-zero ds390 generic pointer
1619 werrorfl (sym->fileDef, sym->lineDef, W_LITERAL_GENERIC);
1620 }
1621 if (port->little_endian)
1622 {
1623 dbuf_printf (oBuf, "\t.byte %s,%s,%s", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2));
1624 if (IS_PTR (val->type) && !IS_GENPTR (val->type))
1625 dbuf_tprintf (oBuf, ",!immedbyte\n", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, sym->name));
1626 else
1627 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 3));
1628 }
1629 else
1630 {
1631 if (IS_PTR (val->type) && !IS_GENPTR (val->type))
1632 dbuf_tprintf (oBuf, "\t.byte !immedbyte\n", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, sym->name));
1633 else
1634 dbuf_printf (oBuf, "\t.byte %s\n", aopLiteral (val, 3));
1635 dbuf_printf (oBuf, ",%s,%s,%s", aopLiteral (val, 2), aopLiteral (val, 1), aopLiteral (val, 0));
1636 }
1637 }
1638 else
1639 {
1640 if (port->little_endian)
1641 {
1642 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1643 aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2), aopLiteral (val, 3));
1644 }
1645 else
1646 {
1647 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1648 aopLiteral (val, 3), aopLiteral (val, 2), aopLiteral (val, 1), aopLiteral (val, 0));
1649 }
1650 }
1651 break;
1652 default:
1653 assert (0);
1654 }
1655 }
1656
1657 if (!noInit && val->sym && val->sym->isstrlit && !isinSet (statsg->syms, val->sym))
1658 {
1659 addSet (&statsg->syms, val->sym);
1660 }
1661
1662 return 1;
1663 }
1664
1665 /*-----------------------------------------------------------------*/
1666 /* printIvalPtr - generates initial value for pointers */
1667 /*-----------------------------------------------------------------*/
1668 void
printIvalPtr(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf)1669 printIvalPtr (symbol *sym, sym_link *type, initList *ilist, struct dbuf_s *oBuf)
1670 {
1671 value *val;
1672 int size;
1673
1674 /* if deep then */
1675 if (ilist && (ilist->type == INIT_DEEP))
1676 ilist = ilist->init.deep;
1677
1678 /* function pointer */
1679 if (IS_FUNC (type->next))
1680 {
1681 printIvalFuncPtr (type, ilist, oBuf);
1682 return;
1683 }
1684
1685 if (!(val = initPointer (ilist, type, 1)))
1686 return;
1687
1688 /* if character pointer */
1689 if (IS_CHAR (type->next) || IS_INT (type->next) && IS_UNSIGNED (type->next))
1690 if (printIvalCharPtr (sym, type, val, oBuf))
1691 return;
1692
1693 /* check the type */
1694 if (compareType (type, val->type) == 0)
1695 {
1696 assert (ilist != NULL);
1697 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1698 printFromToType (val->type, type);
1699 }
1700
1701 /* if val is literal */
1702 if (IS_LITERAL (val->etype))
1703 {
1704 switch (getSize (type))
1705 {
1706 case 1:
1707 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1708 break;
1709 case 2:
1710 if (port->use_dw_for_init)
1711 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1712 else if (port->little_endian)
1713 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1714 else
1715 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1716 break;
1717 case 3:
1718 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1719 if (port->little_endian)
1720 dbuf_printf (oBuf, "\t.byte %s,%s", aopLiteral (val, 0), aopLiteral (val, 1));
1721 else
1722 dbuf_printf (oBuf, "\t.byte %s,%s", aopLiteral (val, 1), aopLiteral (val, 0));
1723 if (IS_GENPTR (val->type))
1724 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1725 else if (IS_PTR (val->type))
1726 dbuf_tprintf (oBuf, ",!immedbyte\n", pointerTypeToGPByte (DCL_TYPE (val->type), val->name, sym->name));
1727 else
1728 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1729 break;
1730 case 4:
1731 if (TARGET_IS_DS390 || TARGET_IS_DS400)
1732 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2), aopLiteral (val, 3));
1733 else
1734 wassertl(0, "Printing pointer of invalid size");
1735 break;
1736 default:
1737 wassertl(0, "Printing pointer of invalid size");
1738 break;
1739 }
1740 return;
1741 }
1742
1743 size = getSize (type);
1744
1745 if (TARGET_PDK_LIKE && size == 2)
1746 {
1747 if (IN_CODESPACE (SPEC_OCLS (val->etype)))
1748 {
1749 dbuf_printf (oBuf, "\tret #<%s\n", val->name);
1750 dbuf_printf (oBuf, "\tret #>(%s + 0x8000)\n", val->name);
1751 }
1752 else
1753 {
1754 dbuf_printf (oBuf, "\tret #%s\n", val->name);
1755 dbuf_printf (oBuf, "\tret #0\n");
1756 }
1757 }
1758 else if (size == 1) /* Z80 specific?? */
1759 {
1760 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1761 }
1762 else if (size == FARPTRSIZE)
1763 {
1764 if (port->use_dw_for_init)
1765 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1766 else
1767 printPointerType (oBuf, val->name);
1768 }
1769 else if (size == GPTRSIZE)
1770 {
1771 printGPointerType (oBuf, val->name, sym->name,
1772 (IS_PTR (val->type) ? DCL_TYPE (val->type) : PTR_TYPE (SPEC_OCLS (val->etype))));
1773 }
1774
1775 return;
1776 }
1777
1778 /*-----------------------------------------------------------------*/
1779 /* printIval - generates code for initial value */
1780 /*-----------------------------------------------------------------*/
1781 void
printIval(symbol * sym,sym_link * type,initList * ilist,struct dbuf_s * oBuf,bool check)1782 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *oBuf, bool check)
1783 {
1784 sym_link *itype;
1785
1786 /* Handle designated initializers */
1787 if (ilist && ilist->type==INIT_DEEP)
1788 ilist = reorderIlist (type, ilist);
1789
1790 /* If this is a hole, substitute an appropriate initializer. */
1791 if (ilist && ilist->type == INIT_HOLE)
1792 {
1793 if (IS_AGGREGATE (type))
1794 {
1795 ilist = newiList(INIT_DEEP, NULL); /* init w/ {} */
1796 }
1797 else
1798 {
1799 ast *ast = newAst_VALUE (constVal("0"));
1800 ast = decorateType (ast, RESULT_TYPE_NONE);
1801 ilist = newiList(INIT_NODE, ast);
1802 }
1803 }
1804
1805 /* if structure then */
1806 if (IS_STRUCT (type))
1807 {
1808 printIvalStruct (sym, type, ilist, oBuf);
1809 return;
1810 }
1811
1812 /* if this is an array */
1813 if (IS_ARRAY (type))
1814 {
1815 printIvalArray (sym, type, ilist, oBuf, check);
1816 return;
1817 }
1818
1819 if (ilist)
1820 {
1821 // not an aggregate, ilist must be a node
1822 if (ilist->type != INIT_NODE)
1823 {
1824 // or a 1-element list
1825 if (ilist->init.deep->next)
1826 {
1827 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
1828 }
1829 else
1830 {
1831 ilist = ilist->init.deep;
1832 }
1833 }
1834
1835 // and the type must match
1836 itype = ilist->init.node->ftype;
1837
1838 if (compareType (type, itype) == 0)
1839 {
1840 // special case for literal strings
1841 if (IS_ARRAY (itype) && IS_CHAR (getSpec (itype)) &&
1842 // which are really code pointers
1843 IS_CODEPTR (type))
1844 {
1845 // no sweat
1846 }
1847 else if (IS_CODEPTR (type) && IS_FUNC (type->next)) /* function pointer */
1848 {
1849 if (ilist)
1850 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
1851 else
1852 werror (E_INCOMPAT_TYPES);
1853 printFromToType (itype, type->next);
1854 }
1855 else
1856 {
1857 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1858 printFromToType (itype, type);
1859 }
1860 }
1861 }
1862
1863 /* if this is a pointer */
1864 if (IS_PTR (type))
1865 {
1866 printIvalPtr (sym, type, ilist, oBuf);
1867 return;
1868 }
1869
1870 /* if type is SPECIFIER */
1871 if (IS_SPEC (type))
1872 {
1873 printIvalType (sym, type, ilist, oBuf);
1874 return;
1875 }
1876 }
1877
1878 /*-----------------------------------------------------------------*/
1879 /* emitStaticSeg - emitcode for the static segment */
1880 /*-----------------------------------------------------------------*/
1881 void
emitStaticSeg(memmap * map,struct dbuf_s * oBuf)1882 emitStaticSeg (memmap *map, struct dbuf_s *oBuf)
1883 {
1884 symbol *sym;
1885 set *tmpSet = NULL;
1886
1887 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1888
1889 /* eliminate redundant __str_%d (generated in stringToSymbol(), SDCCast.c) */
1890 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
1891 addSet (&tmpSet, sym);
1892
1893 /* for all variables in this segment do */
1894 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
1895 {
1896 /* if it is "extern" then do nothing */
1897 if (IS_EXTERN (sym->etype) && !sym->ival)
1898 continue;
1899
1900 /* eliminate redundant __str_%d (generated in stringToSymbol(), SDCCast.c) */
1901 if (!isinSet (tmpSet, sym))
1902 {
1903 const char *p;
1904 if (!ccpStr)
1905 continue;
1906 for (p = setFirstItem (ccpStr); p; p = setNextItem (ccpStr))
1907 if (strcmp (p, sym->name) == 0)
1908 break;
1909 if (!p)
1910 continue;
1911 }
1912
1913 /* if it is not static add it to the public table */
1914 if (!IS_STATIC (sym->etype))
1915 {
1916 addSetHead (&publics, sym);
1917 }
1918
1919 /* if it has an absolute address and no initializer */
1920 if (SPEC_ABSA (sym->etype) && !sym->ival)
1921 {
1922 if (options.debug)
1923 {
1924 emitDebugSym (oBuf, sym);
1925 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1926 }
1927 dbuf_printf (oBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype));
1928 }
1929 else
1930 {
1931 int size = getSize (sym->type);
1932
1933 if (size == 0)
1934 {
1935 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
1936 }
1937 /* if it has an initial value */
1938 if (sym->ival)
1939 {
1940 if (SPEC_ABSA (sym->etype))
1941 {
1942 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1943 }
1944 if (options.debug)
1945 {
1946 emitDebugSym (oBuf, sym);
1947 dbuf_printf (oBuf, " == .\n");
1948 }
1949 dbuf_printf (oBuf, "%s:\n", sym->rname);
1950 ++noAlloc;
1951 resolveIvalSym (sym->ival, sym->type);
1952 printIval (sym, sym->type, sym->ival, oBuf, (map != xinit && map != initializer));
1953 --noAlloc;
1954 /* if sym is a simple string and sym->ival is a string,
1955 WE don't need it anymore */
1956 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1957 IS_AST_SYM_VALUE (list2expr (sym->ival)) && list2val (sym->ival, TRUE)->sym->isstrlit)
1958 {
1959 freeStringSymbol (list2val (sym->ival, TRUE)->sym);
1960 }
1961 }
1962 else
1963 {
1964 /* allocate space */
1965 if (options.debug)
1966 {
1967 emitDebugSym (oBuf, sym);
1968 dbuf_printf (oBuf, " == .\n");
1969 }
1970 /* special case for character strings */
1971 if (IS_ARRAY (sym->type) &&
1972 (IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char ||
1973 IS_INT (sym->type->next) && !IS_LONG (sym->type->next) && SPEC_CVAL (sym->etype).v_char16 ||
1974 IS_INT (sym->type->next) && IS_LONG (sym->type->next) && SPEC_CVAL (sym->etype).v_char32))
1975 {
1976 if (options.const_seg)
1977 dbuf_tprintf(&code->oBuf, "\t!area\n", options.const_seg);
1978 dbuf_printf (oBuf, "%s:\n", sym->rname);
1979 if (IS_CHAR (sym->type->next))
1980 printChar (oBuf, SPEC_CVAL (sym->etype).v_char, size);
1981 else if (IS_INT (sym->type->next) && !IS_LONG (sym->type->next))
1982 printChar16 (oBuf, SPEC_CVAL (sym->etype).v_char16, size / 2);
1983 else if (IS_INT (sym->type->next) && IS_LONG (sym->type->next))
1984 printChar32 (oBuf, SPEC_CVAL (sym->etype).v_char32, size / 4);
1985 else
1986 wassert (0);
1987 if (options.const_seg)
1988 dbuf_tprintf(oBuf, "\t!areacode\n", options.code_seg);
1989 }
1990 else
1991 {
1992 dbuf_printf (oBuf, "%s:\n", sym->rname);
1993 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1994 }
1995 }
1996 }
1997 }
1998
1999 if (tmpSet)
2000 deleteSet (&tmpSet);
2001 if (ccpStr)
2002 {
2003 char *p;
2004 for (p = setFirstItem (ccpStr); p; p = setNextItem (ccpStr))
2005 if (p)
2006 free (p);
2007 deleteSet (&ccpStr);
2008 }
2009 }
2010
2011 /*-----------------------------------------------------------------*/
2012 /* emitMaps - emits the code for the data portion the code */
2013 /*-----------------------------------------------------------------*/
2014 void
emitMaps(void)2015 emitMaps (void)
2016 {
2017 namedspacemap *nm;
2018 int publicsfr = TARGET_IS_MCS51 || TARGET_PDK_LIKE; /* Ideally, this should be true for all */
2019 /* ports but let's be conservative - EEP */
2020
2021 inInitMode++;
2022 /* no special considerations for the following
2023 data, idata & bit & xdata */
2024 emitRegularMap (data, TRUE, TRUE);
2025 emitRegularMap (initialized, TRUE, TRUE);
2026 for (nm = namedspacemaps; nm; nm = nm->next)
2027 if (nm->is_const)
2028 {
2029 dbuf_tprintf (&nm->map->oBuf, "\t!areacode\n", nm->map->sname);
2030 emitStaticSeg (nm->map, &nm->map->oBuf);
2031 }
2032 else
2033 emitRegularMap (nm->map, TRUE, TRUE);
2034 emitRegularMap (idata, TRUE, TRUE);
2035 emitRegularMap (d_abs, TRUE, TRUE);
2036 emitRegularMap (i_abs, TRUE, TRUE);
2037 emitRegularMap (bit, TRUE, TRUE);
2038 emitRegularMap (pdata, TRUE, TRUE);
2039 emitRegularMap (xdata, TRUE, TRUE);
2040 emitRegularMap (x_abs, TRUE, TRUE);
2041 if (port->genXINIT)
2042 {
2043 emitRegularMap (xidata, TRUE, TRUE);
2044 }
2045 emitRegularMap (sfr, publicsfr, FALSE);
2046 emitRegularMap (sfrbit, publicsfr, FALSE);
2047 emitRegularMap (home, TRUE, FALSE);
2048 emitRegularMap (code, TRUE, FALSE);
2049
2050 if (options.const_seg)
2051 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
2052 emitStaticSeg (statsg, &code->oBuf);
2053
2054 if (port->genXINIT)
2055 {
2056 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
2057 emitStaticSeg (xinit, &code->oBuf);
2058 }
2059 if (initializer)
2060 {
2061 dbuf_tprintf (&code->oBuf, "\t!area\n", initializer->sname);
2062 emitStaticSeg (initializer, &code->oBuf);
2063 }
2064 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
2065 emitStaticSeg (c_abs, &code->oBuf);
2066 inInitMode--;
2067 }
2068
2069 /*-----------------------------------------------------------------*/
2070 /* flushStatics - flush all currently defined statics out to file */
2071 /* and delete. Temporary function */
2072 /*-----------------------------------------------------------------*/
2073 void
flushStatics(void)2074 flushStatics (void)
2075 {
2076 emitStaticSeg (statsg, codeOutBuf);
2077 statsg->syms = NULL;
2078 }
2079
2080 /*-----------------------------------------------------------------*/
2081 /* createInterruptVect - creates the interrupt vector */
2082 /*-----------------------------------------------------------------*/
2083 void
createInterruptVect(struct dbuf_s * vBuf)2084 createInterruptVect (struct dbuf_s *vBuf)
2085 {
2086 mainf = newSymbol ("main", 0);
2087 mainf->block = 0;
2088
2089 /* only if the main function exists */
2090 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
2091 {
2092 if (!options.cc_only && !noAssemble && !options.c1mode)
2093 werror (E_NO_MAIN);
2094 return;
2095 }
2096
2097 /* if the main is only a prototype ie. no body then do nothing */
2098 if (!IFFUNC_HASBODY (mainf->type))
2099 {
2100 /* if ! compile only then main function should be present */
2101 if (!options.cc_only && !noAssemble)
2102 werror (E_NO_MAIN);
2103 return;
2104 }
2105
2106 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
2107 dbuf_printf (vBuf, "__interrupt_vect:\n");
2108
2109
2110 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
2111 {
2112 /* There's no such thing as a "generic" interrupt table header. */
2113 wassert (0);
2114 }
2115 }
2116
2117 char *iComments1 = {
2118 ";--------------------------------------------------------\n"
2119 "; File Created by SDCC : free open source ANSI-C Compiler\n"
2120 };
2121
2122 char *iComments2 = {
2123 ";--------------------------------------------------------\n"
2124 };
2125
2126
2127 /*-----------------------------------------------------------------*/
2128 /* initialComments - puts in some initial comments */
2129 /*-----------------------------------------------------------------*/
2130 void
initialComments(FILE * afile)2131 initialComments (FILE * afile)
2132 {
2133 fprintf (afile, "%s", iComments1);
2134 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s)\n", getBuildNumber (), getBuildEnvironment ());
2135 fprintf (afile, "%s", iComments2);
2136 }
2137
2138 /*-----------------------------------------------------------------*/
2139 /* printPublics - generates .global for publics */
2140 /*-----------------------------------------------------------------*/
2141 void
printPublics(FILE * afile)2142 printPublics (FILE * afile)
2143 {
2144 symbol *sym;
2145
2146 fprintf (afile, "%s", iComments2);
2147 fprintf (afile, "; Public variables in this module\n");
2148 fprintf (afile, "%s", iComments2);
2149
2150 for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
2151 tfprintf (afile, "\t!global\n", sym->rname);
2152 }
2153
2154 /*-----------------------------------------------------------------*/
2155 /* printExterns - generates .global for externs */
2156 /*-----------------------------------------------------------------*/
2157 void
printExterns(FILE * afile)2158 printExterns (FILE * afile)
2159 {
2160 symbol *sym;
2161
2162 fprintf (afile, "%s", iComments2);
2163 fprintf (afile, "; Externals used\n");
2164 fprintf (afile, "%s", iComments2);
2165
2166 for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
2167 tfprintf (afile, "\t!extern\n", sym->rname);
2168 }
2169
2170 /*-----------------------------------------------------------------*/
2171 /* emitOverlay - will emit code for the overlay stuff */
2172 /*-----------------------------------------------------------------*/
2173 static void
emitOverlay(struct dbuf_s * aBuf)2174 emitOverlay (struct dbuf_s *aBuf)
2175 {
2176 set *ovrset;
2177
2178 /* for each of the sets in the overlay segment do */
2179 for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets))
2180 {
2181 symbol *sym;
2182
2183 if (elementsInSet (ovrset))
2184 {
2185 /* output the area information */
2186 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
2187 }
2188
2189 for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset))
2190 {
2191 /* if extern then it is in the publics table: do nothing */
2192 if (IS_EXTERN (sym->etype))
2193 continue;
2194
2195 /* if allocation required check is needed
2196 then check if the symbol really requires
2197 allocation only for local variables */
2198 if (!IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level)
2199 continue;
2200
2201 /* if global variable & not static or extern
2202 and addPublics allowed then add it to the public set */
2203 if ((sym->_isparm && !IS_REGPARM (sym->etype)) && !IS_STATIC (sym->etype) && !IS_STATIC (sym->localof->etype))
2204 {
2205 addSetHead (&publics, sym);
2206 }
2207
2208 /* if extern then do nothing or is a function
2209 then do nothing */
2210 if (IS_FUNC (sym->type))
2211 continue;
2212
2213 /* if is has an absolute address then generate
2214 an equate for this no need to allocate space */
2215 if (SPEC_ABSA (sym->etype))
2216 {
2217 /* print extra debug info if required */
2218 if (options.debug)
2219 {
2220 emitDebugSym (aBuf, sym);
2221 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
2222 }
2223 dbuf_printf (aBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype));
2224 }
2225 else
2226 {
2227 int size = getSize (sym->type);
2228
2229 if (size == 0)
2230 {
2231 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
2232 }
2233 /* print extra debug info if required */
2234 if (options.debug)
2235 {
2236 emitDebugSym (aBuf, sym);
2237 dbuf_printf (aBuf, "==.\n");
2238 }
2239
2240 /* allocate space */
2241 dbuf_tprintf (aBuf, "!slabeldef\n", sym->rname);
2242 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
2243 }
2244 }
2245 }
2246 }
2247
2248 /*-----------------------------------------------------------------*/
2249 /* glue - the final glue that hold the whole thing together */
2250 /*-----------------------------------------------------------------*/
2251 void
glue(void)2252 glue (void)
2253 {
2254 struct dbuf_s vBuf;
2255 struct dbuf_s ovrBuf;
2256 struct dbuf_s asmFileName;
2257 FILE *asmFile;
2258 int mcs51_like;
2259 namedspacemap *nm;
2260
2261 dbuf_init (&vBuf, 4096);
2262 dbuf_init (&ovrBuf, 4096);
2263
2264 mcs51_like = (port->general.glue_up_main &&
2265 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_DS400));
2266
2267 /* print the global struct definitions */
2268 if (options.debug)
2269 cdbStructBlock (0);
2270
2271 /* PENDING: this isn't the best place but it will do */
2272 if (port->general.glue_up_main)
2273 {
2274 /* create the interrupt vector table */
2275 createInterruptVect (&vBuf);
2276 }
2277
2278 /* emit code for the all the variables declared */
2279 emitMaps ();
2280 /* do the overlay segments */
2281 emitOverlay (&ovrBuf);
2282
2283 outputDebugSymbols ();
2284
2285 /* now put it all together into the assembler file */
2286 /* create the assembler file name */
2287
2288 /* -o option overrides default name? */
2289 dbuf_init (&asmFileName, PATH_MAX);
2290 if ((noAssemble || options.c1mode) && fullDstFileName)
2291 {
2292 dbuf_append_str (&asmFileName, fullDstFileName);
2293 }
2294 else
2295 {
2296 dbuf_append_str (&asmFileName, dstFileName);
2297 dbuf_append_str (&asmFileName, port->assembler.file_ext);
2298 }
2299
2300 if (!(asmFile = fopen (dbuf_c_str (&asmFileName), "w")))
2301 {
2302 werror (E_FILE_OPEN_ERR, dbuf_c_str (&asmFileName));
2303 dbuf_destroy (&asmFileName);
2304 exit (EXIT_FAILURE);
2305 }
2306 dbuf_destroy (&asmFileName);
2307
2308 /* initial comments */
2309 initialComments (asmFile);
2310
2311 if (TARGET_IS_S08)
2312 fprintf (asmFile, "\t.cs08\n");
2313 else if (TARGET_IS_Z180)
2314 fprintf (asmFile, "\t.hd64\n");
2315 else if (TARGET_IS_R3KA)
2316 fprintf (asmFile, "\t.r3k\n");
2317 else if (TARGET_IS_EZ80_Z80)
2318 fprintf (asmFile, "\t.ez80\n");
2319
2320 /* print module name */
2321 tfprintf (asmFile, "\t!module\n", moduleName);
2322 if (mcs51_like)
2323 {
2324 if(!options.noOptsdccInAsm)
2325 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
2326
2327 switch (options.model)
2328 {
2329 case MODEL_SMALL:
2330 fprintf (asmFile, " --model-small");
2331 break;
2332 case MODEL_COMPACT:
2333 fprintf (asmFile, " --model-compact");
2334 break;
2335 case MODEL_MEDIUM:
2336 fprintf (asmFile, " --model-medium");
2337 break;
2338 case MODEL_LARGE:
2339 fprintf (asmFile, " --model-large");
2340 break;
2341 case MODEL_FLAT24:
2342 fprintf (asmFile, " --model-flat24");
2343 break;
2344 case MODEL_HUGE:
2345 fprintf (asmFile, " --model-huge");
2346 break;
2347 default:
2348 break;
2349 }
2350 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto"); */
2351 if (options.useXstack)
2352 fprintf (asmFile, " --xstack");
2353 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent"); */
2354 /*if(options.float_rent) fprintf (asmFile, " --float-rent"); */
2355 if (options.noRegParams)
2356 fprintf (asmFile, " --no-reg-params");
2357 if (options.parms_in_bank1)
2358 fprintf (asmFile, " --parms-in-bank1");
2359 if (options.all_callee_saves)
2360 fprintf (asmFile, " --all-callee-saves");
2361 fprintf (asmFile, "\n");
2362 }
2363 else if (!TARGET_PIC_LIKE && !options.noOptsdccInAsm)
2364 {
2365 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
2366 }
2367
2368 tfprintf (asmFile, "\t!fileprelude\n");
2369
2370 /* Let the port generate any global directives, etc. */
2371 if (port->genAssemblerPreamble)
2372 {
2373 port->genAssemblerPreamble (asmFile);
2374 }
2375
2376 /* print the global variables in this module */
2377 printPublics (asmFile);
2378 if (port->assembler.externGlobal)
2379 printExterns (asmFile);
2380
2381 if ((mcs51_like) || (TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_Z180 || TARGET_IS_RABBIT || TARGET_IS_EZ80_Z80) || TARGET_PDK_LIKE) /*.p.t.20030924 need to output SFR table for Z80 as well */
2382 {
2383 /* copy the sfr segment */
2384 fprintf (asmFile, "%s", iComments2);
2385 fprintf (asmFile, "; special function registers\n");
2386 fprintf (asmFile, "%s", iComments2);
2387 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
2388 }
2389
2390 if (mcs51_like)
2391 {
2392 /* copy the sbit segment */
2393 fprintf (asmFile, "%s", iComments2);
2394 fprintf (asmFile, "; special function bits\n");
2395 fprintf (asmFile, "%s", iComments2);
2396 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
2397
2398 /*JCF: Create the areas for the register banks */
2399 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
2400 {
2401 fprintf (asmFile, "%s", iComments2);
2402 fprintf (asmFile, "; overlayable register banks\n");
2403 fprintf (asmFile, "%s", iComments2);
2404 if (RegBankUsed[0])
2405 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
2406 if (RegBankUsed[1] || options.parms_in_bank1)
2407 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
2408 if (RegBankUsed[2])
2409 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
2410 if (RegBankUsed[3])
2411 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
2412 }
2413 if (BitBankUsed)
2414 {
2415 fprintf (asmFile, "%s", iComments2);
2416 fprintf (asmFile, "; overlayable bit register bank\n");
2417 fprintf (asmFile, "%s", iComments2);
2418 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
2419 fprintf (asmFile, "bits:\n\t.ds 1\n");
2420 fprintf (asmFile, "\tb0 = bits[0]\n");
2421 fprintf (asmFile, "\tb1 = bits[1]\n");
2422 fprintf (asmFile, "\tb2 = bits[2]\n");
2423 fprintf (asmFile, "\tb3 = bits[3]\n");
2424 fprintf (asmFile, "\tb4 = bits[4]\n");
2425 fprintf (asmFile, "\tb5 = bits[5]\n");
2426 fprintf (asmFile, "\tb6 = bits[6]\n");
2427 fprintf (asmFile, "\tb7 = bits[7]\n");
2428 }
2429 }
2430
2431 /* copy the data segment */
2432 fprintf (asmFile, "%s", iComments2);
2433 fprintf (asmFile, ";%s ram data\n", mcs51_like ? " internal" : "");
2434 fprintf (asmFile, "%s", iComments2);
2435 dbuf_write_and_destroy (&data->oBuf, asmFile);
2436
2437 /* copy the initialized segment */
2438 if (initialized)
2439 {
2440 fprintf (asmFile, "%s", iComments2);
2441 fprintf (asmFile, ";%s ram data\n", mcs51_like ? " internal" : "");
2442 fprintf (asmFile, "%s", iComments2);
2443 dbuf_write_and_destroy (&initialized->oBuf, asmFile);
2444 }
2445
2446 /* copy segments for named address spaces */
2447 for (nm = namedspacemaps; nm; nm = nm->next)
2448 {
2449 fprintf (asmFile, "%s", iComments2);
2450 fprintf (asmFile, "; %s %s data\n", nm->name, nm->is_const ? "rom" : "ram");
2451 fprintf (asmFile, "%s", iComments2);
2452 dbuf_write_and_destroy (&nm->map->oBuf, asmFile);
2453 }
2454
2455 /* create the overlay segments */
2456 if (overlay)
2457 {
2458 fprintf (asmFile, "%s", iComments2);
2459 fprintf (asmFile, "; overlayable items in%s ram \n", mcs51_like ? " internal" : "");
2460 fprintf (asmFile, "%s", iComments2);
2461 dbuf_write_and_destroy (&ovrBuf, asmFile);
2462 }
2463
2464 /* create the stack segment MOF */
2465 if (mainf && IFFUNC_HASBODY (mainf->type))
2466 {
2467 fprintf (asmFile, "%s", iComments2);
2468 fprintf (asmFile, "; Stack segment in internal ram \n");
2469 fprintf (asmFile, "%s", iComments2);
2470 fprintf (asmFile, "\t.area\tSSEG\n" "__start__stack:\n\t.ds\t1\n\n");
2471 }
2472
2473 /* create the idata segment */
2474 if (idata)
2475 {
2476 fprintf (asmFile, "%s", iComments2);
2477 fprintf (asmFile, "; indirectly addressable internal ram data\n");
2478 fprintf (asmFile, "%s", iComments2);
2479 dbuf_write_and_destroy (&idata->oBuf, asmFile);
2480 }
2481
2482 /* create the absolute idata/data segment */
2483 if (d_abs || i_abs)
2484 {
2485 fprintf (asmFile, "%s", iComments2);
2486 fprintf (asmFile, "; absolute%s ram data\n", mcs51_like ? " internal" : "");
2487 fprintf (asmFile, "%s", iComments2);
2488 if (d_abs)
2489 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
2490 if (i_abs)
2491 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
2492 }
2493
2494 /* copy the bit segment */
2495 if (bit)
2496 {
2497 fprintf (asmFile, "%s", iComments2);
2498 fprintf (asmFile, "; bit data\n");
2499 fprintf (asmFile, "%s", iComments2);
2500 dbuf_write_and_destroy (&bit->oBuf, asmFile);
2501 }
2502
2503 /* copy paged external ram data */
2504 if (pdata)
2505 {
2506 fprintf (asmFile, "%s", iComments2);
2507 fprintf (asmFile, "; paged external ram data\n");
2508 fprintf (asmFile, "%s", iComments2);
2509 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
2510 }
2511
2512 /* if external stack then reserve space for it */
2513 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
2514 {
2515 fprintf (asmFile, "%s", iComments2);
2516 fprintf (asmFile, "; external stack \n");
2517 fprintf (asmFile, "%s", iComments2);
2518 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n" "__start__xstack:\n\t.ds\t1\n\n");
2519 }
2520
2521 /* copy external ram data */
2522 if (xdata && mcs51_like)
2523 {
2524 fprintf (asmFile, "%s", iComments2);
2525 fprintf (asmFile, "; external ram data\n");
2526 fprintf (asmFile, "%s", iComments2);
2527 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
2528 }
2529
2530 /* create the absolute xdata segment */
2531 if (x_abs)
2532 {
2533 fprintf (asmFile, "%s", iComments2);
2534 fprintf (asmFile, "; absolute external ram data\n");
2535 fprintf (asmFile, "%s", iComments2);
2536 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
2537 }
2538
2539 /* copy external initialized ram data */
2540 if (xidata)
2541 {
2542 fprintf (asmFile, "%s", iComments2);
2543 fprintf (asmFile, "; external initialized ram data\n");
2544 fprintf (asmFile, "%s", iComments2);
2545 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
2546 }
2547
2548 /* If the port wants to generate any extra areas, let it do so. */
2549 if (port->extraAreas.genExtraAreaDeclaration)
2550 {
2551 port->extraAreas.genExtraAreaDeclaration (asmFile, mainf && IFFUNC_HASBODY (mainf->type));
2552 }
2553
2554 /* copy the interrupt vector table */
2555 if (mainf && IFFUNC_HASBODY (mainf->type))
2556 {
2557 fprintf (asmFile, "%s", iComments2);
2558 fprintf (asmFile, "; interrupt vector \n");
2559 fprintf (asmFile, "%s", iComments2);
2560 dbuf_write_and_destroy (&vBuf, asmFile);
2561 }
2562
2563 /* copy global & static initialisations */
2564 fprintf (asmFile, "%s", iComments2);
2565 fprintf (asmFile, "; global & static initialisations\n");
2566 fprintf (asmFile, "%s", iComments2);
2567
2568 /* Everywhere we generate a reference to the static_name area,
2569 * (which is currently only here), we immediately follow it with a
2570 * definition of the post_static_name area. This guarantees that
2571 * the post_static_name area will immediately follow the static_name
2572 * area.
2573 */
2574 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
2575 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
2576 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
2577 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
2578
2579 if (mainf && IFFUNC_HASBODY (mainf->type))
2580 {
2581 if (port->genInitStartup)
2582 {
2583 port->genInitStartup (asmFile);
2584 }
2585 else
2586 {
2587 assert (0);
2588 }
2589 }
2590 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
2591
2592 /* STM8 / PDK14 note: there are no such instructions supported.
2593 Also, we don't need this logic as well. */
2594 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
2595 {
2596 /* This code is generated in the post-static area.
2597 * This area is guaranteed to follow the static area
2598 * by the ugly shucking and jiving about 20 lines ago.
2599 */
2600 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
2601 if(TARGET_IS_STM8)
2602 fprintf (asmFile, "\tjp\t__sdcc_program_startup\n");
2603 else if(TARGET_PDK_LIKE)
2604 fprintf (asmFile, "\tgoto\t__sdcc_program_startup\n");
2605 else
2606 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp ? 'a' : 'l');
2607 }
2608
2609 fprintf (asmFile, "%s" "; Home\n" "%s", iComments2, iComments2);
2610 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
2611 dbuf_write_and_destroy (&home->oBuf, asmFile);
2612
2613 if (mainf && IFFUNC_HASBODY (mainf->type))
2614 {
2615 /* STM8 note: there is no need to call main().
2616 Instead of that, it's address is specified in the
2617 interrupts table and always equals to 0x8080.
2618 */
2619
2620 /* entry point @ start of HOME */
2621 fprintf (asmFile, "__sdcc_program_startup:\n");
2622
2623 /* put in jump or call to main */
2624 if(TARGET_IS_STM8)
2625 fprintf (asmFile, options.model == MODEL_LARGE ? "\tjpf\t_main\n" : "\tjp\t_main\n");
2626 else if(TARGET_PDK_LIKE)
2627 fprintf (asmFile, "\tgoto\t_main\n");
2628 else
2629 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp ? 'a' : 'l'); /* needed? */
2630 fprintf (asmFile, ";\treturn from main will return to caller\n");
2631 }
2632 /* copy over code */
2633 fprintf (asmFile, "%s", iComments2);
2634 fprintf (asmFile, "; code\n");
2635 fprintf (asmFile, "%s", iComments2);
2636 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
2637 dbuf_write_and_destroy (&code->oBuf, asmFile);
2638
2639 if (port->genAssemblerEnd)
2640 {
2641 port->genAssemblerEnd (asmFile);
2642 }
2643 fclose (asmFile);
2644 }
2645
2646 /* will return 1 if the string is a part
2647 of a target specific keyword */
2648 int
isTargetKeyword(const char * s)2649 isTargetKeyword (const char *s)
2650 {
2651 int i;
2652
2653 if (port->keywords == NULL)
2654 return 0;
2655
2656 if (s[0] == '_' && s[1] == '_')
2657 {
2658 /* Keywords in the port's array have either 0 or 1 underscore, */
2659 /* so skip over the appropriate number of chars when comparing */
2660 for (i = 0 ; port->keywords[i] ; i++ )
2661 {
2662 if (port->keywords[i][0] == '_' &&
2663 strcmp(port->keywords[i],s+1) == 0)
2664 return 1;
2665 else if (strcmp(port->keywords[i],s+2) == 0)
2666 return 1;
2667 }
2668 }
2669 else
2670 {
2671 for (i = 0 ; port->keywords[i] ; i++ )
2672 {
2673 if (strcmp(port->keywords[i],s) == 0)
2674 return 1;
2675 }
2676 }
2677
2678 return 0;
2679 }
2680
2681