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
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 -------------------------------------------------------------------------*/
26 #include "dbuf_string.h"
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;
45 int noInit
= 0; /* no initialization */
49 aopLiteralGptr (const char *name
, const value
*val
)
51 unsigned long v
= ulFromVal (val
);
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
));
63 dbuf_tprintf (&dbuf
, "!immedbyte", (unsigned int) v
& 0xff);
65 return dbuf_detach_c_str (&dbuf
);
69 aopLiteralLong (value
*val
, int offset
, int size
)
76 // assuming we have been warned before
77 val
= constCharVal (0);
80 dbuf_init (&dbuf
, 128);
85 v
= byteOfVal (val
, offset
);
86 dbuf_tprintf (&dbuf
, "!immedbyte", (unsigned int) v
& 0xff);
89 v
= byteOfVal (val
, offset
+1);
90 v
= (v
<< 8) | byteOfVal (val
, offset
);
91 dbuf_tprintf (&dbuf
, "!immedword", (unsigned int) v
& 0xffff);
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);
101 /* Hmm. Too big for now. */
104 return dbuf_detach_c_str (&dbuf
);
107 /*-----------------------------------------------------------------*/
108 /* aopLiteral - string from a literal value */
109 /*-----------------------------------------------------------------*/
111 aopLiteral (value
*val
, int offset
)
113 return aopLiteralLong (val
, offset
, 1);
116 /*-----------------------------------------------------------------*/
117 /* emitDebugSym - emit label for debug symbol */
118 /*-----------------------------------------------------------------*/
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 /*-----------------------------------------------------------------*/
141 emitRegularMap (memmap
*map
, bool addPublics
, bool arFlag
)
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
);
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
);
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
);
169 dbuf_tprintf (&map
->oBuf
, "\t!area\n", map
->sname
);
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
)
186 /* for bitvar locals and parameters */
187 if (!arFlag
&& !sym
->allocreq
&& sym
->level
&& !SPEC_ABSA (sym
->etype
))
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
))) &&
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
);
211 /* if extern then do nothing or is a function
213 if (IS_FUNC (sym
->type
) && !(sym
->isitmp
))
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
))
224 symbol
*tsym
= copySymbol (sym
);
226 // check for constant
227 if (IS_AGGREGATE (tsym
->type
))
229 ival
= initAggregates (tsym
, tsym
->ival
, NULL
);
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));
242 // No point trying to initialize by something that doesn't even make sense.
243 if (astErrors (ival
))
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
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 */
270 DCL_PTR_CONST (t
) = 1;
271 SPEC_STAT (newSym
->etype
) = 1;
275 resolveIvalSym (newSym
->ival
, newSym
->type
);
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
;
287 wassert(dbuf_init (&tmpBuf
, 4096));
288 // before allocation we must parse the sym->ival tree
289 // but without actually generating initialization code
291 resolveIvalSym (sym
->ival
, sym
->type
);
293 printIval (sym
, sym
->type
, sym
->ival
, &tmpBuf
, TRUE
);
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
);
305 dbuf_destroy (&tmpBuf
);
313 if (IS_AGGREGATE (sym
->type
))
315 ival
= initAggregates (sym
, sym
->ival
, NULL
);
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.
341 if (!astErrors (ival
))
342 eBBlockFromiCode (iCodeFromAst (ival
));
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
)
355 /* print extra debug info if required */
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
));
365 int size
= getSize (sym
->type
) + sym
->flexArrayLength
;
368 werrorfl (sym
->fileDef
, sym
->lineDef
, E_UNKNOWN_SIZE
, sym
->name
);
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 */
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
);
384 dbuf_tprintf (&map
->oBuf
, "!labeldef\n", sym
->rname
);
385 dbuf_tprintf (&map
->oBuf
, "\t!ds\n", (unsigned int) size
& 0xffff);
392 /*-----------------------------------------------------------------*/
393 /* initValPointer - pointer initialization code massaging */
394 /*-----------------------------------------------------------------*/
396 initValPointer (ast
*expr
)
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
);
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
;
433 DCL_TYPE (val
->type
) = POINTER
;
434 val
->type
->next
= expr
->left
->ftype
;
435 val
->etype
= getSpec (val
->type
);
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
445 if (IS_AST_OP (expr
->left
) && expr
->left
->opval
.op
== '.')
447 return valForStructElem (expr
->left
->left
, expr
->left
->right
);
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
);
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
);
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
;
500 DCL_TYPE (val
->type
) = POINTER
;
501 val
->type
->next
= expr
->ftype
->next
;
502 val
->etype
= getSpec (val
->type
);
506 /* if structure element then
508 if (IS_AST_OP (expr
) && expr
->opval
.op
== '.')
510 return valForStructElem (expr
->left
, expr
->right
);
514 some_struct->element */
515 if (IS_AST_OP (expr
) && expr
->opval
.op
== PTR_OP
)
519 /*if (expr->left->left)
520 if (expr->left->left->left)
521 if (expr->left->left->opval.op == '[')
522 t = expr->left->left;
524 t = expr->left->left->left;
526 t = expr->left->left;
530 /* a more generic way of above code */
531 while (t
->left
!= NULL
&& t
->opval
.op
!= '[')
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
);
546 /*-----------------------------------------------------------------*/
547 /* initPointer - pointer initialization code massaging */
548 /*-----------------------------------------------------------------*/
550 initPointer (initList
*ilist
, sym_link
*toType
, int showError
)
557 return valCastLiteral (toType
, 0.0, 0);
560 expr
= list2expr (ilist
);
565 werror (E_CONST_EXPECTED
);
569 /* try it the old way first */
570 if ((val
= constExprValue (expr
, FALSE
)))
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
);
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
;
603 val
= initValPointer (expr
);
612 werrorfl (expr
->filename
, expr
->lineno
, E_CONST_EXPECTED
);
614 werror (E_CONST_EXPECTED
);
619 /*-----------------------------------------------------------------*/
620 /* printChar - formats and prints a UTF-8 character string with DB */
621 /*-----------------------------------------------------------------*/
623 printChar (struct dbuf_s
*oBuf
, const char *s
, int plen
)
630 if (TARGET_PDK_LIKE
&& !TARGET_IS_PDK16
) // Assembler does not support .ascii
634 if (isprint((unsigned char) *s
))
635 dbuf_tprintf (oBuf
, "\t!db !constbyte\t; %c\n", (unsigned char) *s
, (unsigned char) *s
);
637 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", (unsigned char) *s
);
648 while (i
&& pplen
< plen
)
650 if (!isprint((unsigned char) *s
) || *s
== '\"' || *s
== '\\')
654 dbuf_tprintf (oBuf
, "\t!ascii\n", buf
);
655 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", (unsigned char) *s
);
671 dbuf_tprintf (oBuf
, "\t!ascii\n", buf
);
678 /*-----------------------------------------------------------------*/
679 /* printChar16 - formats and prints a UTF-16 character string with DB*/
680 /*-----------------------------------------------------------------*/
682 printChar16 (struct dbuf_s
*oBuf
, const TYPE_TARGET_UINT
*s
, int 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);
696 dbuf_printf (oBuf
, "\t.byte %d,%d\n", (*s
>> 8) & 0xff, (*s
>> 0) & 0xff);
703 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", 0);
708 /*-----------------------------------------------------------------*/
709 /* printChar32 - formats and prints a UTF-32 character string with DB*/
710 /*-----------------------------------------------------------------*/
712 printChar32 (struct dbuf_s
*oBuf
, const TYPE_TARGET_ULONG
*s
, int 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);
728 dbuf_printf (oBuf
, "\t.byte %d,%d,%d,%d\n", (*s
>> 24) & 0xff, (*s
>> 16) & 0xff, (*s
>> 8) & 0xff,(*s
>> 0) & 0xff);
735 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", 0);
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
)
752 werror (W_USING_GENERIC_POINTER
, iname
? iname
: "<null>", oname
? oname
: "<null>");
760 return GPTYPE_XSTACK
;
762 fprintf (stderr
, "*** internal error: unknown pointer type %d in GPByte.\n", p_type
);
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));
779 const bool use_ret
= TARGET_PDK_LIKE
&& !TARGET_IS_PDK16
;
782 dbuf_printf (oBuf
, "\t.byte ");
784 for (int i
= 0; i
< size
; i
++)
787 const char *byte
= aopLiteral (val
, port
->little_endian
? i
: size
- 1 - i
);
789 inst
= i
!= size
- 1 ? "\tret %s\n" : "\tret %s";
791 inst
= i
!= size
- 1 ? "%s, " : "%s";
792 dbuf_printf (oBuf
, inst
, byte
);
795 dbuf_printf (oBuf
, "\n");
798 /*-----------------------------------------------------------------*/
799 /* _printPointerType - generates ival for pointer type */
800 /*-----------------------------------------------------------------*/
802 _printPointerType (struct dbuf_s
*oBuf
, const char *name
, int size
)
804 wassert (!TARGET_PDK_LIKE
);
808 if (port
->little_endian
)
809 dbuf_printf (oBuf
, "\t.byte %s, (%s >> 8), (%s >> 16), (%s >> 24)", name
, name
, name
, name
);
811 dbuf_printf (oBuf
, "\t.byte (%s >> 24), (%s >> 16), (%s >> 8), %s", name
, name
, name
, name
);
815 if (port
->little_endian
)
816 dbuf_printf (oBuf
, "\t.byte %s, (%s >> 8), (%s >> 16)", name
, name
, name
);
818 dbuf_printf (oBuf
, "\t.byte (%s >> 16), (%s >> 8), %s", name
, name
, name
);
822 if (port
->little_endian
)
823 dbuf_printf (oBuf
, "\t.byte %s, (%s >> 8)", name
, name
);
825 dbuf_printf (oBuf
, "\t.byte (%s >> 8), %s", name
, name
);
829 /*-----------------------------------------------------------------*/
830 /* printPointerType - generates ival for pointer type */
831 /*-----------------------------------------------------------------*/
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 /*-----------------------------------------------------------------*/
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;
849 _printPointerType (oBuf
, iname
, size
+ 1);
850 dbuf_printf (oBuf
, "\n");
854 _printPointerType (oBuf
, iname
, size
);
855 dbuf_printf (oBuf
, ",#0x%02x\n", byte
);
859 /*-----------------------------------------------------------------*/
860 /* printIvalType - generates ival for int/char */
861 /*-----------------------------------------------------------------*/
863 printIvalType (symbol
* sym
, sym_link
* type
, initList
* ilist
, struct dbuf_s
*oBuf
)
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))
881 if (val
->name
&& strlen (val
->name
) > 0)
882 dbuf_printf (oBuf
, "%s", val
->name
);
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);
889 dbuf_printf (oBuf
, "#0x00");
891 dbuf_printf (oBuf
, "#0x00");
892 if (i
== (le
? (size
- 1) : 0))
893 dbuf_printf (oBuf
, "\n");
895 dbuf_printf (oBuf
, ", ");
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
))
930 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", 0);
933 if (IS_UNSIGNED (val
->type
))
935 dbuf_tprintf (oBuf
, "\t!dbs\t; %u", aopLiteral (val
, 0), (unsigned int) ulVal
);
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
);
944 dbuf_tprintf (oBuf
, "\n");
949 if (port
->use_dw_for_init
)
951 printIvalVal (oBuf
, val
, 2, true);
954 printIvalVal (oBuf
, val
, 2, false);
955 if (IS_UNSIGNED (val
->type
))
956 dbuf_printf (oBuf
, "\t; %u\n", (unsigned int) ulVal
);
958 dbuf_printf (oBuf
, "\t; % d\n", (int) ulVal
);
964 dbuf_tprintf (oBuf
, "\t!dw !constword\n", 0);
965 dbuf_tprintf (oBuf
, "\t!dw !constword\n", 0);
969 printIvalVal (oBuf
, val
, 4, false);
971 if (IS_FLOAT (val
->type
))
973 dbuf_printf (oBuf
, "\t; % e\n", floatFromVal (val
));
977 if (IS_UNSIGNED (val
->type
))
978 dbuf_printf (oBuf
, "\t; %u\n", (unsigned int) ulVal
);
980 dbuf_printf (oBuf
, "\t; % d\n", (int) ulVal
);
985 printIvalVal (oBuf
, val
, getSize (type
), true);
990 /*-----------------------------------------------------------------*/
991 /* printIvalBitFields - generate initializer for bitfields */
992 /* return the number of bytes written */
993 /*-----------------------------------------------------------------*/
995 printIvalBitFields (symbol
** sym
, initList
** ilist
, struct dbuf_s
*oBuf
)
998 initList
*lilist
= *ilist
;
999 unsigned long long ival
= 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 */
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);
1026 size
+= (bit_length
+ 7) / 8;
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
;
1042 if (lsym
&& IS_BITFIELD (lsym
->type
) && (0 == SPEC_BSTR (lsym
->etype
)))
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));
1054 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", (unsigned)(((unsigned long long)ival
>> i
* 8) & 0xff));
1061 return (bytes_written
);
1064 /*-----------------------------------------------------------------*/
1065 /* printIvalStruct - generates initial value for structures */
1066 /*-----------------------------------------------------------------*/
1068 printIvalStruct (symbol
*sym
, sym_link
*type
, initList
*ilist
, struct dbuf_s
*oBuf
)
1071 initList
*iloop
= NULL
;
1072 unsigned int skip_holes
= 0;
1074 sflds
= SPEC_STRUCT (type
)->fields
;
1078 if (ilist
->type
!= INIT_DEEP
)
1080 werrorfl (sym
->fileDef
, sym
->lineDef
, E_INIT_STRUCT
, sym
->name
);
1084 iloop
= ilist
->init
.deep
;
1087 if (SPEC_STRUCT (type
)->type
== UNION
)
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
);
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
;
1119 unsigned int oldoffset
= sflds
->offset
;
1121 if (IS_BITFIELD (sflds
->type
))
1122 printIvalBitFields (&sflds
, &iloop
, oBuf
);
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
;
1138 while (skip_holes
&& iloop
&& iloop
->type
== INIT_HOLE
)
1141 iloop
= iloop
? iloop
->next
: NULL
;
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
)
1156 size_t size
= DCL_ELEM(type
);
1162 val
= list2val (ilist
, TRUE
);
1163 /* if the value is a character string */
1164 if (IS_ARRAY (val
->type
) && IS_CHAR (val
->etype
))
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
;
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
);
1188 printChar (oBuf
, SPEC_CVAL (val
->etype
).v_char
, size
);
1196 printChar (oBuf
, s
, strlen (s
) + 1);
1200 static size_t strLen16(const TYPE_TARGET_UINT
*s
)
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
)
1216 size_t size
= DCL_ELEM(type
);
1217 TYPE_TARGET_UINT
*p
;
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
))
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
;
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
);
1248 printChar16 (oBuf
, SPEC_CVAL (val
->etype
).v_char16
, size
);
1256 printChar16 (oBuf
, s
, strLen16 (s
) + 1);
1260 static size_t strLen32(const TYPE_TARGET_ULONG
*s
)
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
)
1275 size_t size
= DCL_ELEM(type
);
1276 TYPE_TARGET_ULONG
*p
;
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
))
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
;
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
);
1307 printChar32 (oBuf
, SPEC_CVAL (val
->etype
).v_char32
, size
);
1315 printChar32 (oBuf
, s
, strLen32 (s
) + 1);
1319 /*-----------------------------------------------------------------*/
1320 /* printIvalArray - generates code for array initialization */
1321 /*-----------------------------------------------------------------*/
1323 printIvalArray (symbol
* sym
, sym_link
* type
, initList
* ilist
, struct dbuf_s
*oBuf
, bool check
)
1327 unsigned int size
= 0;
1331 /* take care of the special case */
1332 /* array of characters can be init */
1334 /* char *p = "abc"; */
1335 if ((IS_CHAR (type
->next
) || IS_INT (type
->next
)) && ilist
->type
== INIT_NODE
)
1337 val
= list2val (ilist
, TRUE
);
1340 werrorfl (ilist
->filename
, ilist
->lineno
, E_INIT_STRUCT
, sym
->name
);
1343 if (!IS_LITERAL (val
->etype
))
1345 werrorfl (ilist
->filename
, ilist
->lineno
, E_CONST_EXPECTED
);
1348 if (IS_CHAR (type
->next
) && printIvalChar (sym
, type
, ilist
, oBuf
, SPEC_CVAL (sym
->etype
).v_char
, check
))
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
))
1354 if (IS_LONG (type
->next
) && printIvalChar32 (sym
, type
, ilist
, oBuf
, SPEC_CVAL (sym
->etype
).v_char32
, check
))
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
);
1364 werrorfl (ilist
->init
.deep
->filename
, ilist
->init
.deep
->lineno
, E_INIT_STRUCT
, sym
->name
);
1367 if (!IS_LITERAL (val
->etype
))
1369 werrorfl (ilist
->init
.deep
->filename
, ilist
->init
.deep
->lineno
, E_CONST_EXPECTED
);
1372 if (IS_CHAR (type
->next
) && printIvalChar (sym
, type
, ilist
->init
.deep
, oBuf
, SPEC_CVAL (sym
->etype
).v_char
, check
))
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
))
1378 if (IS_LONG (type
->next
) && printIvalChar32 (sym
, type
, ilist
->init
.deep
, oBuf
, SPEC_CVAL (sym
->etype
).v_char32
, check
))
1383 /* not the special case */
1384 if (ilist
->type
!= INIT_DEEP
)
1386 werrorfl (ilist
->filename
, ilist
->lineno
, E_INIT_STRUCT
, sym
->name
);
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
);
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
);
1409 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", 0);
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
);
1420 DCL_ELEM (type
) = size
;
1426 /*-----------------------------------------------------------------*/
1427 /* printIvalFuncPtr - generate initial value for function pointers */
1428 /*-----------------------------------------------------------------*/
1430 printIvalFuncPtr (sym_link
* type
, initList
* ilist
, struct dbuf_s
*oBuf
)
1437 val
= list2val (ilist
, TRUE
);
1439 val
= valCastLiteral (type
, 0.0, 0);
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)
1452 werrorfl (ilist
->filename
, ilist
->lineno
, E_INCOMPAT_TYPES
);
1454 werror (E_INCOMPAT_TYPES
);
1455 printFromToType (val
->type
, type
);
1457 printIvalCharPtr (NULL
, type
, val
, oBuf
);
1461 /* now generate the name */
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
);
1487 printPointerType (oBuf
, name
);
1490 else if (size
== BFUNCPTRSIZE
)
1492 _printPointerType (oBuf
, name
, size
);
1493 dbuf_printf (oBuf
, "\n");
1497 wassertl (0, "Invalid function pointer size.");
1503 /*--------------------------------------------------------------------*/
1504 /* printIvalCharPtr - generates initial values for character pointers */
1505 /*--------------------------------------------------------------------*/
1507 printIvalCharPtr (symbol
* sym
, sym_link
* type
, value
* val
, struct dbuf_s
*oBuf
)
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
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
);
1540 printPointerType (oBuf
, val
->name
);
1542 else if (size
== GPTRSIZE
)
1545 if (IS_PTR (val
->type
))
1547 type
= DCL_TYPE (val
->type
);
1551 type
= PTR_TYPE (SPEC_OCLS (val
->etype
));
1553 if (val
->sym
&& val
->sym
->isstrlit
)
1555 // this is a literal string
1558 printGPointerType (oBuf
, val
->name
, sym
->name
, type
);
1562 fprintf (stderr
, "*** internal error: unknown size in " "printIvalCharPtr.\n");
1567 // these are literals assigned to pointers
1571 dbuf_tprintf (oBuf
, "\t!dbs\n", aopLiteral (val
, 0));
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));
1584 dbuf_tprintf (oBuf
, "\t.byte %s,%s\n", aopLiteral (val
, 1), aopLiteral (val
, 0));
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
));
1597 dbuf_printf (oBuf
, "\t.byte %s,%s,%s\n", aopLiteralGptr (sym
->name
, val
), aopLiteral (val
, 1), aopLiteral (val
, 0));
1601 if (port
->little_endian
)
1602 dbuf_printf (oBuf
, "\t.byte %s,%s,%s\n", aopLiteral (val
, 0), aopLiteral (val
, 1), aopLiteral (val
, 2));
1604 dbuf_printf (oBuf
, "\t.byte %s,%s,%s\n", aopLiteral (val
, 2), aopLiteral (val
, 1), aopLiteral (val
, 0));
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
));
1621 dbuf_printf (oBuf
, ",%s\n", aopLiteral (val
, 3));
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
));
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));
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));
1641 dbuf_printf (oBuf
, "\t.byte %s,%s,%s,%s\n",
1642 aopLiteral (val
, 3), aopLiteral (val
, 2), aopLiteral (val
, 1), aopLiteral (val
, 0));
1651 if (!noInit
&& val
->sym
&& val
->sym
->isstrlit
&& !isinSet (statsg
->syms
, val
->sym
))
1653 addSet (&statsg
->syms
, val
->sym
);
1659 /*-----------------------------------------------------------------*/
1660 /* printIvalPtr - generates initial value for pointers */
1661 /*-----------------------------------------------------------------*/
1663 printIvalPtr (symbol
*sym
, sym_link
*type
, initList
*ilist
, struct dbuf_s
*oBuf
)
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
);
1679 if (!(val
= initPointer (ilist
, type
, 1)))
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
))
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
))
1703 dbuf_tprintf (oBuf
, "\t!db !constbyte\n", (unsigned int) ulFromVal (val
) & 0xff);
1706 if (port
->use_dw_for_init
)
1707 dbuf_tprintf (oBuf
, "\t!dws\n", aopLiteralLong (val
, 0, 2));
1708 else if (port
->little_endian
)
1711 dbuf_tprintf (oBuf
, "\tret %s\n\tret %s\n", aopLiteral (val
, 0), aopLiteral (val
, 1));
1713 dbuf_tprintf (oBuf
, "\t.byte %s,%s\n", aopLiteral (val
, 0), aopLiteral (val
, 1));
1716 dbuf_tprintf (oBuf
, "\t.byte %s,%s\n", aopLiteral (val
, 1), aopLiteral (val
, 0));
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));
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
));
1729 dbuf_printf (oBuf
, ",%s\n", aopLiteral (val
, 2));
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));
1735 wassertl(0, "Printing pointer of invalid size");
1738 wassertl(0, "Printing pointer of invalid size");
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
);
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
);
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
))));
1779 /*-----------------------------------------------------------------*/
1780 /* printIval - generates code for initial value */
1781 /*-----------------------------------------------------------------*/
1783 printIval (symbol
* sym
, sym_link
* type
, initList
* ilist
, struct dbuf_s
*oBuf
, bool check
)
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/ {} */
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
);
1813 /* if this is an array */
1814 if (IS_ARRAY (type
))
1816 printIvalArray (sym
, type
, ilist
, oBuf
, check
);
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
);
1832 ilist
= ilist
->init
.deep
;
1836 // Give up here, to avoid reading invalid memory below.
1837 if (ilist
->init
.node
->isError
)
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
1852 else if (IS_CODEPTR (type
) && IS_FUNC (type
->next
)) /* function pointer */
1855 werrorfl (ilist
->filename
, ilist
->lineno
, E_INCOMPAT_TYPES
);
1857 werror (E_INCOMPAT_TYPES
);
1858 printFromToType (itype
, type
->next
);
1862 werrorfl (ilist
->filename
, ilist
->lineno
, E_TYPE_MISMATCH
, "assignment", " ");
1863 printFromToType (itype
, type
);
1869 /* if this is a pointer */
1872 printIvalPtr (sym
, type
, ilist
, oBuf
);
1876 /* if type is SPECIFIER */
1879 printIvalType (sym
, type
, ilist
, oBuf
);
1884 /*-----------------------------------------------------------------*/
1885 /* emitStaticSeg - emitcode for the static segment */
1886 /*-----------------------------------------------------------------*/
1888 emitStaticSeg (memmap
*map
, struct dbuf_s
*oBuf
)
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
)
1906 /* eliminate redundant __str_%d (generated in stringToSymbol(), SDCCast.c) */
1907 if (!isinSet (tmpSet
, sym
))
1912 for (p
= setFirstItem (ccpStr
); p
; p
= setNextItem (ccpStr
))
1913 if (strcmp (p
, sym
->name
) == 0)
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
)
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
));
1937 int size
= getSize (sym
->type
);
1941 werrorfl (sym
->fileDef
, sym
->lineDef
, E_UNKNOWN_SIZE
, sym
->name
);
1943 /* if it has an initial value */
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
);
1954 emitDebugSym (oBuf
, sym
);
1955 dbuf_printf (oBuf
, " == .\n");
1957 dbuf_printf (oBuf
, "%s:\n", sym
->rname
);
1959 resolveIvalSym (sym
->ival
, sym
->type
);
1960 printIval (sym
, sym
->type
, sym
->ival
, oBuf
, (map
!= xinit
&& map
!= initializer
));
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
);
1973 {//printf("no ival.\n");
1974 /* allocate space */
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);
1997 if (options
.const_seg
)
1998 dbuf_tprintf(oBuf
, "\t!areacode\n", options
.code_seg
);
2002 dbuf_printf (oBuf
, "%s:\n", sym
->rname
);
2003 dbuf_tprintf (oBuf
, "\t!ds\n", (unsigned int) size
& 0xffff);
2010 deleteSet (&tmpSet
);
2014 for (p
= setFirstItem (ccpStr
); p
; p
= setNextItem (ccpStr
))
2017 deleteSet (&ccpStr
);
2021 /*-----------------------------------------------------------------*/
2022 /* emitMaps - emits the code for the data portion the code */
2023 /*-----------------------------------------------------------------*/
2028 int publicsfr
= TARGET_IS_MCS51
|| TARGET_PDK_LIKE
; /* Ideally, this should be true for all */
2029 /* ports but let's be conservative - EEP */
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
)
2039 dbuf_tprintf (&nm
->map
->oBuf
, "\t!areacode\n", nm
->map
->sname
);
2040 emitStaticSeg (nm
->map
, &nm
->map
->oBuf
);
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
);
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
);
2066 dbuf_tprintf (&code
->oBuf
, "\t!area\n", xinit
->sname
);
2067 emitStaticSeg (xinit
, &code
->oBuf
);
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
);
2079 /*-----------------------------------------------------------------*/
2080 /* flushStatics - flush all currently defined statics out to file */
2081 /* and delete. Temporary function */
2082 /*-----------------------------------------------------------------*/
2086 if (!setFirstItem (statsg
->syms
))
2089 if (options
.const_seg
)
2090 dbuf_tprintf (&code
->oBuf
, "\t!area\n", options
.const_seg
);
2092 emitStaticSeg (statsg
, codeOutBuf
);
2095 if (options
.const_seg
)
2096 dbuf_tprintf (&code
->oBuf
, "\t!area\n", options
.code_seg
);
2099 /*-----------------------------------------------------------------*/
2100 /* createInterruptVect - creates the interrupt vector */
2101 /*-----------------------------------------------------------------*/
2103 createInterruptVect (struct dbuf_s
*vBuf
)
2105 mainf
= newSymbol ("main", 0);
2108 /* only if the main function exists */
2109 if (!(mainf
= findSymWithLevel (SymbolTab
, mainf
)))
2111 if (!options
.cc_only
&& !options
.no_assemble
&& !options
.c1mode
)
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
)
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. */
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 /*-----------------------------------------------------------------*/
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 /*-----------------------------------------------------------------*/
2161 printPublics (FILE * afile
)
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 /*-----------------------------------------------------------------*/
2185 printExterns (FILE * afile
)
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 /*-----------------------------------------------------------------*/
2201 emitOverlay (struct dbuf_s
*aBuf
)
2205 /* for each of the sets in the overlay segment do */
2206 for (ovrset
= setFirstItem (ovrSetSets
); ovrset
; ovrset
= setNextItem (ovrSetSets
))
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
))
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
)
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
2237 if (IS_FUNC (sym
->type
))
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 */
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
));
2254 int size
= getSize (sym
->type
);
2258 werrorfl (sym
->fileDef
, sym
->lineDef
, E_UNKNOWN_SIZE
, sym
->name
);
2260 /* print extra debug info if required */
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 /*-----------------------------------------------------------------*/
2282 struct dbuf_s ovrBuf
;
2283 struct dbuf_s asmFileName
;
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 */
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 */
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
);
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?
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
);
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
);
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");
2398 fprintf (asmFile
, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
2400 fprintf (asmFile
, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
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 */
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 */
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 */
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 */
2475 fprintf (asmFile
, "%s", iComments2
);
2476 fprintf (asmFile
, "; absolute%s ram data\n", mcs51_like
? " internal" : "");
2477 fprintf (asmFile
, "%s", iComments2
);
2479 dbuf_write_and_destroy (&d_abs
->oBuf
, asmFile
);
2481 dbuf_write_and_destroy (&i_abs
->oBuf
, asmFile
);
2484 /* copy the bit segment */
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 */
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 */
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 */
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
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
);
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
);
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");
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 */
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");
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
);
2640 /* will return 1 if the string is a part
2641 of a target specific keyword */
2643 isTargetKeyword (const char *s
)
2647 if (port
->keywords
== NULL
)
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)
2659 else if (strcmp(port
->keywords
[i
],s
+2) == 0)
2665 for (i
= 0 ; port
->keywords
[i
] ; i
++ )
2667 if (strcmp(port
->keywords
[i
],s
) == 0)