X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCglue.c;h=1cb787fc7ed1136b9d8642212e8c2a22a1b8fec2;hb=c3bf2d8fd69b69dcf7564d3e24cd045d2bcc385c;hp=209f5d8fa2ff7dbefe1c7cf6491e1f3cdb78ab1a;hpb=19ff45b2f8037758e965b1f7f920064985130b4f;p=fw%2Fsdcc diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 209f5d8f..1cb787fc 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -154,9 +154,11 @@ aopLiteral (value * val, int offset) static void emitRegularMap (memmap * map, bool addPublics, bool arFlag) { - symbol *sym, *symIval; + symbol *sym; ast *ival = NULL; - memmap *segment; + + if (!map) + return; if (addPublics) { @@ -170,16 +172,16 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) else tfprintf (map->oFile, "\t!area\n", map->sname); } - - /* print the area name */ + for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { + symbol *newSym=NULL; /* if extern then add it into the extern list */ if (IS_EXTERN (sym->etype)) { - addSetHead (&externs, sym); + addSetHead (&externs, sym); continue; } @@ -228,35 +230,23 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); } - /* if is has an absolute address then generate - an equate for this no need to allocate space */ - if (SPEC_ABSA (sym->etype)) - { - if (options.debug) { - fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); - } - fprintf (map->oFile, "%s\t=\t0x%04x\n", - sym->rname, - SPEC_ADDR (sym->etype)); - } - else - { - /* allocate space */ - if (options.debug) { - fprintf (map->oFile, "==.\n"); - } - if (IS_STATIC (sym->etype)) - tfprintf (map->oFile, "!slabeldef\n", sym->rname); - else - tfprintf (map->oFile, "!labeldef\n", sym->rname); - tfprintf (map->oFile, "\t!ds\n", - (unsigned int) getSize (sym->type) & 0xffff); - } - /* if it has an initial value then do it only if it is a global variable */ - if (sym->ival && sym->level == 0) - { + if (sym->ival && sym->level == 0) { + if (SPEC_OCLS(sym->etype)==xidata) { + // create a new "XINIT (CODE)" symbol, that will be emitted later + newSym=copySymbol (sym); + SPEC_OCLS(newSym->etype)=xinit; + sprintf (newSym->name, "__xinit_%s", sym->name); + sprintf (newSym->rname,"__xinit_%s", sym->rname); + SPEC_CONST(newSym->etype)=1; + SPEC_STAT(newSym->etype)=1; + resolveIvalSym(newSym->ival); + + // add it to the "XINIT (CODE)" segment + addSet(&xinit->syms, newSym); + sym->ival=NULL; + } else { if (IS_AGGREGATE (sym->type)) { ival = initAggregates (sym, sym->ival, NULL); } else { @@ -265,29 +255,61 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) sym->name, sym->lineDef); } ival = newNode ('=', newAst_VALUE (symbolVal (sym)), - decorateType (resolveSymbols (list2expr (sym->ival)))); + decorateType (resolveSymbols (list2expr (sym->ival)))); } codeOutFile = statsg->oFile; - allocInfo = 0; - - // set ival's lineno to where the symbol was defined - if (ival) ival->lineno=sym->lineDef; - eBBlockFromiCode (iCodeFromAst (ival)); - allocInfo = 1; - - /* if the ival is a symbol assigned to an aggregate, - (bug #458099 -> #462479) - we don't need it anymore, so delete it from its segment */ - if (sym->ival->type == INIT_NODE && - IS_AST_SYM_VALUE(sym->ival->init.node) && - IS_AGGREGATE (sym->type) ) { - symIval=AST_SYMBOL(sym->ival->init.node); - segment = SPEC_OCLS (symIval->etype); - deleteSetItem (&segment->syms, symIval); + + if (ival) { + // set ival's lineno to where the symbol was defined + setAstLineno (ival, lineno=sym->lineDef); + // check if this is not a constant expression + if (!constExprTree(ival)) { + werror (E_CONST_EXPECTED, "found expression"); + // but try to do it anyway + } + allocInfo = 0; + eBBlockFromiCode (iCodeFromAst (ival)); + allocInfo = 1; } + } + sym->ival = NULL; + } - sym->ival = NULL; + /* if is has an absolute address then generate + an equate for this no need to allocate space */ + if (SPEC_ABSA (sym->etype)) + { + char *equ="="; + if (options.debug) { + fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); + } + if (TARGET_IS_XA51) { + if (map==sfr) { + equ="sfr"; + } else if (map==bit || map==sfrbit) { + equ="bit"; + } + } + fprintf (map->oFile, "%s\t%s\t0x%04x\n", + sym->rname, equ, + SPEC_ADDR (sym->etype)); + } + else { + int size = getSize (sym->type); + if (size==0) { + werror(E_UNKNOWN_SIZE,sym->name); + } + /* allocate space */ + if (options.debug) { + fprintf (map->oFile, "==.\n"); } + if (IS_STATIC (sym->etype)) + tfprintf (map->oFile, "!slabeldef\n", sym->rname); + else + tfprintf (map->oFile, "!labeldef\n", sym->rname); + tfprintf (map->oFile, "\t!ds\n", + (unsigned int) size & 0xffff); + } } } @@ -350,10 +372,10 @@ initPointer (initList * ilist) (&some_struct)->element */ if (IS_AST_OP (expr->left) && expr->left->opval.op == PTR_OP && - IS_ADDRESS_OF_OP (expr->left->left)) - return valForStructElem (expr->left->left->left, - expr->left->right); - + IS_ADDRESS_OF_OP (expr->left->left)) { + return valForStructElem (expr->left->left->left, + expr->left->right); + } } /* case 3. (((char *) &a) +/- constant) */ if (IS_AST_OP (expr) && @@ -535,7 +557,15 @@ printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile) werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef); } - val = list2val (ilist); + if (!(val = list2val (ilist))) { + // assuming a warning has been thrown + val=constVal("0"); + } + + if (val->type != type) { + val = valCastLiteral(type, floatFromVal(val)); + } + switch (getSize (type)) { case 1: if (!val) @@ -694,12 +724,16 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, /* take care of the special case */ /* array of characters can be init */ /* by a string */ - if (IS_CHAR (type->next)) + if (IS_CHAR (type->next)) { + if (!IS_LITERAL(list2val(ilist)->etype)) { + werror (W_INIT_WRONG); + return; + } if (printIvalChar (type, (ilist->type == INIT_DEEP ? ilist->init.deep : ilist), oFile, SPEC_CVAL (sym->etype).v_char)) return; - + } /* not the special case */ if (ilist->type != INIT_DEEP) { @@ -750,6 +784,16 @@ printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile) int dLvl = 0; val = list2val (ilist); + + if (IS_LITERAL(val->etype)) { + if (compareType(type,val->etype)==0) { + werror (E_INCOMPAT_TYPES); + printFromToType (val->type, type); + } + printIvalCharPtr (NULL, type, val, oFile); + return; + } + /* check the types */ if ((dLvl = compareType (val->type, type->next)) <= 0) { @@ -835,7 +879,7 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) } else { - /* What is this case? Are these pointers? */ + // these are literals assigned to pointers switch (size) { case 1: @@ -849,9 +893,25 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) aopLiteral (val, 0), aopLiteral (val, 1)); break; case 3: - /* PENDING: 0x02 or 0x%02x, CDATA? */ - fprintf (oFile, "\t.byte %s,%s,#0x02\n", - aopLiteral (val, 0), aopLiteral (val, 1)); + if (IS_GENPTR(type) && floatFromVal(val)!=0) { + // non-zero mcs51 generic pointer + werror (E_LITERAL_GENERIC); + } + fprintf (oFile, "\t.byte %s,%s,%s\n", + aopLiteral (val, 0), + aopLiteral (val, 1), + aopLiteral (val, 2)); + break; + case 4: + if (IS_GENPTR(type) && floatFromVal(val)!=0) { + // non-zero ds390 generic pointer + werror (E_LITERAL_GENERIC); + } + fprintf (oFile, "\t.byte %s,%s,%s,%s\n", + aopLiteral (val, 0), + aopLiteral (val, 1), + aopLiteral (val, 2), + aopLiteral (val, 3)); break; default: assert (0); @@ -988,9 +1048,7 @@ emitStaticSeg (memmap * map, FILE * out) { symbol *sym; - /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */ - if (!out) - out = code->oFile; + /* fprintf(out, "\t.area\t%s\n", map->sname); */ /* for all variables in this segment do */ for (sym = setFirstItem (map->syms); sym; @@ -1004,7 +1062,9 @@ emitStaticSeg (memmap * map, FILE * out) /* if it is not static add it to the public table */ if (!IS_STATIC (sym->etype)) - addSetHead (&publics, sym); + { + addSetHead (&publics, sym); + } /* print extra debug info if required */ if (options.debug) { @@ -1047,18 +1107,22 @@ emitStaticSeg (memmap * map, FILE * out) printIval (sym, sym->type, sym->ival, out); noAlloc--; } - else - { + else { /* allocate space */ + int size = getSize (sym->type); + + if (size==0) { + werror(E_UNKNOWN_SIZE,sym->name); + } fprintf (out, "%s:\n", sym->rname); /* special case for character strings */ if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) && SPEC_CVAL (sym->etype).v_char) - printChar (out, - SPEC_CVAL (sym->etype).v_char, - strlen (SPEC_CVAL (sym->etype).v_char) + 1); + printChar (out, + SPEC_CVAL (sym->etype).v_char, + strlen (SPEC_CVAL (sym->etype).v_char) + 1); else - tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); + tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff); } } } @@ -1077,12 +1141,19 @@ emitMaps () emitRegularMap (idata, TRUE, TRUE); emitRegularMap (bit, TRUE, FALSE); emitRegularMap (xdata, TRUE, TRUE); + if (port->genXINIT) { + emitRegularMap (xidata, TRUE, TRUE); + } emitRegularMap (sfr, FALSE, FALSE); emitRegularMap (sfrbit, FALSE, FALSE); emitRegularMap (home, TRUE, FALSE); emitRegularMap (code, TRUE, FALSE); emitStaticSeg (statsg, code->oFile); + if (port->genXINIT) { + tfprintf (code->oFile, "\t!area\n", xinit->sname); + emitStaticSeg (xinit, code->oFile); + } inInitMode--; } @@ -1131,7 +1202,6 @@ createInterruptVect (FILE * vFile) if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts))) { /* "generic" interrupt table header (if port doesn't specify one). - * Look suspiciously like 8051 code to me... */ @@ -1203,7 +1273,7 @@ printExterns (FILE * afile) for (sym = setFirstItem (externs); sym; sym = setNextItem (externs)) - tfprintf (afile, "\t!global\n", sym->rname); + tfprintf (afile, "\t!extern\n", sym->rname); } /*-----------------------------------------------------------------*/ @@ -1226,11 +1296,6 @@ emitOverlay (FILE * afile) if (elementsInSet (ovrset)) { - /* this dummy area is used to fool the assembler - otherwise the assembler will append each of these - declarations into one chunk and will not overlay - sad but true */ - fprintf (afile, "\t.area _DUMMY\n"); /* output the area informtion */ fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */ } @@ -1238,8 +1303,7 @@ emitOverlay (FILE * afile) for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset)) { - - /* if extern then add it to the publics tabledo nothing */ + /* if extern then it is in the publics table: do nothing */ if (IS_EXTERN (sym->etype)) continue; @@ -1255,7 +1319,9 @@ emitOverlay (FILE * afile) and addPublics allowed then add it to the public set */ if ((sym->_isparm && !IS_REGPARM (sym->etype)) && !IS_STATIC (sym->etype)) - addSetHead (&publics, sym); + { + addSetHead (&publics, sym); + } /* if extern then do nothing or is a function then do nothing */ @@ -1293,16 +1359,20 @@ emitOverlay (FILE * afile) sym->rname, SPEC_ADDR (sym->etype)); } - else - { + else { + int size = getSize(sym->type); + + if (size==0) { + werror(E_UNKNOWN_SIZE,sym->name); + } if (options.debug) - fprintf (afile, "==.\n"); + fprintf (afile, "==.\n"); /* allocate space */ tfprintf (afile, "!labeldef\n", sym->rname); tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); - } - + } + } } } @@ -1394,10 +1464,12 @@ glue () /* create the overlay segments */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; overlayable items in internal ram \n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, ovrFile); + if (overlay) { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; overlayable items in internal ram \n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, ovrFile); + } /* create the stack segment MOF */ if (mainf && IFFUNC_HASBODY(mainf->type)) @@ -1410,10 +1482,12 @@ glue () } /* create the idata segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; indirectly addressable internal ram data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, idata->oFile); + if (idata) { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; indirectly addressable internal ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, idata->oFile); + } /* copy the bit segment */ fprintf (asmFile, "%s", iComments2); @@ -1438,6 +1512,12 @@ glue () fprintf (asmFile, "%s", iComments2); copyFile (asmFile, xdata->oFile); + /* copy xternal initialized ram data */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; external initialized ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, xidata->oFile); + /* copy the interrupt vector table */ if (mainf && IFFUNC_HASBODY(mainf->type)) { @@ -1494,6 +1574,11 @@ glue () fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n"); fprintf (asmFile, "__sdcc_init_data:\n"); + // if the port can copy the XINIT segment to XISEG + if (port->genXINIT) { + port->genXINIT(asmFile); + } + } copyFile (asmFile, statsg->oFile); @@ -1543,6 +1628,9 @@ glue () } copyFile (asmFile, code->oFile); + if (port->genAssemblerEnd) { + port->genAssemblerEnd(asmFile); + } fclose (asmFile); applyToSet (tmpfileSet, closeTmpFiles); applyToSet (tmpfileNameSet, rmTmpFiles);