X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fpcode.c;h=9cb878feae768e03fe634fe363563249122bfa45;hb=3062f96ccb55d1d05caf9c8782f4961f87b341ce;hp=49f86f72703350854168553a20bc1beb5e437c5c;hpb=f8c26719e5821477ae5ed97bdaa1b579b00fd2c5;p=fw%2Fsdcc diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 49f86f72..9cb878fe 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -32,10 +32,10 @@ #include "ralloc.h" #include "device.h" +extern char *pic16_aopGet (struct asmop *aop, int offset, bool bit16, bool dname); + #if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp +#define inline #endif #define DUMP_DF_GRAPHS 0 @@ -158,7 +158,7 @@ extern void pic16_BuildFlowTree(pBlock *pb); extern void pic16_pCodeRegOptimizeRegUsage(int level); extern int pic16_picIsInitialized(void); extern void SAFE_snprintf(char **str, size_t *size, const char *format, ...); -extern int mnem2key(char const *mnem); +extern int mnem2key(unsigned char const *mnem); /****************************************************************/ /* Forward declarations */ @@ -3110,7 +3110,7 @@ void pic16_pCodeInitRegisters(void) /* */ /*-----------------------------------------------------------------*/ -int mnem2key(char const *mnem) +int mnem2key(unsigned char const *mnem) { int key = 0; @@ -3242,7 +3242,7 @@ void pic16initMnemonics(void) for(i=0; imnemonic), pic16Mnemonics[i]); + hTabAddItem(&pic16MnemonicsHash, mnem2key((const unsigned char *)pic16Mnemonics[i]->mnemonic), pic16Mnemonics[i]); pci = hTabFirstItem(pic16MnemonicsHash, &key); while(pci) { @@ -3259,7 +3259,7 @@ int pic16_getpCode(char *mnem,unsigned dest) { pCodeInstruction *pci; - int key = mnem2key(mnem); + int key = mnem2key((unsigned char *)mnem); if(!mnemonics_initialized) pic16initMnemonics(); @@ -3299,7 +3299,7 @@ void pic16initpCodePeepCommands(void) i = 0; do { hTabAddItem(&pic16pCodePeepCommandsHash, - mnem2key(peepCommands[i].cmd), &peepCommands[i]); + mnem2key((const unsigned char *)peepCommands[i].cmd), &peepCommands[i]); i++; } while (peepCommands[i].cmd); @@ -3321,7 +3321,7 @@ int pic16_getpCodePeepCommand(char *cmd) { peepCommand *pcmd; - int key = mnem2key(cmd); + int key = mnem2key((unsigned char *)cmd); pcmd = hTabFirstItemWK(pic16pCodePeepCommandsHash, key); @@ -3522,6 +3522,7 @@ static int RegCond(pCodeOp *pcop) return 0; } + /*-----------------------------------------------------------------*/ /* pic16_newpCode - create and return a newly initialized pCode */ /* */ @@ -3853,7 +3854,7 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...) if(asdir && *asdir) { - while(isspace(*asdir))asdir++; // strip any white space from the beginning + while(isspace((unsigned char)*asdir))asdir++; // strip any white space from the beginning pcad->directive = Safe_strdup( asdir ); } @@ -3866,7 +3867,7 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...) va_end(ap); - while(isspace(*lbp))lbp++; + while(isspace((unsigned char)*lbp))lbp++; if(lbp && *lbp) pcad->arg = Safe_strdup( lbp ); @@ -4066,6 +4067,30 @@ pCodeOp *pic16_newpCodeOpLit(int lit) return pcop; } +/* Allow for 12 bit literals, required for LFSR */ +pCodeOp *pic16_newpCodeOpLit12(int lit) +{ + char *s = buffer; + pCodeOp *pcop; + + + pcop = Safe_calloc(1,sizeof(pCodeOpLit) ); + pcop->type = PO_LITERAL; + + pcop->name = NULL; + //if(lit>=0) + sprintf(s,"0x%03x", ((unsigned int)lit) & 0x0fff); + //else + // sprintf(s, "%i", lit); + + if(s) + pcop->name = Safe_strdup(s); + + ((pCodeOpLit *)pcop)->lit = lit; + + return pcop; +} + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2) @@ -4114,6 +4139,7 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space) // fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset); } else { pcop->name = NULL; + PCOI(pcop)->rIdx = -1; } PCOI(pcop)->index = index; @@ -4223,6 +4249,12 @@ pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace, PIC_OPTYPE subt) return pcop; } +pCodeOp *pic16_newpCodeOpBit_simple (struct asmop *op, int offs, int bit) +{ + return pic16_newpCodeOpBit (pic16_aopGet(op,offs,FALSE,FALSE), + bit, 0, PO_GPR_REGISTER); +} + /*-----------------------------------------------------------------* * pCodeOp *pic16_newpCodeOpReg(int rIdx) - allocate a new register @@ -4235,26 +4267,28 @@ pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace, PIC_OPTYPE subt) pCodeOp *pic16_newpCodeOpReg(int rIdx) { pCodeOp *pcop; + regs *r; pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); pcop->name = NULL; if(rIdx >= 0) { - PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_regWithIdx(rIdx); + r = pic16_regWithIdx(rIdx); + if(!r) + r = pic16_allocWithIdx(rIdx); } else { - PCOR(pcop)->r = pic16_findFreeReg(REG_GPR); + r = pic16_findFreeReg(REG_GPR); - if(PCOR(pcop)->r) - PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; - else { + if(!r) { fprintf(stderr, "%s:%d Could not find a free GPR register\n", __FUNCTION__, __LINE__); - exit(-1); + exit(EXIT_FAILURE); } } + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = r; pcop->type = PCOR(pcop)->r->pc_type; return pcop; @@ -4363,6 +4397,11 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type) else pcop = pic16_newpCodeOpReg(-1); break; + + case PO_TWO_OPS: + assert( !"Cannot create PO_TWO_OPS from string!" ); + pcop = NULL; + break; default: pcop = Safe_calloc(1,sizeof(pCodeOp) ); @@ -4376,12 +4415,27 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type) return pcop; } -#define DB_ITEMS_PER_LINE 8 +pCodeOp *pic16_newpCodeOp2(pCodeOp *src, pCodeOp *dst) +{ + pCodeOp2 *pcop2 = Safe_calloc(1, sizeof(pCodeOp2)); + pcop2->pcop.type = PO_TWO_OPS; + pcop2->pcopL = src; + pcop2->pcopR = dst; + return PCOP(pcop2); +} + +/* This is a multiple of two as gpasm pads DB directives to even length, + * thus the data would be interleaved with \0 bytes... + * This is a multiple of three in order to have arrays of 3-byte pointers + * continuously in memory (without 0-padding at the lines' end). + * This is rather 12 than 6 in order not to split up 4-byte data types + * in arrays right in the middle of a 4-byte word. */ +#define DB_ITEMS_PER_LINE 12 typedef struct DBdata { int count; - char buffer[256]; + char buffer[512]; } DBdata; struct DBdata DBd; @@ -4423,7 +4477,7 @@ void pic16_flushDB(char ptype, void *p) /*-----------------------------------------------------------------*/ /* Add "DB" directives to a pBlock */ /*-----------------------------------------------------------------*/ -void pic16_emitDB(char c, char ptype, void *p) +void pic16_emitDB(int c, char ptype, void *p) { int l; @@ -4461,7 +4515,7 @@ void pic16_emitDS(char *s, char ptype, void *p) // fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer); DBd.count++; //=strlen(s); - if (DBd.count>=16) + if (DBd.count>=DB_ITEMS_PER_LINE) pic16_flushDB(ptype, p); } @@ -4471,12 +4525,27 @@ void pic16_emitDS(char *s, char ptype, void *p) void pic16_pCodeConstString(char *name, char *value) { pBlock *pb; - - // fprintf(stderr, " %s %s %s\n",__FUNCTION__,name,value); + char *item; + static set *emittedSymbols = NULL; if(!name || !value) return; + /* keep track of emitted symbols to avoid multiple definition of str_ */ + if (emittedSymbols) { + /* scan set for name */ + for (item = setFirstItem (emittedSymbols); item; item = setNextItem (emittedSymbols)) + { + if (!strcmp (item,name)) { + //fprintf (stderr, "%s already emitted\n", name); + return; + } // if + } // for + } // if + addSet (&emittedSymbols, Safe_strdup (name)); + + //fprintf(stderr, " %s %s %s\n",__FUNCTION__,name,value); + pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block")); pic16_addpBlock(pb); @@ -4747,6 +4816,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) } if(pcop) { + switch(pcop->type) { case PO_W: case PO_WREG: @@ -4756,17 +4826,17 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) case PO_FSR0: if(use_buffer) { SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name); - return buffer; + return (buffer); } - return PCOR(pcop)->r->name; + return (PCOR(pcop)->r->name); break; case PO_GPR_TEMP: r = pic16_regWithIdx(PCOR(pcop)->r->rIdx); if(use_buffer) { SAFE_snprintf(&buffer,&size,"%s",r->name); - return buffer; + return (buffer); } - return r->name; + return (r->name); case PO_IMMEDIATE: s = buffer; @@ -4793,7 +4863,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) pcop->name); } } - return buffer; + return (buffer); case PO_GPR_REGISTER: case PO_DIR: @@ -4806,7 +4876,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) } else { SAFE_snprintf(&s,&size,"%s",pcop->name); } - return buffer; + return (buffer); case PO_GPR_BIT: s = buffer; if(PCORB(pcop)->subtype == PO_GPR_TEMP) { @@ -4819,19 +4889,23 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) } return (buffer); + case PO_TWO_OPS: + return (pic16_get_op( PCOP2(pcop)->pcopL, use_buffer ? buffer : NULL, size )); + default: if(pcop->name) { if(use_buffer) { SAFE_snprintf(&buffer,&size,"%s",pcop->name); - return buffer; + return (buffer); } - return pcop->name; + return (pcop->name); } } + return ("unhandled type for op1"); } - return "NO operand1"; + return ("NO operand1"); } /*-----------------------------------------------------------------*/ @@ -4839,95 +4913,10 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) /*-----------------------------------------------------------------*/ char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size) { - regs *r; - static char b[50]; - char *s; - int use_buffer = 1; // copy the string to the passed buffer pointer - if(!buffer) { - buffer = b; - size = sizeof(b); - use_buffer = 0; // Don't bother copying the string to the buffer. - } - -#if 0 - fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n", - __FUNCTION__, __LINE__, PCOR(PCOR2(pcop)->pcop2)->r->name, PCOR2(pcop)->pcop2->type, - PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0); -#endif - - if(pcop) { - switch(PCOR2(pcop)->pcop2->type) { - case PO_W: - case PO_WREG: - case PO_PRODL: - case PO_PRODH: - case PO_INDF0: - case PO_FSR0: - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - return buffer; - } - return PCOR(PCOR2(pcop)->pcop2)->r->name; - break; - case PO_GPR_TEMP: - r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx); - - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",r->name); - return buffer; - } - return r->name; - - case PO_IMMEDIATE: - assert( 0 ); - break; -#if 0 - s = buffer; - - if(PCOI(pcop)->_const) { - if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) { - SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)", - pcop->name, - PCOI(pcop)->index, - 8 * PCOI(pcop)->offset ); - } else - SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); - } else { - if( PCOI(pcop)->index) { - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOI(pcop)->index ); - } else { - if(PCOI(pcop)->offset) - SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); - else - SAFE_snprintf(&s,&size,"%s",pcop->name); - } - } - return buffer; -#endif - case PO_DIR: - s = buffer; - if( PCOR(PCOR2(pcop)->pcop2)->instance) { - SAFE_snprintf(&s,&size,"(%s + %d)", - PCOR(PCOR2(pcop)->pcop2)->r->name, - PCOR(PCOR2(pcop)->pcop2)->instance ); - } else { - SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - } - return buffer; - - default: - if(PCOR(PCOR2(pcop)->pcop2)->r->name) { - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - return buffer; - } - return PCOR(PCOR2(pcop)->pcop2)->r->name; - } - } - } + if(pcop && pcop->type == PO_TWO_OPS) { + return pic16_get_op( PCOP2(pcop)->pcopR, buffer, size ); + } return "NO operand2"; } @@ -4967,7 +4956,7 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) { fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n", __FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC); -// exit(-1); +// exit(EXIT_FAILURE); } #endif @@ -4978,10 +4967,14 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) { - if(PCI(pc)->is2MemOp) { - SAFE_snprintf(&s,&size, "%s, %s", - pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0), - pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0)); + //if(PCI(pc)->is2MemOp) + if (PCI(pc)->pcop->type == PO_TWO_OPS) + { + /* split into two phases due to static buffer in pic16_get_op() */ + SAFE_snprintf(&s,&size, "%s", + pic16_get_op((PCI(pc)->pcop), NULL, 0)); + SAFE_snprintf(&s, &size, ", %s", + pic16_get_op2((PCI(pc)->pcop), NULL, 0)); break; } @@ -5026,9 +5019,16 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc) r = pic16_getRegFromInstruction(pc); // fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n", -// __FUNCTION__, __LINE__, r, (r)?r->name:"", (r)?r->accessBank:-1); - - if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED")); +// __FUNCTION__, __LINE__, r, (r)?r->name:"", (r)?isACCESS_BANK(r):-1); + + if(PCI(pc)->isAccess) { + static char *bank_spec[2][2] = { + { "", ", ACCESS" }, /* gpasm uses access bank by default */ + { ", B", ", BANKED" }/* MPASM (should) use BANKED by default */ + }; + + SAFE_snprintf(&s,&size,"%s", bank_spec[(r && !isACCESS_BANK(r)) ? 1 : 0][pic16_mplab_comp ? 1 : 0]); + } } // @@ -5795,9 +5795,13 @@ regs * pic16_getRegFrompCodeOp (pCodeOp *pcop) { case PO_WILD: break; + + case PO_TWO_OPS: + return pic16_getRegFrompCodeOp( PCOP2(pcop)->pcopL ); + break; default: - fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d (%s)\n",pcop->type, dumpPicOptype (pcop->type)); + fprintf(stderr, "pic16_getRegFrompCodeOp - unknown reg type %d (%s)\n",pcop->type, dumpPicOptype (pcop->type)); // assert( 0 ); break; } @@ -5809,7 +5813,6 @@ regs * pic16_getRegFrompCodeOp (pCodeOp *pcop) { /*-----------------------------------------------------------------*/ regs * pic16_getRegFromInstruction(pCode *pc) { - if(!pc || !isPCI(pc) || !PCI(pc)->pcop || @@ -5822,7 +5825,7 @@ regs * pic16_getRegFromInstruction(pCode *pc) dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type); #endif - return pic16_getRegFrompCodeOp (PCI(pc)->pcop); + return( pic16_getRegFrompCodeOp (PCI(pc)->pcop) ); } /*-------------------------------------------------------------------------------*/ @@ -5838,13 +5841,15 @@ regs * pic16_getRegFromInstruction2(pCode *pc) (PCI(pc)->num_ops == 1)) // accept only 2 operand commands return NULL; + if (PCI(pc)->pcop->type != PO_TWO_OPS) + return NULL; #if 0 fprintf(stderr, "pic16_getRegFromInstruction2 - reg type %s (%d)\n", dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type); #endif - return pic16_getRegFrompCodeOp (PCOR2(PCI(pc)->pcop)->pcop2); + return pic16_getRegFrompCodeOp (PCOP2(PCI(pc)->pcop)->pcopR); } /*-----------------------------------------------------------------*/ @@ -5895,7 +5900,7 @@ static void AnalyzepBlock(pBlock *pb) } if(PCI(pc)->pcop->type == PO_GPR_REGISTER) { if(PCOR(PCI(pc)->pcop)->r) { - pic16_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx); + pic16_allocWithIdx(PCOR(PCI(pc)->pcop)->r->rIdx); /* FIXME! - VR */ DFPRINTF((stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx)); } else { if(PCI(pc)->pcop->name) @@ -8693,12 +8698,14 @@ char *pic_optype_names[]={ "PO_BIT", // bit operand. "PO_STR", // (8051 legacy) "PO_LABEL", - "PO_WILD" // Wild card operand in peep optimizer + "PO_WILD", // Wild card operand in peep optimizer + "PO_TWO_OPS" // combine two operands }; char *dumpPicOptype(PIC_OPTYPE type) { + assert( type >= 0 && type < sizeof(pic_optype_names)/sizeof( char *) ); return (pic_optype_names[ type ]); } @@ -8762,7 +8769,7 @@ int comparePtr (const void *p1, const void *p2) /* getSymbolFromOperand - return a pointer to the symbol in */ /* the given operand and its length */ /*----------------------------------------------------------*/ -char *getSymbolFromOperand (char *op, unsigned int *len) +char *getSymbolFromOperand (char *op, int *len) { char *sym, *curr; *len = 0; @@ -9378,6 +9385,9 @@ typedef unsigned int valnum_t; #define PTR_TO_INT(x) (((char *)(x)) - ((char *) 0)) #endif +static int pic16_regIsLocal (regs *r); +static int pic16_safepCodeRemove (pCode *pc, char *comment); + /* statistics */ static unsigned int pic16_df_removed_pcodes = 0; static unsigned int pic16_df_saved_bytes = 0; @@ -9408,12 +9418,53 @@ static int pic16_safepCodeUnlink (pCode *pc, char *comment) { pcprev = pic16_findPrevInstruction (pc->prev); pcnext = pic16_findNextInstruction (pc->next); - /* if previous instruction is a skip -- do not remove */ - if (pcprev && isPCI_SKIP(pcprev)) return 0; - /* move labels to next instruction (if possible) */ if (PCI(pc)->label && !pcnext) return 0; + /* if this is a SKIP with side-effects -- do not remove */ + /* XXX: might try to replace this one with the side-effect only version */ + if (isPCI_SKIP(pc) + && ((PCI(pc)->outCond & (PCC_REGISTER | PCC_W)) != 0)) + { + pCode *newpc; + switch (PCI(pc)->op) + { + case POC_INCFSZ: + case POC_INFSNZ: + newpc = pic16_newpCode(POC_INCF, pic16_pCodeOpCopy( PCI(pc)->pcop ) ); + pic16_pCodeReplace( pc, newpc ); + return 1; + break; + case POC_INCFSZW: + newpc = pic16_newpCode(POC_INCFW, pic16_pCodeOpCopy( PCI(pc)->pcop ) ); + pic16_pCodeReplace( pc, newpc ); + return 1; + break; + case POC_DECFSZ: + case POC_DCFSNZ: + newpc = pic16_newpCode(POC_INCF, pic16_pCodeOpCopy( PCI(pc)->pcop ) ); + pic16_pCodeReplace( pc, newpc ); + return 1; + break; + case POC_DECFSZW: + newpc = pic16_newpCode(POC_INCF, pic16_pCodeOpCopy( PCI(pc)->pcop ) ); + pic16_pCodeReplace( pc, newpc ); + return 1; + break; + default: + return 0; + } + return 0; + } + + /* if previous instruction is a skip -- do not remove */ + if (pcprev && isPCI_SKIP(pcprev)) { + if (!pic16_safepCodeUnlink (pcprev, "=DF= removed now unused SKIP")) { + /* preceeding SKIP could not be removed -- keep this instruction! */ + return 0; + } + } + if (PCI(pc)->label) { //fprintf (stderr, "%s: moving label(s)\n", __FUNCTION__); //pc->print (stderr, pc); @@ -9431,7 +9482,7 @@ static int pic16_safepCodeUnlink (pCode *pc, char *comment) { if (0 || pic16_debug_verbose || pic16_pcode_verbose) { len = strlen (buf) + strlen (comment) + 10; total = (char *) Safe_malloc (len); - snprintf (total, len, "%s: %s", comment, buf); + SNPRINTF (total, len, "%s: %s", comment, buf); pic16_pCodeInsertAfter (pc, pic16_newpCodeCharP(total)); Safe_free (total); } @@ -9531,9 +9582,6 @@ static symbol_t symFromStr (const char *str) { if (!map_symToStr) { int i; - map_strToSym = newHashTable (128); - map_symToStr = newHashTable (128); - struct { char *name; symbol_t sym; } predefsyms[] = { {"WREG", SPO_WREG}, {"STATUS", SPO_STATUS}, @@ -9575,6 +9623,9 @@ static symbol_t symFromStr (const char *str) { {NULL, 0} }; + map_strToSym = newHashTable (128); + map_symToStr = newHashTable (128); + for (i=0; predefsyms[i].name; i++) { char *name; @@ -9594,7 +9645,7 @@ static symbol_t symFromStr (const char *str) { /* find symbol in table */ sym = PTR_TO_INT(hTabFindByKey (map_strToSym, hash, str, &symcmp)); if (sym) { - //fprintf (stderr, "found symbol %u for %s\n", sym, str); + //fprintf (stderr, "found symbol %x for %s\n", sym, str); return sym; } @@ -9605,7 +9656,7 @@ static symbol_t symFromStr (const char *str) { hTabAddItemLong (&map_strToSym, hash, res, INT_TO_PTR(sym)); hTabAddItemLong (&map_symToStr, sym % map_symToStr->size, INT_TO_PTR(sym), res); - //fprintf (stderr, "created symbol %u for %s\n", sym, res); + //fprintf (stderr, "created symbol %x for %s\n", sym, res); return sym; } @@ -9642,7 +9693,7 @@ typedef struct defmap_s { int isWrite:1; /** sym/mask is written */ } access; int accessmethod; - }; + } acc; pCode *pc; /** pCode this symbol is refrenced at */ valnum_t in_val; /** valnum_t of symbol's previous value (the one read at pc) */ valnum_t val; /** new unique number for this value (if isWrite) */ @@ -9665,10 +9716,10 @@ static defmap_t *newDefmap (symbol_t sym, int in_mask, int mask, int isRead, int map = (defmap_t *) Safe_calloc (1, sizeof (defmap_t)); } map->sym = sym; - map->access.in_mask = (isRead ? (in_mask ? in_mask : 0xFF) : 0x00); - map->access.mask = (isWrite ? (mask ? mask : 0xFF) : 0x00); - map->access.isRead = (isRead != 0); - map->access.isWrite = (isWrite != 0); + map->acc.access.in_mask = (isRead ? (in_mask ? in_mask : 0xFF) : 0x00); + map->acc.access.mask = (isWrite ? (mask ? mask : 0xFF) : 0x00); + map->acc.access.isRead = (isRead != 0); + map->acc.access.isWrite = (isWrite != 0); map->pc = pc; map->in_val = 0; map->val = (isWrite ? val : 0); @@ -9688,6 +9739,18 @@ static defmap_t *copyDefmap (defmap_t *map) { return res; } +/* Insert a defmap item after the specified one. */ +static int defmapInsertAfter (defmap_t *ref, defmap_t *newItem) { + if (!ref || !newItem) return 1; + + newItem->next = ref->next; + newItem->prev = ref; + ref->next = newItem; + if (newItem->next) newItem->next->prev = newItem; + + return 0; +} + /* Check whether item (or an identical one) is already in the chain and add it if neccessary. * item is copied before insertion into chain and therefore left untouched. * Returns 1 iff the item has been inserted into the list, 0 otherwise. */ @@ -9696,7 +9759,7 @@ static int defmapAddCopyIfNew (defmap_t **head, defmap_t *item) { dummy = *head; while (dummy && (dummy->sym != item->sym || dummy->pc != item->pc - || dummy->accessmethod != item->accessmethod + || dummy->acc.accessmethod != item->acc.accessmethod || dummy->val != item->val || dummy->in_val != item->in_val)) { dummy = dummy->next; @@ -9795,7 +9858,7 @@ static defmap_t *defmapFindDef (defmap_t *map, symbol_t sym, pCode *pc) { } // if (pc) /* find definition for sym */ - while (curr && (!curr->access.isWrite || (curr->sym != sym))) { + while (curr && (!curr->acc.access.isWrite || (curr->sym != sym))) { curr = curr->next; } @@ -9824,7 +9887,7 @@ static defmap_t *defmapFindUse (defmap_t *map, symbol_t sym, pCode *pc) { } // if (pc) /* find use of sym (scan list backwards) */ - while (curr && (!curr->access.isRead || (curr->sym != sym))) curr = curr->prev; + while (curr && (!curr->acc.access.isRead || (curr->sym != sym))) curr = curr->prev; return curr; } @@ -9868,7 +9931,7 @@ static int defmapUpdate (defmap_t *map, symbol_t sym, pCode *pc, valnum_t newval while (m && m->pc != pc) m = m->next; /* find definition of sym at pc */ - while (m && m->pc == pc && (!m->access.isWrite || (m->sym != sym))) m = m->next; + while (m && m->pc == pc && (!m->acc.access.isWrite || (m->sym != sym))) m = m->next; /* no definition found */ if (!m) return 1; @@ -9881,7 +9944,7 @@ static int defmapUpdate (defmap_t *map, symbol_t sym, pCode *pc, valnum_t newval while (m) { if (m->sym == sym) { m->in_val = newval; - if (m->access.isWrite) m = NULL; + if (m->acc.access.isWrite) m = NULL; } // if if (m) m = m->prev; } // while @@ -9898,18 +9961,18 @@ typedef struct stack_s { struct stack_s *next; } stackitem_t; -typedef stackitem_t *stack_t; +typedef stackitem_t *dynstack_t; static stackitem_t *free_stackitems = NULL; /* Create a stack with one item. */ -static stack_t *newStack () { - stack_t *s = (stack_t *) Safe_malloc (sizeof (stack_t)); +static dynstack_t *newStack () { + dynstack_t *s = (dynstack_t *) Safe_malloc (sizeof (dynstack_t)); *s = NULL; return s; } /* Remove a stack -- its items are only marked free. */ -static void deleteStack (stack_t *s) { +static void deleteStack (dynstack_t *s) { stackitem_t *i; while (*s) { @@ -9932,7 +9995,7 @@ static void releaseStack () { } // while } -static void stackPush (stack_t *stack, void *data) { +static void stackPush (dynstack_t *stack, void *data) { stackitem_t *i; if (free_stackitems) { @@ -9946,7 +10009,7 @@ static void stackPush (stack_t *stack, void *data) { *stack = i; } -static void *stackPop (stack_t *stack) { +static void *stackPop (dynstack_t *stack) { void *data; stackitem_t *i; @@ -9963,7 +10026,7 @@ static void *stackPop (stack_t *stack) { } #if 0 -static int stackContains (stack_t *s, void *data) { +static int stackContains (dynstack_t *s, void *data) { stackitem_t *i; if (!s) return 0; i = *s; @@ -9977,7 +10040,7 @@ static int stackContains (stack_t *s, void *data) { } #endif -static int stackIsEmpty (stack_t *s) { +static int stackIsEmpty (dynstack_t *s) { return (*s == NULL); } @@ -9998,7 +10061,7 @@ static void deleteState (state_t *s) { Safe_free (s); } -static int stateIsNew (state_t *state, stack_t *todo, stack_t *done) { +static int stateIsNew (state_t *state, dynstack_t *todo, dynstack_t *done) { stackitem_t *i; /* scan working list for state */ @@ -10085,8 +10148,8 @@ static int defmapFindAll (symbol_t sym, pCode *pc, defmap_t **chain) { pCodeFlow *curr; pCodeFlowLink *succ; state_t *state; - stack_t *todo; /** stack of state_t */ - stack_t *done; /** stack of state_t */ + dynstack_t *todo; /** stack of state_t */ + dynstack_t *done; /** stack of state_t */ int firstState, n_defs; @@ -10293,6 +10356,7 @@ static valnum_t valnumFromStr (const char *str) { /* create new valnum */ val = newValnum(); hTabAddItemLong (&map_symToValnum, sym % map_symToValnum->size, INT_TO_PTR(sym), INT_TO_PTR(val)); + //fprintf (stderr, "NEW VALNUM %x for symbol %s\n", val, str); return val; } @@ -10410,7 +10474,7 @@ int pic16_isAliveInFlow (symbol_t sym, int mask, pCodeFlow *pcfl, pCode *pc) { /* scan list for reads at this pc first */ while (map && map->pc == mappc->pc) { /* is the symbol (partially) read? */ - if ((map->sym == sym) && (map->access.isRead && ((map->access.in_mask & mask) != 0))) { + if ((map->sym == sym) && (map->acc.access.isRead && ((map->acc.access.in_mask & mask) != 0))) { //if (sym != SPO_STATUS) fprintf (stderr, "%s: symbol %s read at pc %p\n", __FUNCTION__, strFromSym (sym), map->pc); return -1; } @@ -10420,8 +10484,8 @@ int pic16_isAliveInFlow (symbol_t sym, int mask, pCodeFlow *pcfl, pCode *pc) { while (map && map->pc == mappc->pc) { /* honor (partial) redefinitions of sym */ - if ((map->sym == sym) && (map->access.isWrite)) { - mask &= ~map->access.mask; + if ((map->sym == sym) && (map->acc.access.isWrite)) { + mask &= ~map->acc.access.mask; //if (sym != SPO_STATUS) fprintf (stderr, "%s: symbol %s redefined at pc %p, alive mask: %x\n", __FUNCTION__, strFromSym (sym), map->pc, mask); } map = map->prev; @@ -10440,7 +10504,7 @@ int pic16_isAliveInFlow (symbol_t sym, int mask, pCodeFlow *pcfl, pCode *pc) { static int pic16_isAlive (symbol_t sym, pCode *pc) { int mask, visit; defmap_t *map; - stack_t *todo, *done; + dynstack_t *todo, *done; state_t *state; pCodeFlow *pcfl; pCodeFlowLink *succ; @@ -10528,6 +10592,8 @@ static int pic16_symIsSpecial (symbol_t sym) { static int pic16_regIsLocal (regs *r) { symbol_t sym; if (r) { + if (r->type == REG_TMP) return 1; + sym = symFromStr (r->name); switch (sym) { case SPO_WREG: @@ -10640,7 +10706,12 @@ static int pic16_pCodeIsAlive (pCode *pc) { while (map && map->pc != pc) map = map->next; /* no entries found? something is fishy with DF analysis... -- play safe */ - if (!map) { fprintf (stderr, "%s: defmap not found\n", __FUNCTION__); return 1; } + if (!map) { + if (pic16_pcode_verbose) { + fprintf (stderr, "%s: defmap not found\n", __FUNCTION__); + } + return 1; + } /* remember first item assigned to pc for later use */ lastpc = map; @@ -10661,7 +10732,7 @@ static int pic16_pCodeIsAlive (pCode *pc) { //fprintf (stderr, "%s: special sym\n", __FUNCTION__); return 1; } - if (map->access.isWrite) { + if (map->acc.access.isWrite) { if (pic16_isAlive (map->sym, pc)) { //fprintf (stderr, "%s(%s): pCode is alive (sym %s still used)\n", __FUNCTION__, pic16_pBlockGetFunctionName (pc->pb),strFromSym (map->sym)); return 1; @@ -10795,7 +10866,40 @@ static symbol_t pic16_fsrsym_idx[][2] = { {SPO_FSR1L, SPO_FSR1H}, {SPO_FSR2L, SPO_FSR2H} }; - + +/* Merge multiple defmap entries for the same symbol for list's pCode. */ +static void mergeDefmapSymbols (defmap_t *list) { + defmap_t *ref, *curr, *temp; + + /* now make sure that each symbol occurs at most once per pc */ + ref = list; + while (ref && (ref->pc == list->pc)) { + curr = ref->next; + while (curr && (curr->pc == list->pc)) { + if (curr->sym == ref->sym) { + //fprintf (stderr, "Merging defmap entries for symbol %s\n", strFromSym (ref->sym)); + /* found a symbol occuring twice... merge the two */ + if (curr->acc.access.isRead) { + //if (ref->acc.access.isRead) fprintf (stderr, "symbol %s was marked twice as read at pc %p\n", strFromSym (ref->sym), ref->pc); + ref->acc.access.isRead = 1; + ref->acc.access.in_mask |= curr->acc.access.in_mask; + } + if (curr->acc.access.isWrite) { + //if (ref->acc.access.isWrite) fprintf (stderr, "symbol %s was marked twice as written at pc %p\n", strFromSym (ref->sym), ref->pc); + ref->acc.access.isWrite = 1; + ref->acc.access.mask |= curr->acc.access.mask; + } + temp = curr; + curr = curr->next; + deleteDefmap (temp); + continue; // do not skip curr! + } // if + curr = curr->next; + } // while + ref = ref->next; + } // while +} + /** Prepend list with the reads and definitions performed by pc. */ static defmap_t *createDefmap (pCode *pc, defmap_t *list) { pCodeInstruction *pci; @@ -10829,8 +10933,8 @@ static defmap_t *createDefmap (pCode *pc, defmap_t *list) { valnum_t val; lit = PCOL(pci->pcop)->lit; assert (lit >= 0 && lit < 3); - //fprintf (stderr, "LFSR: %s // %s\n", pci->pcop->name, ((pCodeOpLit2 *)(pci->pcop))->arg2->name); - val = valnumFromStr (((pCodeOpLit2 *)(pci->pcop))->arg2->name); + //fprintf (stderr, "LFSR: %s // %s\n", pci->pcop->name, pic16_get_op(((pCodeOpLit2 *)(pci->pcop))->arg2, NULL, 0)); + val = valnumFromStr (pic16_get_op(((pCodeOpLit2 *)(pci->pcop))->arg2, NULL, 0)); //fprintf (stderr, "LFSR lit=%u, symval=%4x\n", lit, val); list = newDefmap (pic16_fsrsym_idx[lit][0], 0x00, 0xff, 0, 1, pc, val, list); list = newDefmap (pic16_fsrsym_idx[lit][1], 0x00, 0xff, 0, 1, pc, val+1, list); // val+1 is guaranteed not be used as a valnum... @@ -10948,7 +11052,7 @@ static defmap_t *createDefmap (pCode *pc, defmap_t *list) { list = newDefmap (symFromStr ("WREG"), mask, mask, inCond & PCC_W, outCond & PCC_W, pc, newValnum (), list); } // if - /* keep STATUS read BEFORE STATUS write in the list */ + /* keep STATUS read BEFORE STATUS write in the list (still neccessary?) */ if (inCond & PCC_STATUS) { smask = 0; if (inCond & PCC_C) smask |= 1U << PIC_C_BIT; @@ -10992,6 +11096,8 @@ static defmap_t *createDefmap (pCode *pc, defmap_t *list) { /* make sure there is at least one entry for each pc (needed by list traversal routines) */ list = newDefmap (0, 0x00, 0x00, 0, 0, pc, 0, list); + + mergeDefmapSymbols (list); return list; } @@ -11004,10 +11110,10 @@ static void printDefmap (defmap_t *map) { fprintf (stderr, "defmap @ %p:\n", curr); while (curr) { fprintf (stderr, "%s%s: %4x|%4x / %02x|%02x, sym %s(%x) @ pc %p\n", - curr->access.isRead ? "R" : " ", - curr->access.isWrite ? "W": " ", + curr->acc.access.isRead ? "R" : " ", + curr->acc.access.isWrite ? "W": " ", curr->in_val, curr->val, - curr->access.in_mask, curr->access.mask, + curr->acc.access.in_mask, curr->acc.access.mask, strFromSym(curr->sym), curr->sym, curr->pc); curr = curr->next; @@ -11042,7 +11148,7 @@ static int defmapUpdateUniqueSym (defmap_t **uniq, defmap_t *additional) { /* update uniq */ do { /* find next assignment in additionals */ - while (curr && !curr->access.isWrite) curr = curr->prev; + while (curr && !curr->acc.access.isWrite) curr = curr->prev; if (!curr) break; @@ -11330,17 +11436,44 @@ void pic16_fixDefmap (pCode *pc, pCode *newpc) { } // while } -void defmapReplaceSymRef (pCode *pc, symbol_t sym, symbol_t newsym) { - defmap_t *map; +/* Replace a defmap entry for sym with newsym for read accesses (isRead == 1) or + * write accesses (isRead == 0). */ +void defmapReplaceSymRef (pCode *pc, symbol_t sym, symbol_t newsym, int isRead) { + defmap_t *map, *map_start; + defmap_t *copy; if (!isPCI(pc)) return; + if (sym == newsym) return; map = PCI(pc)->pcflow->defmap; while (map && map->pc != pc) map = map->next; + map_start = map; while (map && map->pc == pc) { - if (map->sym == sym) map->sym = newsym; + if (map->sym == sym) { + assert ((isRead && map->acc.access.isRead) || ((!isRead) && (map->acc.access.isWrite))); + if (!(map->acc.access.isRead && map->acc.access.isWrite)) { + /* only one kind of access handled... this is easy */ + map->sym = newsym; + } else { + /* must copy defmap entry before replacing symbol... */ + copy = copyDefmap (map); + if (isRead) { + map->acc.access.isRead = 0; + copy->acc.access.isWrite = 0; + } else { + map->acc.access.isWrite = 0; + copy->acc.access.isRead = 0; + } + copy->sym = newsym; + /* insert copy into defmap chain */ + defmapInsertAfter (map, copy); + } + } map = map->next; } // while + + /* as this might introduce multiple defmap entries for newsym... */ + mergeDefmapSymbols (map_start); } /* Assign "better" valnums to results. */ @@ -11378,12 +11511,12 @@ static void assignValnums (pCode *pc) { //list = val; /* might save some time later... */ while (val && val->pc == pc) { val->in_val = 0; - if (val->sym != 0 && (1 || val->access.isRead)) { + if (val->sym != 0 && (1 || val->acc.access.isRead)) { /* get valnum for sym */ count = defmapFindAll (val->sym, pc, &oldval); //fprintf (stderr, "%d defs for sym %s\n", count, strFromSym (val->sym)); if (count == 1) { - if ((val->access.in_mask & oldval->access.mask) == val->access.in_mask) { + if ((val->acc.access.in_mask & oldval->acc.access.mask) == val->acc.access.in_mask) { val->in_val = oldval->val; } else { val->in_val = 0; @@ -11395,15 +11528,15 @@ static void assignValnums (pCode *pc) { /* multiple definition(s) found -- value not known (unless always the same valnum) */ assert (oldval); dummy = oldval->next; - mask = oldval->access.mask; + mask = oldval->acc.access.mask; val->in_val = oldval->val; while (dummy && (dummy->val == val->in_val)) { - mask &= dummy->access.mask; + mask &= dummy->acc.access.mask; dummy = dummy->next; } // while /* found other values or to restictive mask */ - if (dummy || ((mask & val->access.in_mask) != val->access.in_mask)) { + if (dummy || ((mask & val->acc.access.in_mask) != val->acc.access.in_mask)) { val->in_val = 0; } } @@ -11457,13 +11590,13 @@ static void assignValnums (pCode *pc) { case POC_XORLW: /* modifies STATUS (Z,N) */ /* can be optimized iff WREG contains a known literal (0x100 - 0x1FF) */ if (pci->pcop->type == PO_LITERAL) { - lit = (unsigned char) PCOL(pci->pcop)->lit; int vallit = -1; + lit = (unsigned char) PCOL(pci->pcop)->lit; val = defmapCurr (list, SPO_WREG, pc); if (val) vallit = litFromValnum (val->in_val); if (vallit != -1) { /* xxxLW , WREG contains a known literal */ - fprintf (stderr, "%s 0x%02x, WREG: 0x%x\n", pci->mnemonic, lit, vallit); + //fprintf (stderr, "%s 0x%02x, WREG: 0x%x\n", pci->mnemonic, lit, vallit); if (pci->op == POC_ANDLW) { lit &= vallit; } else if (pci->op == POC_IORLW) { @@ -11494,7 +11627,7 @@ static void assignValnums (pCode *pc) { val = defmapCurr (list, pic16_fsrsym_idx[lit][0], pc); if (val && (val->in_val != 0) && (val->in_val == val->val)) { - fprintf (stderr, "FSR%dL already set up correctly at %p (%x)\n", lit, pc, val->val); + //fprintf (stderr, "FSR%dL already set up correctly at %p (%x)\n", lit, pc, val->val); } else { /* cannot remove this LFSR */ ok = 0; @@ -11502,7 +11635,7 @@ static void assignValnums (pCode *pc) { val = defmapCurr (list, pic16_fsrsym_idx[lit][1], pc); if (val && (val->in_val != 0) && (val->in_val == val->val)) { - fprintf (stderr, "FSR%dH already set up correctly at %p (%x)\n", lit, pc, val->val); + //fprintf (stderr, "FSR%dH already set up correctly at %p (%x)\n", lit, pc, val->val); } else { ok = 0; } // if @@ -11532,14 +11665,18 @@ static void assignValnums (pCode *pc) { } if (pic16_debug_verbose || pic16_pcode_verbose) pic16_InsertCommentAfter (pc->prev, "=DF= MOVWF: replaced by CLRF/SETF"); pic16_pCodeReplace (pc, newpc); - defmapReplaceSymRef (pc, SPO_WREG, 0); + defmapReplaceSymRef (pc, SPO_WREG, 0, 1); pic16_fixDefmap (pc, newpc); pc = newpc; /* This breaks the defmap chain's references to pCodes... fix it! */ if (!val->prev) PCI(pc)->pcflow->defmap = val->next; - deleteDefmap (val); // delete reference to WREG as in value - val = NULL; + if (!val->acc.access.isWrite) { + deleteDefmap (val); // delete reference to WREG as in value + val = NULL; + } else { + val->acc.access.isRead = 0; // delete reference to WREG as in value + } oldval = PCI(pc)->pcflow->defmap; while (oldval) { if (oldval->pc == pc) oldval->pc = newpc; @@ -11575,9 +11712,9 @@ static void assignValnums (pCode *pc) { if (!isSpecial1 && pic16_regIsLocal (reg1) && val && oldval && !pic16_isAlive (SPO_STATUS, pc)) { //pc->print (stderr, pc); fprintf (stderr, "lit: %d (%x, %x)\n", lit, lit, val->in_val); if (lit == 0) { - newpc = pic16_newpCode (POC_CLRF, PCOR2(pci->pcop)->pcop2); + newpc = pic16_newpCode (POC_CLRF, PCOP2(pci->pcop)->pcopR); } else if (lit == 0x00ff) { - newpc = pic16_newpCode (POC_SETF, PCOR2(pci->pcop)->pcop2); + newpc = pic16_newpCode (POC_SETF, PCOP2(pci->pcop)->pcopR); } else { newpc = NULL; } @@ -11585,13 +11722,15 @@ static void assignValnums (pCode *pc) { pic16_InsertCommentAfter (pc->prev, "=DF= MOVFF: replaced by CRLF/SETF"); pic16_df_saved_bytes += PCI(pc)->isize - PCI(newpc)->isize; pic16_pCodeReplace (pc, newpc); - defmapReplaceSymRef (pc, sym1, 0); + defmapReplaceSymRef (pc, sym1, 0, 1); pic16_fixDefmap (pc, newpc); pc = newpc; break; // do not process instruction as MOVFF... } - } else if (!isSpecial1 && !isSpecial2 && pic16_regIsLocal (reg1) && pic16_regIsLocal (reg2)) { - if (val && oldval && (val->in_val != 0) && (val->in_val == oldval->in_val)) { + } else if (!isSpecial1 && !isSpecial2 + && pic16_regIsLocal (reg1) && pic16_regIsLocal (reg2) + && val && oldval && (val->in_val != 0)) { + if (val->in_val == oldval->in_val) { //fprintf (stderr, "MOVFF: F2 (%s) already set up correctly (%x) at %p\n", strFromSym (sym2), oldval->in_val, pc); pic16_safepCodeRemove (pc, "=DF= redundant MOVFF removed"); } else { @@ -11615,18 +11754,42 @@ static void assignValnums (pCode *pc) { if (copy->val && copy->val == val->in_val) { //fprintf (stderr, "found replacement symbol for %s (val %x) <-- %s (assigned %x @ %p)\n", strFromSym(sym1), val->in_val, strFromSym(copy->sym), copy->val, copy->pc); if (copy->sym == SPO_WREG) { - newpc = pic16_newpCode (POC_MOVWF, pic16_pCodeOpCopy (PCOR2(pci->pcop)->pcop2)); + newpc = pic16_newpCode (POC_MOVWF, pic16_pCodeOpCopy (PCOP2(pci->pcop)->pcopR)); } else { + pCodeOp *pcop = NULL; + /* the code below fails if we try to replace + * MOVFF PRODL, r0x03 + * MOVFF r0x03, PCLATU + * with + * MOVFF PRODL, PCLATU + * as copy(PRODL) contains has pc==NULL, by name fails... + */ + if (!copy->pc || !PCI(copy->pc)->pcop) break; + + if (copy->pc && PCI(copy->pc)->pcop) + pcop = PCI(copy->pc)->pcop; +#if 0 + /* This code is broken--see above. */ + else + { + const char *symname = strFromSym(copy->sym); + + assert( symname ); + pic16_InsertCommentAfter (pc->prev, "BUG-ME"); + pic16_InsertCommentAfter (pc->prev, "=DF= MOVFF: newpCodeOpregFromStr(%s)", (char *)symname); + //pcop = pic16_newpCodeOpRegFromStr((char *)symname); + } +#endif + assert( pcop ); newpc = pic16_newpCode(POC_MOVFF, pic16_popGet2p( -// /*TODO: change to copy->pc's out symbol*/pic16_pCodeOpCopy (pci->pcop), - pic16_pCodeOpCopy (PCI(copy->pc)->pcop), - pic16_pCodeOpCopy (PCOR2(pci->pcop)->pcop2))); + pcop, + pic16_pCodeOpCopy (PCOP2(pci->pcop)->pcopR))); } pic16_InsertCommentAfter (pc->prev, "=DF= MOVFF: SRC op %s replaced by %s", strFromSym(sym1), strFromSym(copy->sym)); pic16_df_saved_bytes += PCI(pc)->isize - PCI(newpc)->isize; pic16_pCodeReplace (pc, newpc); - assert (val->sym == sym1 && val->access.isRead && !val->access.isWrite); - defmapReplaceSymRef (pc, sym1, copy->sym); + assert (val->sym == sym1 && val->acc.access.isRead && !val->acc.access.isWrite); + defmapReplaceSymRef (pc, sym1, copy->sym, 1); pic16_fixDefmap (pc, newpc); pc = newpc; } @@ -11825,166 +11988,6 @@ static void pic16_createDF (pBlock *pb) { #endif } - -/* ======================================================================= */ -/* === DEPRECATED CONTROL FLOW CREATION ROUTINES ========================= */ -/* ======================================================================= */ - -#if 0 - -/* connect pCode f anf t via their to/from pBranches */ -static void pic16_pCodeLink (pCode *f, pCode *t) { - pBranch *br; - pCodeInstruction *_f, *_t; - - if (!f || !t) return; - -#if 0 - fprintf (stderr, "linking:\n"); - f->print(stderr, f); - f->print(stderr, t); -#endif - - assert (isPCI(f) || isPCAD(f)); - assert (isPCI(t) || isPCAD(t)); - _f = PCI(f); - _t = PCI(t); - - /* define t to be CF successor of f */ - br = Safe_malloc (sizeof (pBranch)); - br->pc = t; - br->next = NULL; - _f->to = pic16_pBranchAppend (_f->to, br); - - /* define f to be CF predecessor of t */ - br = Safe_malloc (sizeof (pBranch)); - br->pc = f; - br->next = NULL; - _t->from = pic16_pBranchAppend (_t->from, br); - - /* also update pcflow information */ - if (_f->pcflow && _t->pcflow && _f->pcflow != _t->pcflow) { - //fprintf (stderr, "creating flow %p --> %p\n", _f->pcflow, _t->pcflow); - LinkFlow_pCode (_f, _t); - } // if -} - -static void pic16_destructCF (pBlock *pb) { - pCode *pc; - pBranch *br; - - /* remove old CF information */ - pc = pb->pcHead; - while (pc) { - if (isPCI(pc)) { - while (PCI(pc)->to) { - br = PCI(pc)->to->next; - Safe_free (PCI(pc)->to); - PCI(pc)->to = br; - } // while - while (PCI(pc)->from) { - br = PCI(pc)->from->next; - Safe_free (PCI(pc)->from); - PCI(pc)->from = br; - } - } else if (isPCFL(pc)) { - deleteSet (&PCFL(pc)->to); - deleteSet (&PCFL(pc)->from); - } - pc = pc->next; - } - - releaseStack (); -} - -/* Set up pCodeInstruction's to and from pBranches. */ -static void pic16_createCF (pBlock *pb) { - pCode *pc; - pCode *next, *dest; - char *label; - - //fprintf (stderr, "creating CF for %p\n", pb); - - pic16_destructCF (pb); - - /* check pBlock: do not analyze pBlocks with ASMDIRs (for now...) */ - if (pic16_pBlockHasAsmdirs (pb)) { - //fprintf (stderr, "%s: pBlock contains ASMDIRs -- data flow analysis not performed!\n", __FUNCTION__); - return; - } - - pc = pic16_findNextInstruction(pb->pcHead); - while (pc) { - next = pic16_findNextInstruction(pc->next); - if (isPCI_SKIP(pc)) { - pic16_pCodeLink(pc, next); - pic16_pCodeLink(pc, pic16_findNextInstruction(next->next)); - } else if (isPCI_BRANCH(pc)) { - // Bcc, BRA, CALL, GOTO - if (PCI(pc)->pcop) { - switch (PCI(pc)->pcop->type) { - case PO_LABEL: - label = PCOLAB(PCI(pc)->pcop)->pcop.name; - dest = findLabelinpBlock (pc->pb, PCOLAB(PCI(pc)->pcop)); - break; - - case PO_STR: - /* needed for GOTO ___irq_handler */ - label = PCI(pc)->pcop->name; - dest = NULL; - break; - - default: - assert (0 && "invalid label format"); - break; - } // switch - } else { - label = "NO PCOP"; - dest = NULL; - } - - switch (PCI(pc)->op) { - case POC_BRA: - case POC_GOTO: - if (dest != NULL) { - pic16_pCodeLink(pc, dest); - } else { - //fprintf (stderr, "jump target \"%s\" not found!\n", label); - } - break; - case POC_CALL: - case POC_RETURN: - case POC_RETFIE: - pic16_pCodeLink(pc, next); - break; - case POC_BC: - case POC_BNC: - case POC_BZ: - case POC_BNZ: - case POC_BN: - case POC_BNN: - case POC_BOV: - case POC_BNOV: - if (dest != NULL) { - pic16_pCodeLink(pc, dest); - } else { - //fprintf (stderr, "jump target \"%s\"not found!\n", label); - } - pic16_pCodeLink(pc, next); - break; - default: - fprintf (stderr, "BRANCH instruction: %s\n", PCI(pc)->mnemonic); - assert (0 && "unhandled branch instruction"); - break; - } // switch - } else { - pic16_pCodeLink (pc, next); - } - pc = next; - } // while -} -#endif - /* ======================================================================== */ /* === VCG DUMPER ROUTINES ================================================ */ /* ======================================================================== */ @@ -12059,7 +12062,7 @@ static void pic16_vcg_close (FILE *of) { } #define BUF_SIZE 128 -#define pcTitle(pc) (snprintf (buf, BUF_SIZE, "n_%p, %p/%u", PCODE(pc), isPCI(pc) ? PCI(pc)->pcflow : NULL, PCODE(pc)->seq), &buf[0]) +#define pcTitle(pc) (SNPRINTF (buf, BUF_SIZE, "n_%p, %p/%u", PCODE(pc), isPCI(pc) ? PCI(pc)->pcflow : NULL, PCODE(pc)->seq), &buf[0]) #if 0 static int ptrcmp (const void *p1, const void *p2) { @@ -12110,7 +12113,7 @@ static void pic16_vcg_dumpnode (pCode *pc, FILE *of) { prev = map; do { - fprintf (of, "%s%c%c: val %4x|%4x & %02x|%02x, sym %s", (prev == map) ? "" : "\n", map->access.isRead ? 'R' : ' ', map->access.isWrite ? 'W' : ' ', map->in_val, map->val, map->access.in_mask, map->access.mask, strFromSym (map->sym)); + fprintf (of, "%s%c%c: val %4x|%4x & %02x|%02x, sym %s", (prev == map) ? "" : "\n", map->acc.access.isRead ? 'R' : ' ', map->acc.access.isWrite ? 'W' : ' ', map->in_val, map->val, map->acc.access.in_mask, map->acc.access.mask, strFromSym (map->sym)); prev = map; map = map->next; } while (map && prev->pc == map->pc); @@ -12236,9 +12239,9 @@ static void pic16_vcg_dump_default (pBlock *pb) { pc = pb->pcHead; while (pc && !isPCF(pc)) pc = pc->next; if (pc) { - snprintf (buf, BUF_SIZE, "%s_%s.vcg", PCF(pc)->modname, PCF(pc)->fname); + SNPRINTF (buf, BUF_SIZE, "%s_%s.vcg", PCF(pc)->modname, PCF(pc)->fname); } else { - snprintf (buf, BUF_SIZE, "pb_%p.vcg", pb); + SNPRINTF (buf, BUF_SIZE, "pb_%p.vcg", pb); } //fprintf (stderr, "now dumping %s\n", buf);