X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fpcode.c;h=e20eb83206fbce78c8fc6da68c39329c5f22ccd4;hb=998bc7b7fc11e191943ed839f790fff34b78df3b;hp=1ffd594317409e08e54bf5311e032fa30e82b8f5;hpb=97cd7990e16c7d3190086766a5089f5ea1b5e990;p=fw%2Fsdcc diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 1ffd5943..e20eb832 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -161,7 +161,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 */ @@ -3113,7 +3113,7 @@ void pic16_pCodeInitRegisters(void) /* */ /*-----------------------------------------------------------------*/ -int mnem2key(char const *mnem) +int mnem2key(unsigned char const *mnem) { int key = 0; @@ -3856,7 +3856,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 ); } @@ -3869,7 +3869,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 ); @@ -4244,26 +4244,28 @@ pCodeOp *pic16_newpCodeOpBit_simple (struct asmop *op, int offs, int bit) 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); } } + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = r; pcop->type = PCOR(pcop)->r->pc_type; return pcop; @@ -4385,12 +4387,18 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type) return pcop; } -#define DB_ITEMS_PER_LINE 8 +/* 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; @@ -4470,7 +4478,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); } @@ -4480,12 +4488,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); @@ -5911,7 +5934,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) @@ -9394,6 +9417,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; @@ -9424,12 +9450,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); @@ -9610,7 +9677,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; } @@ -9621,7 +9688,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; } @@ -10321,6 +10388,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; } @@ -10556,6 +10624,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: @@ -10668,7 +10738,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; @@ -10890,8 +10965,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... @@ -11553,7 +11628,7 @@ static void assignValnums (pCode *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) { @@ -11584,7 +11659,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; @@ -11592,7 +11667,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 @@ -11919,166 +11994,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 ================================================ */ /* ======================================================================== */