X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fpcodepeep.c;h=ec373e3358477a89c119be5c21a0e67899355907;hb=53aa65126ec2bd463145ebbeacac554196789b53;hp=df81ff9ee4680429253bf0e6323793ed3c1d5e70;hpb=437d64783e5a2f4a6cb2f096627d57f5a9fa734f;p=fw%2Fsdcc diff --git a/src/pic16/pcodepeep.c b/src/pic16/pcodepeep.c index df81ff9e..ec373e33 100644 --- a/src/pic16/pcodepeep.c +++ b/src/pic16/pcodepeep.c @@ -1,6 +1,7 @@ /*------------------------------------------------------------------------- - pcodepeep.c - post code generation + pcodepeep.c - post code generation + Written By - Scott Dattalo scott@dattalo.com Ported to PIC16 By - Martin Dubuc m.dubuc@rogers.com @@ -24,30 +25,28 @@ #include "common.h" // Include everything in the SDCC src directory #include "newalloc.h" + //#define PCODE_DEBUG + #include "pcode.h" #include "pcodeflow.h" #include "ralloc.h" -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - pCodeOp *pic16_popCopyGPR2Bit(pCodeOpReg *pc, int bitval); pCodeOp *pic16_newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype); +pCodeOp *pic16_newpCodeOpWild2(int id, int id2, pCodeWildBlock *pcwb, pCodeOp *subtype, pCodeOp *subtype2); pCode *pic16_newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label); pCode * pic16_findNextInstruction(pCode *pc); int pic16_getpCode(char *mnem,int dest); int pic16_getpCodePeepCommand(char *cmd); void pic16_pBlockMergeLabels(pBlock *pb); -char *pCode2str(char *str, int size, pCode *pc); -char *pic16_get_op( pCodeOp *pcop,char *buf,int buf_size); +char *pic16_pCode2str(char *str, int size, pCode *pc); +//char *pic16_get_op(pCodeOp *pcop,char *buf, size_t buf_size); +pCodeOp *pic16_popCombine2(pCodeOp *, pCodeOp *, int); extern pCodeInstruction *pic16Mnemonics[]; - +static int parsing_peeps=1; #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT)) @@ -151,7 +150,7 @@ typedef struct parsedPattern { #define MAX_PARSEDPATARR 50 parsedPattern parsedPatArr[MAX_PARSEDPATARR]; -static unsigned int parsedPatIdx=0; +//static unsigned int parsedPatIdx=0; typedef enum { @@ -202,7 +201,10 @@ typedef enum { ALT_MNEM1B, ALT_MNEM2, ALT_MNEM2A, - ALT_MNEM3 + ALT_MNEM2B, + ALT_MNEM3, + ALT_MNEM4, + ALT_MNEM4a } altPatterns; static char alt_comment[] = { PCP_COMMENT, 0}; @@ -214,7 +216,10 @@ static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0}; static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0}; static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0}; static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0}; +static char alt_mnem2b[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_WILDVAR, 0}; static char alt_mnem3[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0}; +static char alt_mnem4[] = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_STR, 0}; // for lfsr 0 , name +static char alt_mnem4a[] = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_NUMBER, 0}; // for lfsr 0 , value static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb); static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb); @@ -225,12 +230,19 @@ static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb); static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb); static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb); static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb); +static void * cvt_altpat_mnem2b(void *pp, pCodeWildBlock *pcwb); static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb); +static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb); +static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb); +/* NOTE: Order is important in the following table */ static pcPattern altArr[] = { {ALT_LABEL, alt_label, cvt_altpat_label}, {ALT_COMMENT, alt_comment,cvt_altpat_comment}, + {ALT_MNEM4a, alt_mnem4a, cvt_altpat_mnem4a}, + {ALT_MNEM4, alt_mnem4, cvt_altpat_mnem4}, {ALT_MNEM3, alt_mnem3, cvt_altpat_mnem3}, + {ALT_MNEM2B, alt_mnem2b, cvt_altpat_mnem2b}, {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a}, {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2}, {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b}, @@ -258,7 +270,7 @@ static int cvt_extract_destination(parsedPattern *pp) // just check first letter for now - if(toupper(*pp->pct[0].tok.s) == 'F') + if(toupper((unsigned char)*pp->pct[0].tok.s) == 'F') return 1; } else if (pp->pct[0].tt == PCT_NUMBER) { @@ -289,14 +301,14 @@ static pCodeOp *cvt_extract_status(char *reg, char *bit) if(len == 1) { // check C,Z - if(toupper(*bit) == 'C') + if(toupper((unsigned char)*bit) == 'C') return PCOP(pic16_popCopyGPR2Bit(&pic16_pc_status,PIC_C_BIT)); - if(toupper(*bit) == 'Z') + if(toupper((unsigned char)*bit) == 'Z') return PCOP(pic16_popCopyGPR2Bit(&pic16_pc_status,PIC_Z_BIT)); } // Check DC - if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C') + if(len ==2 && toupper((unsigned char)bit[0]) == 'D' && toupper((unsigned char)bit[1]) == 'C') return PCOP(pic16_popCopyGPR2Bit(&pic16_pc_status,PIC_DC_BIT)); return NULL; @@ -433,8 +445,10 @@ static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb) if(pic16Mnemonics[opcode]->isBitInst) pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_BIT); - else - pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER); + else { +// fprintf(stderr, "%s:%d tok.s= %s\n", __FILE__, __LINE__, p[1].pct[0].tok.s); + pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_STR); //GPR_REGISTER); + } pci = PCI(pic16_newpCode(opcode, pcosubtype)); @@ -493,7 +507,7 @@ static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb) } if(pic16Mnemonics[opcode]->isBitInst) - pcosubtype = pic16_newpCodeOpBit(NULL,-1,0); + pcosubtype = pic16_newpCodeOpBit(NULL,-1,0, PO_GPR_REGISTER); else pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER); @@ -566,7 +580,6 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb) p[3].pct[0].tok.s, dest)); - opcode = pic16_getpCode(p->pct[0].tok.s,dest); if(opcode < 0) { fprintf(stderr, "Bad mnemonic\n"); @@ -580,8 +593,15 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb) return NULL; } + } else + if(pic16Mnemonics[opcode]->is2MemOp) { + /* support for movff instruction */ + pcosubtype = pic16_popCombine2( + pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER), + pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0); } else pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER); + pci = PCI(pic16_newpCode(opcode,pcosubtype)); @@ -611,7 +631,7 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) int dest; pCodeInstruction *pci=NULL; - pCodeOp *pcosubtype; + pCodeOp *pcosubtype, *pcosubtype2; if(!pcwb) { fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__); @@ -626,6 +646,14 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) p[3].pct[0].tok.s, dest)); +#if 0 + fprintf(stderr,"altpat_mnem2a %s var %d destination %s(%d)\n", + p->pct[0].tok.s, + p[1].pct[1].tok.n, + p[3].pct[0].tok.s, + dest); +#endif + opcode = pic16_getpCode(p->pct[0].tok.s,dest); if(opcode < 0) { @@ -633,14 +661,94 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) return NULL; } - if(pic16Mnemonics[opcode]->isBitInst) + if(pic16Mnemonics[opcode]->isBitInst) { pcosubtype = pic16_newpCodeOp(NULL,PO_BIT); + pcosubtype2 = NULL; + } else { +#if 0 + if(pic16Mnemonics[opcode]->is2MemOp) { + /* support for movff instruction */ + pcosubtype = pic16_newpCodeOp(NULL, PO_GPR_REGISTER); + pcosubtype2 = pic16_newpCodeOp(p[3].pct[0].tok.s, PO_STR); + } else { +#endif + pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER); pcosubtype2 = NULL; } + + + if(!pcosubtype2) + pci = PCI(pic16_newpCode(opcode, + pic16_newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype))); else - pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER); + pci = PCI(pic16_newpCode(opcode, + pic16_newpCodeOpWild2(p[1].pct[1].tok.n, p[3].pct[1].tok.n, pcwb, pcosubtype, pcosubtype2))); + + /* Save the index of the maximum wildcard variable */ + //if(p[1].pct[1].tok.n > sMaxWildVar) + // sMaxWildVar = p[1].pct[1].tok.n; + + if(p[1].pct[1].tok.n > pcwb->nvars) + pcwb->nvars = p[1].pct[1].tok.n; + + if(!pci) + fprintf(stderr,"couldn't find mnemonic\n"); + + return pci; + +} + +/*-----------------------------------------------------------------*/ +/* cvt_altpat_mem2b - convert assembly line type to a pCode */ +/* instruction with 2 wild operands */ +/* */ +/* pp[0] - mnem */ +/* pp[1] - wild var */ +/* pp[2] - comma */ +/* pp[3] - wild var */ +/* */ +/*-----------------------------------------------------------------*/ +static void * cvt_altpat_mnem2b(void *pp,pCodeWildBlock *pcwb) +{ + parsedPattern *p = pp; + int opcode; + int dest; + pCodeInstruction *pci=NULL; + pCodeOp *pcosubtype, *pcosubtype2; + + if(!pcwb) { + fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__); + return NULL; + } + + dest = cvt_extract_destination(&p[3]); + + DFPRINTF((stderr,"altpat_mnem2b %s src %d dst (%d)\n", + p->pct[0].tok.s, + p[1].pct[1].tok.n, + p[3].pct[1].tok.n)); + +#if 0 + fprintf(stderr,"altpat_mnem2b %s src: %d dst: %d\n", + p->pct[0].tok.s, + p[1].pct[1].tok.n, + p[3].pct[1].tok.n); +#endif + + opcode = pic16_getpCode(p->pct[0].tok.s,dest); + if(opcode < 0) { + fprintf(stderr, "Bad mnemonic\n"); + return NULL; + } + + if(pic16Mnemonics[opcode]->is2MemOp) { + /* support for movff instruction */ + pcosubtype = pic16_newpCodeOp(NULL, PO_GPR_REGISTER); + pcosubtype2 = pic16_newpCodeOp(NULL, PO_GPR_REGISTER); + } else pcosubtype = pcosubtype2 = NULL; pci = PCI(pic16_newpCode(opcode, - pic16_newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype))); + pic16_newpCodeOpWild2(p[1].pct[1].tok.n, p[3].pct[1].tok.n, + pcwb, pcosubtype, pcosubtype2))); /* Save the index of the maximum wildcard variable */ //if(p[1].pct[1].tok.n > sMaxWildVar) @@ -696,7 +804,7 @@ static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb) //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s); //if(pcosubtype == NULL) { - pcosubtype = pic16_newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0); + pcosubtype = pic16_newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0, PO_GPR_REGISTER); //} } else pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER); @@ -715,6 +823,110 @@ static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb) } +/*-----------------------------------------------------------------*/ +/* cvt_altpat_mem4 - convert assembly line type to a pCode */ +/* This rule is for lfsr instruction */ +/* */ +/* */ +/* pp[0] - mnem */ +/* pp[1] - number */ +/* pp[2] - comma */ +/* pp[3] - source */ +/* */ +/*-----------------------------------------------------------------*/ +static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb) +{ + parsedPattern *p = pp; + int opcode; + int dest; // or could be bit position in the register + + pCodeInstruction *pci=NULL; + pCodeOp *pcosubtype=NULL; + + dest = cvt_extract_destination(&p[3]); + + DFPRINTF((stderr,"altpat_mnem4 %s fsr %d source %s\n", + p->pct[0].tok.s, + p[1].pct[0].tok.n, + p[3].pct[0].tok.s)); + + opcode = pic16_getpCode(p->pct[0].tok.s,0); + if(opcode < 0) { + fprintf(stderr, "Bad mnemonic\n"); + return NULL; + } + DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode)); + + if(pic16Mnemonics[opcode]->is2LitOp) { + pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOp(p[3].pct[0].tok.s, PO_STR)); + } + + if(pcosubtype == NULL) { + fprintf(stderr, "Bad operand\n"); + return NULL; + } + + pci = PCI(pic16_newpCode(opcode, pcosubtype)); + + if(!pci) + fprintf(stderr,"couldn't find mnemonic\n"); + + return pci; + +} + +/*-----------------------------------------------------------------*/ +/* cvt_altpat_mem4a - convert assembly line type to a pCode */ +/* This rule is for lfsr instruction */ +/* */ +/* */ +/* pp[0] - mnem */ +/* pp[1] - number */ +/* pp[2] - comma */ +/* pp[3] - value */ +/* */ +/*-----------------------------------------------------------------*/ +static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb) +{ + parsedPattern *p = pp; + int opcode; + int dest; // or could be bit position in the register + + pCodeInstruction *pci=NULL; + pCodeOp *pcosubtype=NULL; + + dest = cvt_extract_destination(&p[3]); + + DFPRINTF((stderr,"altpat_mnem4a %s fsr %d value 0x%02x\n", + p->pct[0].tok.s, + p[1].pct[0].tok.n, + p[3].pct[0].tok.n)); + + opcode = pic16_getpCode(p->pct[0].tok.s,0); + if(opcode < 0) { + fprintf(stderr, "Bad mnemonic\n"); + return NULL; + } + DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode)); + + if(pic16Mnemonics[opcode]->is2LitOp) { + pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOpLit(p[3].pct[0].tok.n)); + } + + if(pcosubtype == NULL) { + fprintf(stderr, "Bad operand\n"); + return NULL; + } + + pci = PCI(pic16_newpCode(opcode, pcosubtype)); + + if(!pci) + fprintf(stderr,"couldn't find mnemonic\n"); + + return pci; + +} + /*-----------------------------------------------------------------*/ /* tokenizeLineNode - Convert a string (of char's) that was parsed */ /* by SDCCpeeph.c into a string of tokens. */ @@ -741,18 +953,18 @@ static void tokenizeLineNode(char *ln) if(!ln || !*ln) return; +// fprintf(stderr, "%s:%d: processing %s\n", __FILE__, __LINE__, ln); while(*ln) { - - if(isspace(*ln)) { + if(isspace((unsigned char)*ln)) { // add a SPACE token and eat the extra spaces. tokArr[tokIdx++].tt = PCT_SPACE; - while (isspace (*ln)) + while (isspace ((unsigned char)*ln)) ln++; continue; } - if(isdigit(*ln)) { + if(isdigit((unsigned char)*ln)) { tokArr[tokIdx].tt = PCT_NUMBER; tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0); @@ -784,12 +996,12 @@ static void tokenizeLineNode(char *ln) break; - default: - if(isalpha(*ln) || (*ln == '_') ) { + default: // hack to allow : goto $ + if(isalpha((unsigned char)*ln) || (*ln == '_') || (!parsing_peeps && (*ln == '$'))) { char buffer[50]; int i=0; - while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49) + while( (isalpha((unsigned char)*ln) || isdigit((unsigned char)*ln) || (*ln == '_') || (*ln == '$')) && i<49) buffer[i++] = *ln++; ln--; @@ -799,10 +1011,12 @@ static void tokenizeLineNode(char *ln) tokArr[tokIdx++].tt = PCT_STRING; } else { - fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n"); - fprintf(stderr, "Line: %s\n",lnstart); - fprintf(stderr, "Token: '%c'\n",*ln); - exit(1); + if(parsing_peeps) { + fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n"); + fprintf(stderr, "Line: %s\n",lnstart); + fprintf(stderr, "Token: '%c'\n",*ln); + exit(1); + } } } @@ -886,7 +1100,7 @@ static int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens) return (i+1); } - //dump1Token(*pat); DFPRINTF((stderr,"\n")); +// dump1Token(*pat); fputc('\n', stderr); DFPRINTF((stderr,"\n")); if(pct->tt != *pat) return 0; @@ -914,11 +1128,11 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens) while(i < max_tokens) { if(*pct == 0) { - //DFPRINTF((stderr,"matched\n")); + DFPRINTF((stderr,"matched\n")); return i; } - //dump1Token(*pat); DFPRINTF((stderr,"\n")); +// dump1Token(*pat); DFPRINTF((stderr,"\n")); if( !pat || !pat->pcp ) return 0; @@ -926,7 +1140,7 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens) if (pat->pcp->pt != *pct) return 0; - //DFPRINTF((stderr," pct=%d\n",*pct)); + DFPRINTF((stderr," pct=%d\n",*pct)); pct++; pat++; i++; @@ -1121,7 +1335,7 @@ static int parseTokens(pCodeWildBlock *pcwb, pCode **pcret) parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx]; lparsedPatIdx++; - //dump1Token(tokArr[ltokIdx].tt); +// dump1Token(tokArr[ltokIdx].tt); if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) { DFPRINTF((stderr," reached end \n")); @@ -1198,6 +1412,7 @@ static void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb) for( ; ln; ln = ln->next) { //DFPRINTF((stderr,"%s\n",ln->line)); +// fprintf(stderr, "peep rule : %s\n", ln->line); tokenizeLineNode(ln->line); @@ -1205,7 +1420,7 @@ static void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb) int i; fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line); fprintf(stderr,"Tokens:\n"); - for(i=0; i<5; i++) + for(i=0; i<8; i++) dump1Token(tokArr[i].tt); fputc('\n',stderr); exit (1); @@ -1214,9 +1429,10 @@ static void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb) } /*-----------------------------------------------------------------*/ -/* */ +/* pic16_AssembleLine - parse line and return the pCode equivalent */ +/* peeps=1 if parsing peep rules, 0 otherwise */ /*-----------------------------------------------------------------*/ -pCode *pic16_AssembleLine(char *line) +pCode *pic16_AssembleLine(char *line, int peeps) { pCode *pc=NULL; @@ -1225,11 +1441,18 @@ pCode *pic16_AssembleLine(char *line) return NULL; } + parsing_peeps = peeps; + tokenizeLineNode(line); if(parseTokens(NULL,&pc)) fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line); + else { + DFPRINTF((stderr, "pc= %p\n", pc)); +// if(pc)pc->print(stderr, pc); + } + parsing_peeps = 1; return pc; } @@ -1349,7 +1572,7 @@ void pic16_peepRules2pCode(peepRule *rules) peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target); //DFPRINTF((stderr,"finished target, here it is in pcode form:\n")); - //pic16_printpBlock(stderr, currentRule->target.pb); +// pic16_printpBlock(stderr, currentRule->target.pb); //DFPRINTF((stderr,"target with labels merged:\n")); //pic16_pBlockMergeLabels(curBlock); @@ -1400,7 +1623,7 @@ void pic16_peepRules2pCode(peepRule *rules) } } - +#if 0 static void printpCodeString(FILE *of, pCode *pc, int max) { int i=0; @@ -1410,7 +1633,7 @@ static void printpCodeString(FILE *of, pCode *pc, int max) pc = pc->next; } } - +#endif /*-----------------------------------------------------------------*/ /* _DLL * DLL_append */ /* */ @@ -1510,17 +1733,18 @@ int pic16_pCodeSearchCondition(pCode *pc, unsigned int cond) *-----------------------------------------------------------------*/ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) { - char b[50], *n2; + char b[1024], *n2; if(!pcops || !pcopd) return 0; -/* - fprintf(stderr," Comparing operands %s", + +#if 0 + fprintf(stderr,"%s:%d Comparing operands %s", __FILE__, __LINE__, pic16_get_op( pcops,NULL,0)); fprintf(stderr," to %s\n", pic16_get_op( pcopd,NULL,0)); -*/ +#endif if(pcops->type != pcopd->type) { //fprintf(stderr," - fail - diff types\n"); @@ -1535,20 +1759,20 @@ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) return 0; } - b[0]=0; - pic16_get_op(pcops,b,50); + memset(b, 0, sizeof(b) ); //b[0]=0; + pic16_get_op(pcops,b, sizeof(b) ); n2 = pic16_get_op(pcopd,NULL,0); if( !n2 || strcmp(b,n2)) { - //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) ); +// fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) ); return 0; // different names } switch(pcops->type) { case PO_DIR: if( PCOR(pcops)->instance != PCOR(pcopd)->instance) { - //fprintf(stderr, " - fail different instances\n"); +// fprintf(stderr, " - fail different instances\n"); return 0; } break; @@ -1647,7 +1871,8 @@ static int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) { int index; // index into wild card arrays - + int havematch=0; + /* one-for-one match. Here the source and destination opcodes * are not wild. However, there may be a label or a wild operand */ @@ -1676,7 +1901,8 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) /* Compare the operands */ if(PCI(pcd)->pcop) { - if (PCI(pcd)->pcop->type == PO_WILD) { + /* assert that optimizations do not touch operations that work on SFRs or INDF registers */ + if ((PCI(pcd)->pcop->type == PO_WILD) && (!(PCI(pcs)->pcop) || ((PCI(pcs)->pcop->type != PO_SFR_REGISTER) && (PCI(pcs)->pcop->type != PO_INDF0)))) { index = PCOW(PCI(pcd)->pcop)->id; //DFPRINTF((stderr,"destination is wild\n")); #ifdef DEBUG_PCODEPEEP @@ -1687,6 +1913,7 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) #endif PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop; + havematch = -1; if(!peepBlock->target.wildpCodeOps[index]) { peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop; @@ -1702,17 +1929,18 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) ); */ - return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]); + havematch = pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]); +// return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]); } - { + if((havematch==-1) && PCI(pcs)->pcop) { char *n; switch(PCI(pcs)->pcop->type) { case PO_GPR_TEMP: case PO_FSR0: //case PO_INDF0: - n = PCOR(PCI(pcs)->pcop)->r->name; + n = PCOR(PCI(pcs)->pcop)->r->name; break; default: @@ -1724,20 +1952,93 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) else { DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n)); peepBlock->target.vars[index] = n; - return 1; + havematch = 1; +// return 1; } } + /* now check whether the second operand matches */ + /* assert that optimizations do not touch operations that work on SFRs or INDF registers */ + if(PCOW2(PCI(pcd)->pcop) && (PCOP2(PCI(pcd)->pcop)->pcopR->type == PO_WILD) && (!(PCOP2(PCI(pcs)->pcop)->pcopR) || ((PCOP2(PCI(pcs)->pcop)->pcopR->type != PO_SFR_REGISTER) && (PCOP2(PCI(pcs)->pcop)->pcopR) && (PCOP2(PCI(pcs)->pcop)->pcopR->type != PO_INDF0)))) { + +// fprintf(stderr, "%s:%d %s second operand is wild\n", __FILE__, __LINE__, __FUNCTION__); + + index = PCOW2(PCI(pcd)->pcop)->id; + //DFPRINTF((stderr,"destination is wild\n")); +#ifdef DEBUG_PCODEPEEP + if (index > peepBlock->nops) { + DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__)); + exit(1); + } +#endif + + PCOW2(PCI(pcd)->pcop)->matched = PCOP2(PCI(pcs)->pcop)->pcopR; + if(!peepBlock->target.wildpCodeOps[index]) { + peepBlock->target.wildpCodeOps[index] = PCOP2(PCI(pcs)->pcop)->pcopR; + + //if(PCI(pcs)->pcop->type == PO_GPR_TEMP) + + } else { + /* + pcs->print(stderr,pcs); + pcd->print(stderr,pcd); + + fprintf(stderr, "comparing operands of these instructions, result %d\n", + pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]) + ); + */ + + return ((havematch==1) && pCodeOpCompare(PCOP2(PCI(pcs)->pcop)->pcopR, + peepBlock->target.wildpCodeOps[index])); + } + + if(PCOP2(PCI(pcs)->pcop)->pcopR) { + char *n; + + switch(PCOP2(PCI(pcs)->pcop)->pcopR->type) { + case PO_GPR_TEMP: + case PO_FSR0: + //case PO_INDF0: + n = PCOR(PCOP2(PCI(pcs)->pcop)->pcopR)->r->name; + break; + default: + n = PCOP2(PCI(pcs)->pcop)->pcopR->name; + } + + if(peepBlock->target.vars[index]) + return (havematch && (strcmp(peepBlock->target.vars[index],n) == 0)); + else { + DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n)); + peepBlock->target.vars[index] = n; + return (havematch==1); //&& 1; + } + } + + } else if (PCOW2(PCI(pcd)->pcop) && (PCOP2(PCI(pcd)->pcop)->pcopR->type == PO_WILD) && PCOP2(PCI(pcs)->pcop)->pcopR) + { + return 0; + } else { + return havematch; + } +#if 0 + else if (PCI(pcd)->pcop->type == PO_LITERAL) { + return (havematch && + pCodeOpCompare(PCOR2(PCI(pcs)->pcop)->pcop2, PCOR2(PCI(pcd)->pcop)->pcop2)); + + } +#endif + } else if (PCI(pcd)->pcop->type == PO_LITERAL) { return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop); } + } + /* FIXME - need an else to check the case when the destination * isn't a wild card */ } else /* The pcd has no operand. Lines match if pcs has no operand either*/ return (PCI(pcs)->pcop == NULL); - } } /* Compare a wild instruction to a regular one. */ @@ -1874,13 +2175,58 @@ pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop) return NULL; switch(pcop->type) { + case PO_NONE: + case PO_STR: + case PO_REL_ADDR: + pcopnew = Safe_calloc(1, sizeof (pCodeOp)); + memcpy(pcopnew, pcop, sizeof (pCodeOp)); + break; + + case PO_W: + case PO_WREG: + case PO_STATUS: + case PO_BSR: + case PO_FSR0: + case PO_INDF0: + case PO_INTCON: + case PO_GPR_REGISTER: + case PO_GPR_TEMP: + case PO_SFR_REGISTER: + case PO_PCL: + case PO_PCLATH: + case PO_PCLATU: + case PO_PRODL: + case PO_PRODH: + case PO_DIR: + //DFPRINTF((stderr,"pCodeOpCopy GPR register\n")); + /* XXX: might also be pCodeOpReg2 -- that's why the two structs are identical */ + pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) ); + memcpy (pcopnew, pcop, sizeof(pCodeOpReg)); + break; + + case PO_LITERAL: + //DFPRINTF((stderr,"pCodeOpCopy lit\n")); + /* XXX: might also be pCodeOpLit2, that's why the two structs are identical... */ + pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) ); + memcpy (pcopnew, pcop, sizeof(pCodeOpLit)); + break; + + case PO_IMMEDIATE: + pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) ); + memcpy (pcopnew, pcop, sizeof(pCodeOpImmd)); + break; + + case PO_GPR_BIT: case PO_CRY: case PO_BIT: - //DFPRINTF((stderr,"pCodeOpCopy bit\n")); - pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) ); - PCORB(pcopnew)->bit = PCORB(pcop)->bit; - PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace; + pcopnew = Safe_calloc(1, sizeof (pCodeOpRegBit)); + memcpy (pcopnew, pcop, sizeof (pCodeOpRegBit)); + break; + case PO_LABEL: + //DFPRINTF((stderr,"pCodeOpCopy label\n")); + pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) ); + memcpy (pcopnew, pcop, sizeof (pCodeOpLabel)); break; case PO_WILD: @@ -1895,81 +2241,19 @@ pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop) pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]); //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name)); } - return pcopnew; break; - case PO_LABEL: - //DFPRINTF((stderr,"pCodeOpCopy label\n")); - pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) ); - PCOLAB(pcopnew)->key = PCOLAB(pcop)->key; - break; - - case PO_IMMEDIATE: - pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) ); - PCOI(pcopnew)->index = PCOI(pcop)->index; - PCOI(pcopnew)->offset = PCOI(pcop)->offset; - PCOI(pcopnew)->_const = PCOI(pcop)->_const; - break; - - case PO_LITERAL: - //DFPRINTF((stderr,"pCodeOpCopy lit\n")); - pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) ); - PCOL(pcopnew)->lit = PCOL(pcop)->lit; - break; - -#if 0 // mdubuc - To add - case PO_REL_ADDR: - break; -#endif - - case PO_GPR_BIT: - - pcopnew = pic16_newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace); - PCOR(pcopnew)->r = PCOR(pcop)->r; - PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx; - DFPRINTF((stderr," pCodeOpCopy Bit -register index\n")); + case PO_TWO_OPS: + pcopnew = pic16_newpCodeOp2( pic16_pCodeOpCopy( PCOP2(pcop)->pcopL ), + pic16_pCodeOpCopy( PCOP2(pcop)->pcopR ) ); return pcopnew; - break; - case PO_GPR_REGISTER: - case PO_GPR_TEMP: - case PO_FSR0: - case PO_INDF0: - //DFPRINTF((stderr,"pCodeOpCopy GPR register\n")); - pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) ); - PCOR(pcopnew)->r = PCOR(pcop)->r; - PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx; - PCOR(pcopnew)->instance = PCOR(pcop)->instance; - DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx)); - break; - - case PO_DIR: - //fprintf(stderr,"pCodeOpCopy PO_DIR\n"); - pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) ); - PCOR(pcopnew)->r = PCOR(pcop)->r; - PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx; - PCOR(pcopnew)->instance = PCOR(pcop)->instance; - break; - case PO_STATUS: - DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n")); - case PO_BSR: - DFPRINTF((stderr,"pCodeOpCopy PO_BSR\n")); - case PO_SFR_REGISTER: - case PO_STR: - case PO_NONE: - case PO_W: - case PO_WREG: - case PO_INTCON: - case PO_PCL: - case PO_PCLATH: - - //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type)); - pcopnew = Safe_calloc(1,sizeof(pCodeOp) ); - - } + default: + assert ( !"unhandled pCodeOp type copied" ); + } // switch - pcopnew->type = pcop->type; + /* strdup pcop->name (prevent access to shared but released memory) */ if(pcop->name) pcopnew->name = Safe_strdup(pcop->name); else @@ -2027,6 +2311,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) pCodeCSource *pc_cline=NULL; _DLL *peeprules; int matched; + pCode *pcr; peeprules = (_DLL *)peepSnippets; @@ -2066,7 +2351,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) if(!pcin && pct) { DFPRINTF((stderr," partial match... no more code\n")); - fprintf(stderr," partial match... no more code\n"); +// fprintf(stderr," partial match... no more code\n"); matched = 0; } if(!pct) { @@ -2091,7 +2376,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) (pic16_pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) ) matched = 0; - //fprintf(stderr," condition results = %d\n",pic16_pCodeSearchCondition(pcin,peepBlock->postFalseCond)); +// fprintf(stderr," condition results = %d\n",pic16_pCodeSearchCondition(pcin,peepBlock->postFalseCond)); //if(!matched) fprintf(stderr,"failed on conditions\n"); @@ -2100,14 +2385,14 @@ int pic16_pCodePeepMatchRule(pCode *pc) if(matched) { pCode *pcprev; - pCode *pcr; +// pCode *pcr; /* We matched a rule! Now we have to go through and remove the inefficient code with the optimized version */ #ifdef PCODE_DEBUG DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n")); - printpCodeString(stderr,peepBlock->target.pb->pcHead,10); +// printpCodeString(stderr,peepBlock->target.pb->pcHead,10); DFPRINTF((stderr,"first thing matched\n")); pc->print(stderr,pc); if(pcin) { @@ -2124,16 +2409,16 @@ int pic16_pCodePeepMatchRule(pCode *pc) pcin->prev = pc->prev; -#if 0 +#if 1 { /* DEBUG */ /* Converted the deleted pCodes into comments */ - char buf[256]; + char buf[1024]; pCodeCSource *pc_cline2=NULL; - buf[0] = ';'; - buf[1] = '#'; +// buf[0] = ';'; + buf[0] = '#'; while(pc && pc!=pcin) { @@ -2147,7 +2432,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) } } - pCode2str(&buf[2], 254, pc); + pic16_pCode2str(&buf[1], sizeof( buf )-1, pc); pic16_pCodeInsertAfter(pcprev, pic16_newpCodeCharP(buf)); pcprev = pcprev->next; pc = pc->next; @@ -2161,6 +2446,8 @@ int pic16_pCodePeepMatchRule(pCode *pc) if(pcin) pCodeDeleteChain(pc,pcin); +// fprintf(stderr, "%s:%d rule matched\n", __FILE__, __LINE__); + /* Generate the replacement code */ pc = pcprev; pcr = peepBlock->replace.pb->pcHead; // This is the replacement code @@ -2175,6 +2462,7 @@ int pic16_pCodePeepMatchRule(pCode *pc) * Is it wild? */ if(PCI(pcr)->pcop->type == PO_WILD) { int index = PCOW(PCI(pcr)->pcop)->id; +// fprintf(stderr, "%s:%d replacing index= %d\n", __FUNCTION__, __LINE__, index); //DFPRINTF((stderr,"copying wildopcode\n")); if(peepBlock->target.wildpCodeOps[index]) pcop = pic16_pCodeOpCopy(peepBlock->target.wildpCodeOps[index]); @@ -2183,6 +2471,26 @@ int pic16_pCodePeepMatchRule(pCode *pc) } else pcop = pic16_pCodeOpCopy(PCI(pcr)->pcop); } + + if(PCI(pcr)->is2MemOp && PCOP2(PCI(pcr)->pcop)->pcopR) { + /* The replacing instruction has also a second operand. + * Is it wild? */ +// fprintf(stderr, "%s:%d pcop2= %p\n", __FILE__, __LINE__, PCOR2(PCI(pcr)->pcop)->pcop2); + if(PCOP2(PCI(pcr)->pcop)->pcopR->type == PO_WILD) { + int index = PCOW2(PCI(pcr)->pcop)->id; +// fprintf(stderr, "%s:%d replacing index= %d\n", __FUNCTION__, __LINE__, index); + //DFPRINTF((stderr,"copying wildopcode\n")); + if(peepBlock->target.wildpCodeOps[index]) + pcop = pic16_popCombine2(pic16_pCodeOpCopy(pcop), + pic16_pCodeOpCopy(peepBlock->target.wildpCodeOps[index]), 0); + else + DFPRINTF((stderr,"error, wildopcode in replace but not source?\n")); + } else + pcop = pic16_popCombine2(pic16_pCodeOpCopy(pcop), + pic16_pCodeOpCopy(PCOP2(PCI(pcr)->pcop)->pcopR), 0); + + } + //DFPRINTF((stderr,"inserting pCode\n")); pic16_pCodeInsertAfter(pc, pic16_newpCode(PCI(pcr)->op,pcop)); } else if (pcr->type == PC_WILD) {