X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fglue.c;h=50b9ba17e5daa3bfa708b12a927f1173d2c53e6e;hb=9575f3d72c4cf6b0a0068965d4bd01a1f8e5bef7;hp=1ba22eee9fa9bdec2cd3c24769836239402ab860;hpb=c6fc407e1e4bf2a52848dd924a9b10d6200874ec;p=fw%2Fsdcc diff --git a/src/pic/glue.c b/src/pic/glue.c index 1ba22eee..50b9ba17 100644 --- a/src/pic/glue.c +++ b/src/pic/glue.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- - SDCCglue.c - glues everything we have done together into one file. + glue.c - glues everything we have done together into one file. Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) This program is free software; you can redistribute it and/or modify it @@ -22,123 +22,49 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include "../common.h" -#include -#include "ralloc.h" -#include "pcode.h" -#include "newalloc.h" -#include "gen.h" -#include "main.h" -#include "device.h" +#include "glue.h" #include "dbuf_string.h" +#include "device.h" +#include "gen.h" +#include "main.h" -#ifdef WORDS_BIGENDIAN -#define _ENDIAN(x) (3-x) -#else -#define _ENDIAN(x) (x) -#endif - -#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff) -#define IS_GLOBAL(sym) ((sym)->level == 0) - -extern symbol *interrupts[256]; -static void showAllMemmaps(FILE *of); // XXX: emits initialized symbols -extern int noAlloc; +/* + * Imports + */ extern set *publics; extern set *externs; -extern unsigned maxInterrupts; extern symbol *mainf; -extern char *VersionString; extern struct dbuf_s *codeOutBuf; -extern char *iComments1; -extern char *iComments2; -//extern void emitStaticSeg (memmap * map); -set *pic14_localFunctions = NULL; -extern DEFSETFUNC (closeTmpFiles); -extern DEFSETFUNC (rmTmpFiles); +extern void initialComments (FILE *afile); +extern operand *operandFromAst (ast *tree, int lvl); +extern value *initPointer (initList *ilist, sym_link *toType); -extern void AnalyzeBanking (void); -extern void ReuseReg(void); -extern void InlinepCode(void); -extern void writeUsedRegs(FILE *); -extern void initialComments (FILE * afile); -extern void printPublics (FILE * afile); - -extern void printChar (FILE * ofile, char *s, int plen); -void pCodeInitRegisters(void); -int getConfigWord(int address); -int getHasSecondConfigReg(void); -void pic14_debugLogClose(void); // from ralloc.c - -char *udata_section_name=0; // FIXME Temporary fix to change udata section name -- VR +set *pic14_localFunctions = NULL; int pic14_hasInterrupt = 0; // Indicates whether to emit interrupt handler or not -/* dbufs for initialized data (idata and code sections), - * extern, and global declarations */ -struct dbuf_s *ivalBuf, *extBuf, *gloBuf, *gloDefBuf; - -static set *emitted = NULL; int pic14_stringInSet(const char *str, set **world, int autoAdd); -/*-----------------------------------------------------------------*/ -/* aopLiteral - string from a literal value */ -/*-----------------------------------------------------------------*/ -unsigned int pic14aopLiteral (value *val, int offset) -{ - union { - float f; - unsigned char c[4]; - } fl; - - /* if it is a float then it gets tricky */ - /* otherwise it is fairly simple */ - if (!IS_FLOAT(val->type)) { - unsigned long v = ulFromVal (val); - - return ( (v >> (offset * 8)) & 0xff); - } - /* it is type float */ - fl.f = (float) floatFromVal(val); #ifdef WORDS_BIGENDIAN - return fl.c[3-offset]; +#define _ENDIAN(x) (3-x) #else - return fl.c[offset]; +#define _ENDIAN(x) (x) #endif -} +#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff) +#define IS_GLOBAL(sym) ((sym)->level == 0) +#define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype)) -#if 0 -static int -is_valid_identifier( const char *name ) -{ - char a; - if (!name) return 0; - a = *name; - - /* only accept [a-zA-Z_][a-zA-Z0-9_] */ - if (!((a >= 'a' && a <= 'z') - || (a >= 'A' && a <= 'z') - || (a == '_'))) - return 0; - - name++; - while ((a = *name++)) - { - if (!((a >= 'a' && a <= 'z') - || (a >= 'A' && a <= 'Z') - || (a >= '0' && a <= '9') - || (a == '_'))) - return 0; - } // while - - /* valid identifier */ - return 1; -} -#endif +/* dbufs for initialized data (idata and code sections), + * extern, and global declarations */ +static struct dbuf_s *ivalBuf, *extBuf, *gloBuf, *gloDefBuf; + +static set *emitted = NULL; + +static void showAllMemmaps (FILE *of); // XXX: emits initialized symbols static void emitPseudoStack(struct dbuf_s *oBuf, struct dbuf_s *oBufExt) @@ -210,8 +136,6 @@ emitIfNew(struct dbuf_s *oBuf, set **emitted, const char *fmt, return (!wasPresent); } -#define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype)) -extern int IS_CONFIG_ADDRESS( int addr ); static void pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf) { @@ -306,668 +230,9 @@ pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf) } // for i } -#if 0 -/*-----------------------------------------------------------------*/ -/* emitRegularMap - emit code for maps with no special cases */ -/*-----------------------------------------------------------------*/ -static void -pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag) -{ - symbol *sym; - int bitvars = 0;; - - /* print the area name */ - if (addPublics) - dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname); - - for (sym = setFirstItem (map->syms); sym; - sym = setNextItem (map->syms)) { - - //printf("%s\n",sym->name); - - /* ignore if config word */ - if (SPEC_ABSA(sym->etype) - && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) - continue; - - /* if extern then add it into the extern list */ - if (IS_EXTERN (sym->etype)) { - addSetHead (&externs, sym); - continue; - } - - /* if allocation required check is needed - then check if the symbol really requires - allocation only for local variables */ - if (arFlag && !IS_AGGREGATE (sym->type) && - !(sym->_isparm && !IS_REGPARM (sym->etype)) && - !sym->allocreq && sym->level) - continue; - - /* if global variable & not static or extern - and addPublics allowed then add it to the public set */ - if ((sym->level == 0 || - (sym->_isparm && !IS_REGPARM (sym->etype))) && - addPublics && - !IS_STATIC (sym->etype)) - { - //fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name ); - addSetHead (&publics, sym); - } - - // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs() - if (sym->_isparm) - continue; - /* if extern then do nothing or is a function - then do nothing */ - if (IS_FUNC (sym->type)) - continue; -#if 0 - /* print extra debug info if required */ - if (options.debug || sym->level == 0) - { - if (!sym->level) /* global */ - if (IS_STATIC (sym->etype)) - dbuf_printf (&map->oBuf, "F%s_", moduleName); /* scope is file */ - else - dbuf_printf (&map->oBuf, "G_"); /* scope is global */ - else - /* symbol is local */ - dbuf_printf (&map->oBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-")); - dbuf_printf (&map->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block); - } -#endif - /* absolute symbols are handled in pic14_constructAbsMap */ - if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym)) - continue; - - /* if it has an absolute address then generate - an equate for this no need to allocate space */ - if (0 && SPEC_ABSA (sym->etype)) - { - //if (options.debug || sym->level == 0) - //dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype)); - - dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n", - sym->rname, - SPEC_ADDR (sym->etype)); - } - else - { - /* allocate space */ - - /* If this is a bit variable, then allocate storage after 8 bits have been declared */ - /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */ - /* by grouping the bits together into groups of 8 and storing them in the normal ram. */ - if (IS_BITVAR (sym->etype)) - { - bitvars++; - } - else - { - if (!sym->ival) { - emitSymbol (&map->oBuf, - sym->rname, - NULL, - getSize (sym->type) & 0xffff, - SPEC_ABSA(sym->etype) - ? SPEC_ADDR(sym->etype) - : -1, - 0, - 0); - } - /* - { - int i, size; - - if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) - { - for (i = 1; i < size; i++) - dbuf_printf (&map->oBuf, "\t%s_%d\n", sym->rname, i); - } - } - */ - } - //dbuf_printf (&map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff); - } - - /* if it has a initial value then do it only if - it is a global variable */ - if (sym->ival) { - /* mark symbol as already defined */ - pic14_stringInSet(sym->name, &emitted, 1); - pic14_stringInSet(sym->rname, &emitted, 1); - } -#if 0 - /* if it has a initial value then do it only if - it is a global variable */ - if (sym->ival && sym->level == 0) { - ast *ival = NULL; - - if (IS_AGGREGATE (sym->type)) - ival = initAggregates (sym, sym->ival, NULL); - else - ival = newNode ('=', newAst_VALUE(symbolVal (sym)), - decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE)); - codeOutBuf = &statsg->oBuf; - GcurMemmap = statsg; - eBBlockFromiCode (iCodeFromAst (ival)); - sym->ival = NULL; - } -#endif - } -} -#endif - - -#if 0 -/*-----------------------------------------------------------------*/ -/* printIvalType - generates ival for int/char */ -/*-----------------------------------------------------------------*/ -static void -printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb) -{ - value *val; - unsigned long ulval; - - //fprintf(stderr, "%s\n",__FUNCTION__); - - /* if initList is deep */ - if (ilist->type == INIT_DEEP) - ilist = ilist->init.deep; - - if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) { - werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef); - } - - if (!(val = list2val (ilist))) { - // assuming a warning has been thrown - val = constCharVal (0); - } - - if (val->type != type) { - val = valCastLiteral(type, floatFromVal(val)); - } - - if(val) - ulval = ulFromVal (val); - else - ulval =0; - - switch (getSize (type)) { - case 1: - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0)))); - break; - - case 2: - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0)))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1)))); - break; - - case 4: - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0)))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1)))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2)))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3)))); - break; - } -} - -/*-----------------------------------------------------------------*/ -/* printIvalBitFields - generate initializer for bitfields */ -/*-----------------------------------------------------------------*/ -static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb ) -{ - value *val ; - symbol *lsym = *sym; - initList *lilist = *ilist ; - unsigned long ival = 0; - int size =0; - - - do { - unsigned long i; - val = list2val(lilist); - if (size) { - if (SPEC_BLEN(lsym->etype) > 8) { - size += ((SPEC_BLEN (lsym->etype) / 8) + - (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0)); - } - } else { - size = ((SPEC_BLEN (lsym->etype) / 8) + - (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0)); - } - i = ulFromVal (val); - i <<= SPEC_BSTR (lsym->etype); - ival |= i; - if (! ( lsym->next && - (IS_BITFIELD(lsym->next->type)) && - (SPEC_BSTR(lsym->next->etype)))) break; - lsym = lsym->next; - lilist = lilist->next; - } while (1); - switch (size) { - case 1: - //tfprintf (oFile, "\t!db !constbyte\n",ival); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival))); - break; - - case 2: - //tfprintf (oFile, "\t!dw !constword\n",ival); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival))); - break; - case 4: - //tfprintf (oFile, "\t!db !constword,!constword\n",(ival >> 8) & 0xffff, (ival & 0xffff)); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>24))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>16))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8))); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival))); - break; - } - *sym = lsym; - *ilist = lilist; -} - -/*-----------------------------------------------------------------*/ -/* printIvalStruct - generates initial value for structures */ -/*-----------------------------------------------------------------*/ -static void printIvalStruct (symbol * sym, sym_link * type, initList * ilist, pBlock *pb) -{ - symbol *sflds; - initList *iloop = NULL; - - sflds = SPEC_STRUCT (type)->fields; - - if (ilist) { - if (ilist->type != INIT_DEEP) { - werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name); - return; - } - - iloop = ilist->init.deep; - } - - for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) { - if (IS_BITFIELD(sflds->type)) { - printIvalBitFields(&sflds,&iloop,pb); - } else { - printIval (sym, sflds->type, iloop, pb); - } - } - if (iloop) { - werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name); - } - return; -} - -/*-----------------------------------------------------------------*/ -/* printIvalChar - generates initital value for character array */ -/*-----------------------------------------------------------------*/ -static int -printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s) -{ - value *val; - int remain, ilen; - - if(!pb) - return 0; - - //fprintf(stderr, "%s\n",__FUNCTION__); - if (!s) - { - - val = list2val (ilist); - - /* if the value is a character string */ - if (IS_ARRAY (val->type) && IS_CHAR (val->etype)) - { - ilen = DCL_ELEM(val->type); - - if (!DCL_ELEM (type)) - DCL_ELEM (type) = ilen; - - /* emit string constant */ - for (remain = 0; remain < ilen; remain++) { - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain]))); - } - - /* fill array up to desired size */ - if ((remain = (DCL_ELEM (type) - ilen)) > 0) - while (remain--) - //tfprintf (oFile, "\t!db !constbyte\n", 0); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0))); - return 1; - } - else - return 0; - } - else { - //printChar (oFile, s, strlen (s) + 1); - - for(remain=0; remain<(int)strlen(s); remain++) { - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain]))); - //fprintf(stderr,"0x%02x ",s[remain]); - } - //fprintf(stderr,"\n"); - } - return 1; -} - -/*-----------------------------------------------------------------*/ -/* printIvalArray - generates code for array initialization */ -/*-----------------------------------------------------------------*/ -static void -printIvalArray (symbol * sym, sym_link * type, initList * ilist, - pBlock *pb) -{ - initList *iloop; - unsigned size = 0; - - if(!pb) - return; - if (ilist) { - /* take care of the special case */ - /* array of characters can be init */ - /* by a string */ - if (IS_CHAR (type->next)) { - //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__); - if (!IS_LITERAL(list2val(ilist)->etype)) { - werror (W_INIT_WRONG); - return; - } - if (printIvalChar (type, - (ilist->type == INIT_DEEP ? ilist->init.deep : ilist), - pb, SPEC_CVAL (sym->etype).v_char)) - return; - } - /* not the special case */ - if (ilist->type != INIT_DEEP) { - werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name); - return; - } - - for (iloop=ilist->init.deep; iloop; iloop=iloop->next) { - if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) { - werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name); - break; - } - printIval (sym, type->next, iloop, pb); - } - } - - if (DCL_ELEM(type)) { - // pad with zeros if needed - if (sizenext); - while (size--) { - //tfprintf (oFile, "\t!db !constbyte\n", 0); - addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0))); - } - } - } else { - // we have not been given a size, but we now know it - DCL_ELEM (type) = size; - } - - return; -} - -/*-----------------------------------------------------------------*/ -/* printIvalPtr - generates code for initial value of pointers */ -/*-----------------------------------------------------------------*/ -extern value *initPointer (initList *, sym_link *toType); - -static void -printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb) -{ - value *val; - - if (!ilist || !pb) - return; - - fprintf (stderr, "FIXME: initializers for pointers...\n"); - printTypeChain (type, stderr); - - fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type)); - fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE); - - if (ilist && (ilist->type == INIT_DEEP)) - ilist = ilist->init.deep; - - /* function pointers */ - if (IS_FUNC (type->next)) - { - assert ( !"function pointers not yet handled" ); - //printIvalFuncPtr (type, ilist, pb); - } - - if (!(val = initPointer (ilist, type))) - return; - - if (IS_CHAR (type->next)) - { - if (printIvalChar (type, ilist, pb, NULL)) return; - } - - /* check the type */ - if (compareType (type, val->type) == 0) - { - werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG); - printFromToType (val->type, type); - } - - if (IS_LITERAL (val->etype)) - { - switch (getSize (type)) - { - case 1: - fprintf (stderr, "BYTE: %i\n", (unsigned char) ulFromVal (val) & 0x00FF); - break; - case 2: - fprintf (stderr, "WORD: %i\n", (unsigned int) ulFromVal (val) & 0x00FFFF); - break; - case 3: /* gneric pointers */ - assert ( !"generic pointers not yet handled" ); - case 4: - fprintf (stderr, "LONG: %i\n", (unsigned int) ulFromVal (val) & 0x0000FFFFFFFF); - break; - default: - assert ( !"invaild size of value -- aborting" ); - } // switch - - return; - } // if (IS_LITERAL) - - /* now handle symbolic values */ - switch (getSize (type)) - { - case 1: - fprintf (stderr, "BYTE: %s", val->name); - break; - case 2: - fprintf (stderr, "WORD: %s", val->name); - break; - case 4: - fprintf (stderr, "LONG: %s", val->name); - break; - default: - assert ( !"invalid size of (symbolic) value -- aborting" ); - } // switch -} - -/*-----------------------------------------------------------------*/ -/* printIval - generates code for initial value */ -/*-----------------------------------------------------------------*/ -static void -printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb) -{ - if (!ilist || !pb) - return; - - /* if structure then */ - if (IS_STRUCT (type)) - { - //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname); - printIvalStruct (sym, type, ilist, pb); - return; - } - - /* if this is an array */ - if (IS_ARRAY (type)) - { - //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname); - printIvalArray (sym, type, ilist, pb); - return; - } - - /* if this is a pointer */ - if (IS_PTR (type)) - { - //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname); - printIvalPtr (sym, type, ilist, pb); - return; - } - - /* if type is SPECIFIER */ - if (IS_SPEC (type)) - { - //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname); - printIvalType (sym, type, ilist, pb); - return; - } -} -#endif - -#if 0 -extern void pCodeConstString(char *name, char *value); -/*-----------------------------------------------------------------*/ -/* emitStaticSeg - emitcode for the static segment */ -/*-----------------------------------------------------------------*/ -static void -pic14emitStaticSeg (memmap * map) -{ - symbol *sym; - - dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname); - - //fprintf(stderr, "%s\n",__FUNCTION__); - - /* for all variables in this segment do */ - for (sym = setFirstItem (map->syms); sym; - sym = setNextItem (map->syms)) - { - /* if extern then add it into the extern list */ - if (IS_EXTERN (sym->etype)) { - addSetHead (&externs, sym); - continue; - } - - /* if it is not static add it to the public - table */ - if (!IS_STATIC (sym->etype)) - addSetHead (&publics, sym); - - /* print extra debug info if required */ - if (options.debug || sym->level == 0) - { - if (!sym->level) - { /* global */ - if (IS_STATIC (sym->etype)) - dbuf_printf (&code->oBuf, "F%s_", moduleName); /* scope is file */ - else - dbuf_printf (&code->oBuf, "G_"); /* scope is global */ - } - else - /* symbol is local */ - dbuf_printf (&code->oBuf, "L%s_", - (sym->localof ? sym->localof->name : "-null-")); - dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block); - - } - - /* if it has an absolute address */ - if (SPEC_ABSA (sym->etype)) - { - if (options.debug || sym->level == 0) - dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype)); - - dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n", - sym->rname, - SPEC_ADDR (sym->etype)); - } - else - { - if (options.debug || sym->level == 0) - dbuf_printf (&code->oBuf, " == .\n"); - - /* if it has an initial value */ - if (sym->ival) - { -#if 0 - pBlock *pb; - - dbuf_printf (&code->oBuf, "%s:\n", sym->rname); - noAlloc++; - resolveIvalSym (sym->ival, sym->type); - //printIval (sym, sym->type, sym->ival, &code->oBuf); - pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival")); - addpBlock(pb); - addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1)); - - printIval (sym, sym->type, sym->ival, pb); - noAlloc--; -#endif - } - else - { - - /* allocate space */ - dbuf_printf (&code->oBuf, "%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) - pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char); - /*printChar (code->oFile, - SPEC_CVAL (sym->etype).v_char, - strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/ - else - dbuf_printf (&code->oBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff); - } - } - } - -} -#endif - - -#if 0 -/*-----------------------------------------------------------------*/ -/* emitMaps - emits the code for the data portion the code */ -/*-----------------------------------------------------------------*/ -static void -pic14emitMaps () -{ - pic14_constructAbsMap (&sfr->oBuf); - emitPseudoStack(&sfr->oBuf, &sfr->oBuf); -/* no special considerations for the following - data, idata & bit & xdata */ - pic14emitRegularMap (data, TRUE, TRUE); - pic14emitRegularMap (idata, TRUE, TRUE); - pic14emitRegularMap (bit, TRUE, FALSE); - pic14emitRegularMap (xdata, TRUE, TRUE); - pic14emitRegularMap (sfr, TRUE, FALSE); - pic14emitRegularMap (sfrbit, FALSE, FALSE); - pic14emitRegularMap (code, TRUE, FALSE); - pic14emitStaticSeg (statsg); - pic14emitStaticSeg (c_abs); -} -#endif - /*-----------------------------------------------------------------*/ /* createInterruptVect - creates the interrupt vector */ /*-----------------------------------------------------------------*/ -pCodeOp *popGetExternal (char *str, int isReg); static void pic14createInterruptVect (struct dbuf_s * vBuf) { @@ -1013,7 +278,7 @@ pic14initialComments (FILE * afile) { initialComments (afile); fprintf (afile, "; PIC port for the 14-bit core\n"); - fprintf (afile, iComments2); + fprintf (afile, "%s", iComments2); } @@ -1036,141 +301,6 @@ pic14_stringInSet(const char *str, set **world, int autoAdd) return 0; } -#if 0 -static int -pic14_emitSymbolIfNew(FILE *file, const char *fmt, const char *sym, int checkLocals) -{ - if (!pic14_stringInSet(sym, &emitted, 1)) { - /* sym was not in emittedSymbols */ - if (!checkLocals || !pic14_stringInSet(sym, &pic14_localFunctions, 0)) { - /* sym is not a locally defined function---avoid bug #1443651 */ - fprintf( file, fmt, sym ); - return 0; - } - } - return 1; -} -#endif - -#if 0 -/*-------------------------------------------------------------------*/ -/* emitSymbol - write a symbol definition only if it is not */ -/* already present */ -/*-------------------------------------------------------------------*/ -static void -emitSymbol (struct dbuf_s *oBuf, const char *name, const char *section_type, int size, int addr, int useEQU, int globalize) -{ - static unsigned int sec_idx = 0; - - /* workaround: variables declared via `sbit' result in a numeric - * identifier (0xHH), EQU'ing them is invalid, so just ignore it. - * sbit is heavily used in the inc2h-generated header files! - */ - if (!is_valid_identifier(name)) - { - //fprintf( stderr, "%s:%s:%u: ignored symbol: %s\n", __FILE__, __FUNCTION__, __LINE__, name ); - return; - } - - /* check whether the symbol is already defined */ - if (pic14_stringInSet(name, &emitted, 1)) return; - - /* new symbol -- define it */ - //fprintf (stderr, "%s: emitting %s (%d)\n", __FUNCTION__, name, size); - if (useEQU) { - dbuf_printf (oBuf, "%s\tEQU\t0x%04x\n", name, addr); - } else { - /* we place each symbol into a section of its own to allow the linker - * to distribute the data into all available memory banks */ - if (!section_type) section_type = "udata"; - if (addr != -1) - { - /* absolute symbols are handled in pic14_constructAbsMap */ - /* do nothing */ - } else { - if (globalize) dbuf_printf (oBuf, "\tglobal\t%s\n", name); - dbuf_printf (oBuf, "udata_%s_%u\t%s\n", moduleName, - sec_idx++, section_type); - dbuf_printf (oBuf, "%s\tres\t%d\n", name, size); - } - } -} -#endif - - -#if 0 -/*-----------------------------------------------------------------*/ -/* printExterns - generates extern for external variables */ -/*-----------------------------------------------------------------*/ -static void -pic14printExterns (FILE * afile) -{ - symbol *sym; - - fprintf (afile, "%s", iComments2); - fprintf (afile, "; extern variables in this module\n"); - fprintf (afile, "%s", iComments2); - - for (sym = setFirstItem (externs); sym; sym = setNextItem (externs)) - pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1); -} - -/*-----------------------------------------------------------------*/ -/* printPublics - generates .global for publics */ -/*-----------------------------------------------------------------*/ -static void -pic14printPublics (FILE * afile) -{ - symbol *sym; - - fprintf (afile, "%s", iComments2); - fprintf (afile, "; public variables in this module\n"); - fprintf (afile, "%s", iComments2); - - for (sym = setFirstItem (publics); sym; - sym = setNextItem (publics)) { - - if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) { - if (!IS_BITVAR(sym->type)) - pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0); - } else { - /* Absolute variables are defines in the asm file as equates and thus can not be made global. */ - /* Not any longer! */ - //if (!SPEC_ABSA (sym->etype)) - pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0); - } - } -} -#endif - -/* - * Interface to BANKSEL generation. - * This function should return != 0 iff str1 and str2 denote operands that - * are known to be allocated into the same bank. Consequently, there will - * be no BANKSEL emitted if str2 is accessed while str1 has been used to - * select the current bank just previously. - * - * If in doubt, return 0. - */ -int -pic14_operandsAllocatedInSameBank(const char *str1, const char *str2) { - // see pic14printLocals - - if (getenv("SDCC_PIC14_SPLIT_LOCALS")) { - // no clustering applied, each register resides in its own bank - } else { - // check whether BOTH names are local registers - // XXX: This is some kind of shortcut, should be safe... - // In this model, all r0xXXXX are allocated into a single section - // per file, so no BANKSEL required if accessing a r0xXXXX after a - // (different) r0xXXXX. Works great for multi-byte operands. - if (str1 && str2 && str1[0] == 'r' && str2[0] == 'r') return (1); - } // if - - // assume operands in different banks - return (0); -} - static void pic14printLocals (struct dbuf_s *oBuf) { @@ -1324,7 +454,7 @@ pic14emitOverlay (struct dbuf_s * aBuf) } -void +static void pic14_emitInterruptHandler (FILE * asmFile) { if (pic14_hasInterrupt) @@ -1371,31 +501,6 @@ picglue () pic14_options.isLibrarySource = 1; } -#if 0 - if (mainf && IFFUNC_HASBODY(mainf->type)) { - - pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block")); - addpBlock(pb); - - /* entry point @ start of CSEG */ - addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1)); - /* put in the call to main */ - addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR))); - - if (options.mainreturn) { - - addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n")); - addpCode2pBlock(pb,newpCode(POC_RETURN,NULL)); - - } else { - - addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n")); - addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR))); - - } - } -#endif - /* At this point we've got all the code in the form of pCode structures */ /* Now it needs to be rearranged into the order it should be placed in the */ /* code space */ @@ -1410,8 +515,6 @@ picglue () if (options.debug) cdbStructBlock (0); - /* emit code for the all the variables declared */ - //pic14emitMaps (); /* do the overlay segments */ pic14emitOverlay(&ovrBuf); @@ -1437,11 +540,11 @@ picglue () if ((noAssemble || options.c1mode) && fullDstFileName) { - sprintf (buffer, fullDstFileName); + sprintf (buffer, "%s", fullDstFileName); } else { - sprintf (buffer, dstFileName); + sprintf (buffer, "%s", dstFileName); strcat (buffer, ".asm"); } @@ -1466,32 +569,6 @@ picglue () port->genAssemblerPreamble(asmFile); } - /* print the global variables in this module */ - //pic14printPublics (asmFile); - - /* print the extern variables in this module */ - //pic14printExterns (asmFile); - - /* copy the sfr segment */ -#if 0 - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; special function registers\n"); - fprintf (asmFile, "%s", iComments2); - dbuf_write_and_destroy (&sfr->oBuf, asmFile); - - - if (udata_section_name) { - sprintf(udata_name,"%s",udata_section_name); - } else { - sprintf(udata_name,"data_%s",moduleName); - } - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; udata\n"); - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "%s\tudata\n", udata_name); - dbuf_write_and_destroy(&data->oBuf, asmFile); -#endif - /* Put all variables into a cblock */ AnalyzeBanking(); @@ -1507,48 +584,6 @@ picglue () fprintf (asmFile, "%s", iComments2); dbuf_write_and_destroy (&ovrBuf, asmFile); -#if 0 - - /* create the stack segment MOF */ - if (mainf && IFFUNC_HASBODY(mainf->type)) { - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; Stack segment in internal ram \n"); - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n" - ";__start__stack:\n;\t.ds\t1\n\n"); - } - - /* create the idata segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; indirectly addressable internal ram data\n"); - fprintf (asmFile, "%s", iComments2); - dbuf_write_and_destroy (&idata->oBuf, asmFile); - - /* if external stack then reserve space of it */ - if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) { - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; external stack \n"); - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */ - fprintf (asmFile,";\t.ds 256\n"); - } - - /* copy xtern ram data */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; external ram data\n"); - fprintf (asmFile, "%s", iComments2); - dbuf_write_and_destroy (&xdata->oBuf, asmFile); - -#endif - - /* copy the bit segment */ -#if 0 - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; bit data\n"); - fprintf (asmFile, "%s", iComments2); - dbuf_write_and_destroy (&bit->oBuf, asmFile); -#endif - /* copy the interrupt vector table */ if (mainf && IFFUNC_HASBODY(mainf->type)) dbuf_write_and_destroy (&vBuf, asmFile); @@ -1596,60 +631,7 @@ picglue () #define DEBUGprintf 1 ? (void)0 : (void)printf #endif - -void ast_print (ast * tree, FILE *outfile, int indent); - -#if 0 -/* - * Emit all memmaps. - */ -static void -showInitList(initList *list, int level) -{ - static const char *list_type[] = { "INIT_NODE", "INIT_DEEP", "INIT_HOLE" }; - static const char *ast_type[] = { "EX_OP", "EX_VALUE", "EX_LINK", "EX_OPERAND" }; - struct ast *ast; - while (list) { - printf (" %d: type %u (%s), init %p, next %p\n", level, list->type, list_type[list->type], list->init.node, list->next); - if (list->type == INIT_DEEP) { - showInitList(list->init.deep, level + 1); - } else if (list->type == INIT_NODE) { - ast = list->init.node; - printf (" type %u (%s), level %d, block %d, seqPoint %d\n", - ast->type, ast_type[ast->type], ast->level, ast->block, ast->seqPoint); - if (ast->type == EX_VALUE) { - printf (" VAL %lf\n", floatFromVal(ast->opval.val)); - } else if (ast->type == EX_LINK) { - printTypeChain(ast->opval.lnk, NULL); - } else if (ast->type == EX_OP) { - printf (" OP %u\n", ast->opval.op); - } - } // if - list = list->next; - } // while -} -#endif - -/* - * DEBUG: Print a value. - */ -void -printVal(value *val) -{ - printf ("value %p: name %s, type %p, etype %p, sym %s, vArgs %d, lit 0x%lx/%ld\n", - val, val->name, val->type, val->etype, - val->sym ? val->sym->name : NULL, val->vArgs, - (long) ulFromVal (val), (long) ulFromVal (val)); - printTypeChain(val->type, stdout); - printf ("\n"); - printTypeChain(val->etype, stdout); - printf ("\n"); -} - -//prototype from ../SDCCicode.c -operand *operandFromAst (ast * tree,int lvl); - -char * +static char * parseIvalAst (ast *node, int *inCodeSpace) { #define LEN 4096 char *buffer = NULL; @@ -1762,7 +744,6 @@ emitIvalLabel(struct dbuf_s *oBuf, symbol *sym) return (in_code); } -char *get_op(pCodeOp *pcop,char *buffer, size_t size); /* * Actually emit the initial values in .asm format. */ @@ -1801,7 +782,6 @@ emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size) if (constExprTree(node) && (val = constExprValue(node, 0))) { op = operandFromValue(val); DEBUGprintf ("%s: constExpr ", __FUNCTION__); - //printVal(val); } else if (IS_AST_VALUE(node)) { op = operandFromAst(node, 0); } else if (IS_AST_OP(node)) { @@ -1819,8 +799,20 @@ emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size) } for (i=0; i < size; i++) { - char *text = op ? aopGet(AOP(op), i, 0, 0) + char *text; + + /* + * FIXME: This is hacky and needs some more thought. + */ + if (op && IS_SYMOP(op) && IS_FUNC(OP_SYM_TYPE(op))) { + /* This branch is introduced to fix #1427663. */ + PCOI(AOP(op)->aopu.pcop)->offset+=i; + text = get_op(AOP(op)->aopu.pcop, NULL, 0); + PCOI(AOP(op)->aopu.pcop)->offset-=i; + } else { + text = op ? aopGet(AOP(op), i, 0, 0) : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0); + } // if if (in_code) { dbuf_printf (oBuf, "\tretlw %s\n", text); } else { @@ -2179,3 +1171,4 @@ showAllMemmaps(FILE *of) extBuf = gloBuf = gloDefBuf = ivalBuf = NULL; } +