X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fpcodepeep.c;h=81aabf13eca49699879a0b1b2db08da6e67a0e00;hb=3456dfdd9cd3a27e8b59645bf8f4bfb01515481d;hp=e23e667c712b5bc5cc9a53aeb1d25f57ae7f7056;hpb=d29d3bd3d0ba71cced0f534b9c08c41d042a5a38;p=fw%2Fsdcc diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index e23e667c..81aabf13 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -23,9 +23,9 @@ #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) @@ -37,17 +37,20 @@ pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval); -pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype); +pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype); pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label); pCode * findNextInstruction(pCode *pc); -char *Safe_strdup(char *str); int getpCode(char *mnem,int dest); +int getpCodePeepCommand(char *cmd); void pBlockMergeLabels(pBlock *pb); char *pCode2str(char *str, int size, pCode *pc); +char *get_op( pCodeOp *pcop,char *buf,int buf_size); extern pCodeInstruction *pic14Mnemonics[]; +#define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT)) + /****************************************************************/ /* * rootRules - defined in SDCCpeep.c @@ -90,7 +93,7 @@ static pCodePeepSnippets *peepSnippets=NULL; /* */ /****************************************************************/ -static pCodePeep *curPeep=NULL; +//static pCodePeep *curPeep=NULL; /****************************************************************/ /* */ @@ -98,7 +101,7 @@ static pCodePeep *curPeep=NULL; /* */ /****************************************************************/ -static pBlock *curBlock=NULL; +//static pBlock *curBlock=NULL; /****************************************************************/ @@ -107,8 +110,8 @@ static pBlock *curBlock=NULL; /* */ /****************************************************************/ -static int sMaxWildVar = 0; -static int sMaxWildMnem = 0; +//static int sMaxWildVar = 0; +//static int sMaxWildMnem = 0; typedef struct pCodeToken @@ -130,6 +133,8 @@ typedef enum { PCT_NULL=0, PCT_SPACE=1, PCT_PERCENT, + PCT_LESSTHAN, + PCT_GREATERTHAN, PCT_COLON, PCT_COMMA, PCT_COMMENT, @@ -171,7 +176,7 @@ static char pcpat_comment[] = {PCT_COMMENT, 0}; typedef struct pcPattern { char pt; // Pattern type char *tokens; // list of tokens that describe the pattern - void * (*f) (void *); + void * (*f) (void *,pCodeWildBlock *); } pcPattern; pcPattern pcpArr[] = { @@ -196,7 +201,8 @@ typedef enum { ALT_MNEM1A, ALT_MNEM1B, ALT_MNEM2, - ALT_MNEM2A + ALT_MNEM2A, + ALT_MNEM3 } altPatterns; static char alt_comment[] = { PCP_COMMENT, 0}; @@ -208,20 +214,23 @@ 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 void * cvt_altpat_label(void *pp); -static void * cvt_altpat_comment(void *pp); -static void * cvt_altpat_mnem0(void *pp); -static void * cvt_altpat_mnem0a(void *pp); -static void * cvt_altpat_mnem1(void *pp); -static void * cvt_altpat_mnem1a(void *pp); -static void * cvt_altpat_mnem1b(void *pp); -static void * cvt_altpat_mnem2(void *pp); -static void * cvt_altpat_mnem2a(void *pp); +static char alt_mnem3[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0}; + +static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb); +static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb); +static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb); +static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb); +static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb); +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_mnem3(void *pp,pCodeWildBlock *pcwb); pcPattern altArr[] = { {ALT_LABEL, alt_label, cvt_altpat_label}, {ALT_COMMENT, alt_comment,cvt_altpat_comment}, + {ALT_MNEM3, alt_mnem3, cvt_altpat_mnem3}, {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a}, {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2}, {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b}, @@ -304,12 +313,12 @@ static pCodeOp *cvt_extract_status(char *reg, char *bit) /* at this point, we wish to extract only the 'number' */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_label(void *pp) +static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; - fprintf(stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n); - return newpCodeLabel(-p->pct[1].tok.n); + DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n)); + return newpCodeLabel(NULL,-p->pct[1].tok.n); } @@ -321,29 +330,41 @@ static void * cvt_altpat_label(void *pp) /* */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_comment(void *pp) +static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; - fprintf(stderr,"altpat_comment = %s\n",p->pct[0].tok.s); + DFPRINTF((stderr,"altpat_comment = %s\n",p->pct[0].tok.s)); return newpCodeCharP(p->pct[0].tok.s); } /*-----------------------------------------------------------------*/ +/* cvt_altpat_mem0 - convert assembly line type to a wild pCode */ +/* instruction */ +/* */ +/* pp[0] - str */ +/* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem0(void *pp) +static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; pCodeInstruction *pci=NULL; - fprintf(stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s); + DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s)); opcode = getpCode(p->pct[0].tok.s,0); + if(opcode < 0) { - fprintf(stderr, "Bad mnemonic\n"); + /* look for special command strings like _NOTBITSKIP_ */ + + //fprintf(stderr, "Bad mnemonic\n"); + + opcode = getpCodePeepCommand(p->pct[0].tok.s); + //if(opcode > 0) + // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode); return NULL; } @@ -363,16 +384,19 @@ static void * cvt_altpat_mnem0(void *pp) /* pp[0] - wild var */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem0a(void *pp) +static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb) { parsedPattern *p = pp; - fprintf(stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n); + DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n)); /* Save the index of the maximum wildcard mnemonic */ - if(p[0].pct[1].tok.n > sMaxWildVar) - sMaxWildMnem = p[0].pct[1].tok.n; + //if(p[0].pct[1].tok.n > sMaxWildVar) + // sMaxWildMnem = p[0].pct[1].tok.n; + + if(p[0].pct[1].tok.n > pcwb->nwildpCodes) + pcwb->nwildpCodes = p[0].pct[1].tok.n; return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL); @@ -386,7 +410,7 @@ static void * cvt_altpat_mnem0a(void *pp) /* pp[1] - Operand */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem1(void *pp) +static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; @@ -395,15 +419,19 @@ static void * cvt_altpat_mnem1(void *pp) pCodeInstruction *pci=NULL; pCodeOp *pcosubtype; - fprintf(stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s); + DFPRINTF((stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s)); opcode = getpCode(p->pct[0].tok.s,0); if(opcode < 0) { - fprintf(stderr, "Bad mnemonic\n"); + //fprintf(stderr, "Bad mnemonic\n"); + opcode = getpCodePeepCommand(p->pct[0].tok.s); + //if(opcode > 0) + //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode); + return NULL; } - if(pic14Mnemonics[opcode]->bit_inst) + if(pic14Mnemonics[opcode]->isBitInst) pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT); else pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER); @@ -426,7 +454,7 @@ static void * cvt_altpat_mnem1(void *pp) /* pp[1] - wild var */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem1a(void *pp) +static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; @@ -434,26 +462,51 @@ static void * cvt_altpat_mnem1a(void *pp) pCodeInstruction *pci=NULL; pCodeOp *pcosubtype; - fprintf(stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n); + DFPRINTF((stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n)); opcode = getpCode(p->pct[0].tok.s,0); if(opcode < 0) { - fprintf(stderr, "Bad mnemonic\n"); - return NULL; + int cmd_id = getpCodePeepCommand(p->pct[0].tok.s); + pCode *pc=NULL; + + if(cmd_id<0) { + fprintf(stderr, "Bad mnemonic\n"); + return NULL; + } + + if(p[0].pct[1].tok.n > pcwb->nwildpCodes) + pcwb->nwildpCodes = p[0].pct[1].tok.n; + + pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL); + + switch(cmd_id) { + case NOTBITSKIP: + PCW(pc)->mustNotBeBitSkipInst = 1; + break; + case BITSKIP: + PCW(pc)->mustBeBitSkipInst = 1; + break; + case INVERTBITSKIP: + PCW(pc)->invertBitSkipInst = 1; + } + return pc; } - if(pic14Mnemonics[opcode]->bit_inst) + if(pic14Mnemonics[opcode]->isBitInst) pcosubtype = newpCodeOpBit(NULL,-1,0); else pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER); pci = PCI(newpCode(opcode, - newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype))); + newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype))); /* 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 > 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"); @@ -464,14 +517,14 @@ static void * cvt_altpat_mnem1a(void *pp) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem1b(void *pp) +static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; pCodeInstruction *pci=NULL; - fprintf(stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n); + DFPRINTF((stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n)); opcode = getpCode(p->pct[0].tok.s,0); if(opcode < 0) { @@ -490,7 +543,7 @@ static void * cvt_altpat_mnem1b(void *pp) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem2(void *pp) +static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; @@ -501,11 +554,11 @@ static void * cvt_altpat_mnem2(void *pp) dest = cvt_extract_destination(&p[3]); - fprintf(stderr,"altpat_mnem2 %s var %s destination %s(%d)\n", + DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n", p->pct[0].tok.s, p[1].pct[0].tok.s, p[3].pct[0].tok.s, - dest); + dest)); opcode = getpCode(p->pct[0].tok.s,dest); @@ -514,7 +567,7 @@ static void * cvt_altpat_mnem2(void *pp) return NULL; } - if(pic14Mnemonics[opcode]->bit_inst) { + if(pic14Mnemonics[opcode]->isBitInst) { pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s); if(pcosubtype == NULL) { fprintf(stderr, "bad operand?\n"); @@ -545,7 +598,7 @@ static void * cvt_altpat_mnem2(void *pp) /* pp[3] - destination */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem2a(void *pp) +static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; @@ -554,13 +607,18 @@ static void * cvt_altpat_mnem2a(void *pp) pCodeInstruction *pci=NULL; pCodeOp *pcosubtype; + if(!pcwb) { + fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__); + return NULL; + } + dest = cvt_extract_destination(&p[3]); - fprintf(stderr,"altpat_mnem2a %s var %d destination %s(%d)\n", + DFPRINTF((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); + dest)); opcode = getpCode(p->pct[0].tok.s,dest); @@ -569,18 +627,80 @@ static void * cvt_altpat_mnem2a(void *pp) return NULL; } - if(pic14Mnemonics[opcode]->bit_inst) + if(pic14Mnemonics[opcode]->isBitInst) pcosubtype = newpCodeOp(NULL,PO_BIT); else pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER); pci = PCI(newpCode(opcode, - newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype))); + newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype))); /* 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 > 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_mem3 - convert assembly line type to a pCode */ +/* This rule is for bsf/bcf type instructions */ +/* */ +/* */ +/* pp[0] - mnem */ +/* pp[1] - register */ +/* pp[2] - comma */ +/* pp[3] - number */ +/* */ +/*-----------------------------------------------------------------*/ +static void * cvt_altpat_mnem3(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_mnem3 %s var %s bit (%d)\n", + p->pct[0].tok.s, + p[1].pct[0].tok.s, + p[3].pct[0].tok.n)); + + + opcode = getpCode(p->pct[0].tok.s,0); + if(opcode < 0) { + fprintf(stderr, "Bad mnemonic\n"); + return NULL; + } + + + if(pic14Mnemonics[opcode]->isBitInst) { + //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s); + + //if(pcosubtype == NULL) { + pcosubtype = newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0); + //} + } else + pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER); + + if(pcosubtype == NULL) { + fprintf(stderr, "Bad operand\n"); + return NULL; + } + + pci = PCI(newpCode(opcode, pcosubtype)); if(!pci) fprintf(stderr,"couldn't find mnemonic\n"); @@ -608,13 +728,14 @@ static void * cvt_altpat_mnem2a(void *pp) static void tokenizeLineNode(char *ln) { - + char *lnstart=ln; tokIdx = 0; // Starting off at the beginning tokArr[0].tt = PCT_NULL; // and assume invalid character for first token. if(!ln || !*ln) return; + while(*ln) { if(isspace(*ln)) { @@ -638,6 +759,12 @@ static void tokenizeLineNode(char *ln) case '%': tokArr[tokIdx++].tt = PCT_PERCENT; break; + case '<': + tokArr[tokIdx++].tt = PCT_LESSTHAN; + break; + case '>': + tokArr[tokIdx++].tt = PCT_GREATERTHAN; + break; case ':': tokArr[tokIdx++].tt = PCT_COLON; break; @@ -652,11 +779,11 @@ static void tokenizeLineNode(char *ln) default: - if(isalpha(*ln)) { + if(isalpha(*ln) || (*ln == '_') ) { char buffer[50]; int i=0; - while( (isalpha(*ln) || isdigit(*ln)) && i<49) + while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49) buffer[i++] = *ln++; ln--; @@ -665,6 +792,11 @@ static void tokenizeLineNode(char *ln) tokArr[tokIdx].tok.s = Safe_strdup(buffer); 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); } } @@ -695,12 +827,16 @@ void dump1Token(pCodeTokens tt) fprintf(stderr, " space "); break; case PCT_PERCENT: - fprintf(stderr, " pct "); - fputc('%', stderr); + fprintf(stderr, " pct %%"); + break; + case PCT_LESSTHAN: + fprintf(stderr, " pct <"); + break; + case PCT_GREATERTHAN: + fprintf(stderr, " pct >"); break; case PCT_COLON: - fprintf(stderr, " col "); - fputc(':',stderr); + fprintf(stderr, " col :"); break; case PCT_COMMA: fprintf(stderr, " comma , "); @@ -721,6 +857,7 @@ void dump1Token(pCodeTokens tt) fprintf(stderr, " null "); } + } @@ -734,16 +871,16 @@ int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens) if(!pct || !pat || !*pat) return 0; - //fprintf(stderr,"comparing against:\n"); + //DFPRINTF((stderr,"comparing against:\n")); while(i < max_tokens) { if(*pat == 0){ - //fprintf(stderr,"matched\n"); + //DFPRINTF((stderr,"matched\n")); return (i+1); } - //dump1Token(*pat); fprintf(stderr,"\n"); + //dump1Token(*pat); DFPRINTF((stderr,"\n")); if(pct->tt != *pat) return 0; @@ -771,11 +908,11 @@ int altComparePattern( char *pct, parsedPattern *pat, int max_tokens) while(i < max_tokens) { if(*pct == 0) { - //fprintf(stderr,"matched\n"); + //DFPRINTF((stderr,"matched\n")); return i; } - //dump1Token(*pat); fprintf(stderr,"\n"); + //dump1Token(*pat); DFPRINTF((stderr,"\n")); if( !pat || !pat->pcp ) return 0; @@ -783,7 +920,7 @@ int altComparePattern( char *pct, parsedPattern *pat, int max_tokens) if (pat->pcp->pt != *pct) return 0; - //fprintf(stderr," pct=%d\n",*pct); + //DFPRINTF((stderr," pct=%d\n",*pct)); pct++; pat++; i++; @@ -824,18 +961,22 @@ int advTokIdx(int *v, int amt) /* pcode. */ /*-----------------------------------------------------------------*/ -void parseTokens(void) +int parseTokens(pCodeWildBlock *pcwb, pCode **pcret) { - unsigned i; pCode *pc; + int error = 0; if(!tokIdx) - return; - - for(i=0; i<=tokIdx; i++) - dump1Token(tokArr[i].tt); + return error; - fputc('\n',stderr); +#ifdef PCODE_DEBUG + { + unsigned i; + for(i=0; i<=tokIdx; i++) + dump1Token(tokArr[i].tt); + fputc('\n',stderr); + } +#endif { int lparsedPatIdx=0; @@ -881,32 +1022,32 @@ void parseTokens(void) switch(pcpArr[lpcpIdx].pt) { case PCP_LABEL: if(state == PS_START){ - fprintf(stderr," label\n"); + DFPRINTF((stderr," label\n")); state = PS_HAVE_LABEL; } else - fprintf(stderr," bad state (%d) for label\n",state); + DFPRINTF((stderr," bad state (%d) for label\n",state)); break; case PCP_STR: - fprintf(stderr," %s is",tokArr[ltokIdx].tok.s); + DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s)); switch(state) { case PS_START: case PS_HAVE_LABEL: - fprintf(stderr," mnem\n"); + DFPRINTF((stderr," mnem\n")); cPmnem = tokArr[ltokIdx].tok.s; state = PS_HAVE_MNEM; break; case PS_HAVE_MNEM: - fprintf(stderr," 1st operand\n"); + DFPRINTF((stderr," 1st operand\n")); cP1stop = tokArr[ltokIdx].tok.s; //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER); state = PS_HAVE_1OPERAND; break; case PS_HAVE_1OPERAND: - fprintf(stderr," error expecting comma\n"); + DFPRINTF((stderr," error expecting comma\n")); break; case PS_HAVE_COMMA: - fprintf(stderr," 2 operands\n"); + DFPRINTF((stderr," 2 operands\n")); cP2ndop = tokArr[ltokIdx].tok.s; break; case PS_HAVE_2OPERANDS: @@ -918,18 +1059,18 @@ void parseTokens(void) switch(state) { case PS_START: case PS_HAVE_LABEL: - fprintf(stderr," wild mnem\n"); + DFPRINTF((stderr," wild mnem\n")); state = PS_HAVE_MNEM; break; case PS_HAVE_MNEM: - fprintf(stderr," 1st operand is wild\n"); + DFPRINTF((stderr," 1st operand is wild\n")); state = PS_HAVE_1OPERAND; break; case PS_HAVE_1OPERAND: - fprintf(stderr," error expecting comma\n"); + DFPRINTF((stderr," error expecting comma\n")); break; case PS_HAVE_COMMA: - fprintf(stderr," 2nd operand is wild\n"); + DFPRINTF((stderr," 2nd operand is wild\n")); break; case PS_HAVE_2OPERANDS: break; @@ -943,14 +1084,14 @@ void parseTokens(void) fprintf(stderr," ERROR number\n"); break; case PS_HAVE_MNEM: - fprintf(stderr," 1st operand is a number\n"); + DFPRINTF((stderr," 1st operand is a number\n")); state = PS_HAVE_1OPERAND; break; case PS_HAVE_1OPERAND: fprintf(stderr," error expecting comma\n"); break; case PS_HAVE_COMMA: - fprintf(stderr," 2nd operand is a number\n"); + DFPRINTF((stderr," 2nd operand is a number\n")); break; case PS_HAVE_2OPERANDS: break; @@ -961,10 +1102,12 @@ void parseTokens(void) break; case PCP_COMMA: if(state == PS_HAVE_1OPERAND){ - fprintf(stderr," got a comma\n"); + DFPRINTF((stderr," got a comma\n")); state = PS_HAVE_COMMA; } else fprintf(stderr," unexpected comma\n"); + break; + } matching = 1; @@ -975,7 +1118,7 @@ void parseTokens(void) //dump1Token(tokArr[ltokIdx].tt); if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) { - fprintf(stderr," reached end \n"); + DFPRINTF((stderr," reached end \n")); matching = 0; //return; } @@ -996,12 +1139,21 @@ void parseTokens(void) if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) { if( altArr[k].f) { - pc = altArr[k].f(&parsedPatArr[j]); - if(pc && pc->print) - pc->print(stderr,pc); + pc = altArr[k].f(&parsedPatArr[j],pcwb); + //if(pc && pc->print) + // pc->print(stderr,pc); //if(pc && pc->destruct) pc->destruct(pc); dumps core? - if(curBlock && pc) - addpCode2pBlock(curBlock, pc); + + //if(curBlock && pc) + //addpCode2pBlock(curBlock, pc); + if(pc) { + if (pcret) { + *pcret = pc; + return 0; // Only accept one line for now. + } else + addpCode2pBlock(pcwb->pb, pc); + } else + error++; } j += c; } @@ -1010,28 +1162,28 @@ void parseTokens(void) while(j<=lparsedPatIdx && kf ) parsedPatArr[j].pcp->f(&parsedPatArr[j]); - fprintf(stderr," %d",parsedPatArr[j].pcp->pt); + DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt)); j++; } while(jnext) { - fprintf(stderr,"%s\n",ln->line); + //DFPRINTF((stderr,"%s\n",ln->line)); tokenizeLineNode(ln->line); - parseTokens(); + + if(parseTokens(pcwb,NULL)) { + int i; + fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line); + fprintf(stderr,"Tokens:\n"); + for(i=0; i<5; i++) + dump1Token(tokArr[i].tt); + fputc('\n',stderr); + exit (1); + } + } +} +/*-----------------------------------------------------------------*/ +/* */ +/*-----------------------------------------------------------------*/ +pCode *AssembleLine(char *line) +{ + pCode *pc=NULL; + + if(!line || !*line) { + fprintf(stderr,"WARNING returning NULL in AssembleLine\n"); + return NULL; } + + tokenizeLineNode(line); + + if(parseTokens(NULL,&pc)) + fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line); + + return pc; + } /*-----------------------------------------------------------------*/ /* peepRuleCondition */ /*-----------------------------------------------------------------*/ -static void peepRuleCondition(char *cond) +static void peepRuleCondition(char *cond, pCodePeep *pcp) { - if(!cond) + if(!cond || !pcp) return; - fprintf(stderr,"\nCondition: %s\n",cond); - + //DFPRINTF((stderr,"\nCondition: %s\n",cond)); /* brute force compares for now */ if(STRCASECMP(cond, "NZ") == 0) { - fprintf(stderr,"found NZ\n"); - curPeep->postFalseCond = PCC_Z; + //DFPRINTF((stderr,"found NZ\n")); + pcp->postFalseCond = PCC_Z; } } + + +void initpCodeWildBlock(pCodeWildBlock *pcwb) +{ + + // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock)); + + if(!pcwb) + return; + + pcwb->vars = NULL; + pcwb->wildpCodes = NULL; + pcwb->wildpCodeOps = NULL; + + pcwb->nvars = 0; + pcwb->nwildpCodes = 0; + pcwb->nops = 0; + +} + +void postinit_pCodeWildBlock(pCodeWildBlock *pcwb) +{ + + if(!pcwb) + return; + + pcwb->nvars+=2; + pcwb->nops = pcwb->nvars; + + pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *)); + pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *)); + + pcwb->nwildpCodes+=2; + pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *)); + +} + +void initpCodePeep(pCodePeep *pcp) +{ + + // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock)); + + if(!pcp) + return; + + initpCodeWildBlock(&pcp->target); + pcp->target.pb = newpCodeChain(NULL, 'W', NULL); + + initpCodeWildBlock(&pcp->replace); + pcp->replace.pb = newpCodeChain(NULL, 'W', NULL); + +} + /*-----------------------------------------------------------------*/ /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/ /* pCode. */ @@ -1077,13 +1310,17 @@ static void peepRuleCondition(char *cond) /* taking raw text to produce machine code, it produces pCode. */ /* */ /*-----------------------------------------------------------------*/ +extern void pic14initpCodePeepCommands(void); void peepRules2pCode(peepRule *rules) { peepRule *pr; + pCodePeep *currentRule; pCodePeepSnippets *pcps; + pic14initpCodePeepCommands(); + /* The rules are in a linked-list. Each rule has two portions */ /* There's the `target' and there's the `replace'. The target */ /* is compared against the SDCC generated code and if it */ @@ -1094,66 +1331,68 @@ void peepRules2pCode(peepRule *rules) for (pr = rules; pr; pr = pr->next) { - fprintf(stderr,"\nRule:\n\n"); + //DFPRINTF((stderr,"\nRule:\n\n")); pcps = Safe_calloc(1,sizeof(pCodePeepSnippets)); - curPeep = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); - - curPeep->vars = NULL; - curPeep->wildpCodes = NULL; curPeep->wildpCodeOps = NULL; - curPeep->postFalseCond = PCC_NONE; - curPeep->postTrueCond = PCC_NONE; - peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps); - curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL); - sMaxWildVar = 0; - sMaxWildMnem = 0; + currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); + initpCodePeep(currentRule); /* Convert the target block */ - peepRuleBlock2pCodeBlock(pr->match); - - fprintf(stderr,"finished target, here it is in pcode form:\n"); - printpBlock(stderr, curBlock); + peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target); - fprintf(stderr,"target with labels merged:\n"); - pBlockMergeLabels(curBlock); - printpBlock(stderr, curBlock); + //DFPRINTF((stderr,"finished target, here it is in pcode form:\n")); + //printpBlock(stderr, currentRule->target.pb); - fprintf(stderr,"\nReplaced by:\n"); + //DFPRINTF((stderr,"target with labels merged:\n")); + //pBlockMergeLabels(curBlock); + pBlockMergeLabels(currentRule->target.pb); + //printpBlock(stderr, currentRule->replace.pb); + //#ifdef PCODE_DEBUG + // printpBlock(stderr, curBlock); + //#endif + //DFPRINTF((stderr,"\nReplaced by:\n")); - curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL); /* Convert the replace block */ - peepRuleBlock2pCodeBlock(pr->replace); + peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace); + + //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n")); + //printpBlock(stderr, curBlock); - fprintf(stderr,"finished replace block, here it is in pcode form:\n"); - printpBlock(stderr, curBlock); + //DFPRINTF((stderr,"replace with labels merged:\n")); - fprintf(stderr,"replace with labels merged:\n"); - pBlockMergeLabels(curBlock); - printpBlock(stderr, curBlock); + pBlockMergeLabels(currentRule->replace.pb); + //printpBlock(stderr, currentRule->replace.pb); - peepRuleCondition(pr->cond); + peepRuleCondition(pr->cond,currentRule); /* The rule has been converted to pCode. Now allocate * space for the wildcards */ - - ++sMaxWildVar; - curPeep->nvars = sMaxWildVar; - curPeep->vars = Safe_calloc(sMaxWildVar, sizeof(char *)); - - curPeep->nops = sMaxWildVar; - curPeep->wildpCodeOps = Safe_calloc(sMaxWildVar, sizeof(pCodeOp *)); - - curPeep->nwildpCodes = ++sMaxWildMnem; - curPeep->wildpCodes = Safe_calloc(sMaxWildMnem, sizeof(char *)); - + + postinit_pCodeWildBlock(¤tRule->target); + postinit_pCodeWildBlock(¤tRule->replace); //return; // debug ... don't want to go through all the rules yet } + { + pCodePeep *peepBlock; + _DLL *peeprules; + + peeprules = (_DLL *)peepSnippets; + //fprintf(stderr,"target rules\n"); + while(peeprules) { + //fprintf(stderr," rule:\n"); + peepBlock = ((pCodePeepSnippets*)peeprules)->peep; + //printpBlock(stderr, peepBlock->target.pb); + peeprules = peeprules->next; + } + //fprintf(stderr," ... done\n"); + } + } void printpCodeString(FILE *of, pCode *pc, int max) @@ -1220,260 +1459,158 @@ static void * DLL_append(_DLL *list, _DLL *next) -----------------------------------------------------------------*/ -#if 0 -/*-----------------------------------------------------------------*/ -/* pCodePeep */ -/*-----------------------------------------------------------------*/ -int pCodePeepCompare(pCode *pc, pCodePeep *pcp) -{ - pCode *pcfrom,*pcto; - - pcfrom = pc; - for( pcto=pcp->target; pcto; pcto=pcto->next) { - pcfrom = findNextInstruction(pcfrom); - - if( pcfrom && - (PCI(pcfrom)->op == PCI(pcto)->op || - PCI(pcto)->op == POC_WILD)) - continue; - return 0; - } - return 0; -} /*-----------------------------------------------------------------*/ -/* pCodePeep */ +/* pCodeSearchCondition - Search a pCode chain for a 'condition' */ +/* */ +/* return conditions */ +/* 1 - The Condition was found for a pCode's input */ +/* 0 - No matching condition was found for the whole chain */ +/* -1 - The Condition was found for a pCode's output */ +/* */ /*-----------------------------------------------------------------*/ -void pCodePeepSearch(pCodePeep *snippet) +int pCodeSearchCondition(pCode *pc, unsigned int cond) { - pBlock *pb; - pCode *pc; + //fprintf(stderr,"Checking conditions %d\n",cond); + while(pc) { - if(!the_pFile) - return; + /* If we reach a function end (presumably an end since we most + probably began the search in the middle of a function), then + the condition was not found. */ + if(pc->type == PC_FUNCTION) + return 0; - /* compare the chain to the pCode that we've - got so far. If a match is found, then replace - the pCode chain. - */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - for(pc = pb->pcHead; pc; pc = pc->next) { - pCodePeepCompare(pc,snippet); + if(pc->type == PC_OPCODE) { + //fprintf(stderr," checking conditions of: "); + //pc->print(stderr,pc); + //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond); + if(PCI(pc)->inCond & cond) + return 1; + if(PCI(pc)->outCond & cond) + return -1; } - } -} -#endif - -#if 0 -pBlock *pBlockAppend(pBlock *pb1, pBlock *pb2) -{ - pBlock *pb; - - if(!pb1->tail) - return pb2; - - pb = pb1->tail; - - pb2->head = pb1; - pb2->tail = NULL; - pb1->tail = pb2; + pc = pc->next; + } + return 0; } -#endif - -void pCodePeepInit(void) +/*----------------------------------------------------------------- + * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) + * + * Compare two pCodeOp's and return 1 if they're the same + *-----------------------------------------------------------------*/ +int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) { -#if 0 - pBlock *pb; - // pCode *pc; - pCodePeep *pcp; - pCodePeepSnippets *pcps; - - /* Declare a peep code snippet */ - /* do I really need a separate struct just to DLL the snippets? */ - /* e.g. I could put the DLL into the pCodePeep structure */ - - /* - - target: - - movwf %1 - movf %1,w - - replace: - - movwf %1 - - Condition: - false condition - PCC_Z (Z bit is not used as input to subsequent code) - true condition - none - */ - pcps = Safe_calloc(1,sizeof(pCodePeepSnippets)); - pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); - peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps); - - - pb = newpCodeChain(NULL, 'W', newpCode(POC_MOVWF, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) ); - addpCode2pBlock( pb, newpCode(POC_MOVFW, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) ); - - pcp->target = pb; - - pcp->replace = newpCodeChain(NULL, 'W',newpCode(POC_MOVWF, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) ); - - /* Allocate space to store pointers to the wildcard variables */ - pcp->nvars = 1; - pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *)); - pcp->nwildpCodes = 0; - pcp->wildpCodes = NULL; + char b[50], *n2; - pcp->postFalseCond = PCC_Z; - pcp->postTrueCond = PCC_NONE; - - fprintf(stderr,"Peep rule\nTarget:\n"); - printpCodeString(stderr,pcp->target->pcHead, 10); - fprintf(stderr,"Replaced with:\n"); - printpCodeString(stderr,pcp->replace->pcHead, 10); - - /* Now for another peep example */ - pcps = Safe_calloc(1,sizeof(pCodePeepSnippets)); - pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); - peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps); - - { - /* - target: - - btfsc %0 - goto %1 - %3 - %1: %4 - - replace: - btfss %0 - %3 - %1: %4 - - The %3 and %4 are wild opcodes. Since the opcodes - are stored in a different array than the wild operands, - they can have the same indices and not conflict. So - below, the %3 is really a %0, %4 is a %1. - - */ - pCodeOp *pcl; - pCodeOp *pcw; - pCodeOp *pcwb; - - // Create a new wild operand subtyped as a bit - pcwb = newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1,0)); - - // Create a - pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSC,pcwb)); - - pcl = newpCodeOpLabel(-1); - pcw = newpCodeOpWild(1, pcp, pcl); - addpCode2pBlock( pb, newpCode(POC_GOTO, pcw)); - addpCode2pBlock( pb, newpCodeWild(0,NULL,NULL)); - addpCode2pBlock( pb, newpCodeWild(1,NULL,pcw)); - - - pcp->target = pb; - - pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSS, pcwb)); - addpCode2pBlock( pb, newpCodeWild(0,NULL,NULL)); - addpCode2pBlock( pb, newpCodeWild(1,NULL,pcw)); - - pcp->replace = pb; + if(!pcops || !pcopd) + return 0; +/* + fprintf(stderr," Comparing operands %s", + get_op( pcops,NULL,0)); - /* Allocate space to store pointers to the wildcard variables */ - pcp->nvars = 2; - pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *)); - pcp->nwildpCodes = 2; - pcp->wildpCodes = Safe_calloc(pcp->nwildpCodes, sizeof(pCode *)); + fprintf(stderr," to %s\n", + get_op( pcopd,NULL,0)); +*/ - pcp->postFalseCond = PCC_NONE; - pcp->postTrueCond = PCC_NONE; + if(pcops->type != pcopd->type) { + //fprintf(stderr," - fail - diff types\n"); + return 0; // different types } + if(pcops->type == PO_LITERAL) { + if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit)) + return 1; + return 0; + } + b[0]=0; + get_op(pcops,b,50); + n2 = 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) ); + return 0; // different names + } + switch(pcops->type) { + case PO_DIR: + if( PCOR(pcops)->instance != PCOR(pcopd)->instance) { + //fprintf(stderr, " - fail different instances\n"); + return 0; + } + break; + default: + break; + } + //fprintf(stderr," - pass\n"); + return 1; +} - //------------- - - /* Now for another peep example */ - pcps = Safe_calloc(1,sizeof(pCodePeepSnippets)); - pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); - peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps); - - { - pCodeOp *pcw; - - pcw = newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER)); - - pb = newpCodeChain(NULL, 'W', newpCode(POC_MOVWF, pcw)); - addpCode2pBlock( pb, newpCode(POC_MOVWF, pcw)); - - pcp->target = pb; - - pb = newpCodeChain(NULL, 'W',newpCode(POC_MOVWF, pcw)); - - pcp->replace = pb; +int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) +{ + int labindex; - /* Allocate space to store pointers to the wildcard variables */ - pcp->nvars = 1; - pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *)); - pcp->nwildpCodes = 0; - pcp->wildpCodes = NULL; + /* Check for a label associated with this wild pCode */ + // If the wild card has a label, make sure the source code does too. + if(PCI(pcd)->label) { + pCode *pcl = PCI(pcd)->label->pc; - pcp->postFalseCond = PCC_NONE; - pcp->postTrueCond = PCC_NONE; - } +#ifdef PCODE_DEBUG + int li = -PCL(pcl)->key; + if(peepBlock->target.vars[li] == NULL) { + if(PCI(pcs)->label) { + DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label)); + } + } else { + // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key)); + DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li])); + if(PCI(pcs)->label) { + DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label)); + } + } +#endif -#endif -} + if(!PCI(pcs)->label) + return 0; -/*-----------------------------------------------------------------*/ -/* pCodeSearchCondition - Search a pCode chain for a 'condition' */ -/* */ -/* return conditions */ -/* 1 - The Condition was found for a pCode's input */ -/* 0 - No matching condition was found for the whole chain */ -/* -1 - The Condition was found for a pCode's output */ -/* */ -/*-----------------------------------------------------------------*/ -int pCodeSearchCondition(pCode *pc, unsigned int cond) -{ + labindex = -PCL(pcl)->key; + if(peepBlock->target.vars[labindex] == NULL) { + // First time to encounter this label + peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label; + DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label)); - while(pc) { + } else { + if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) { + DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label)); + return 0; + } + DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex])); + } + } else { + //DFPRINTF((stderr,"destination doesn't have a label\n")); - /* If we reach a function end (presumably an end since we most - probably began the search in the middle of a function), then - the condition was not found. */ - if(pc->type == PC_FUNCTION) + if(PCI(pcs)->label) return 0; - if(pc->type == PC_OPCODE) { - if(PCI(pc)->inCond & cond) - return 1; - if(PCI(pc)->outCond & cond) - return -1; - } + //DFPRINTF((stderr,"neither src nor dest have labels\n")); - pc = pc->next; } - return 0; + return 1; + } + /*-----------------------------------------------------------------*/ /* pCodePeepMatchLine - Compare source and destination pCodes to */ /* see they're the same. */ @@ -1505,6 +1642,15 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) { int index; // index into wild card arrays + /* one-for-one match. Here the source and destination opcodes + * are not wild. However, there may be a label or a wild operand */ + + if(pcs) { + if(PCI(pcs)->label) { + DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label)); + } + } + if(pcs->type == pcd->type) { if(pcs->type == PC_OPCODE) { @@ -1513,45 +1659,72 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(PCI(pcs)->op != PCI(pcd)->op) return 0; - fprintf(stderr,"%s comparing\n",__FUNCTION__); +#ifdef PCODE_DEBUG + DFPRINTF((stderr,"%s comparing\n",__FUNCTION__)); pcs->print(stderr,pcs); pcd->print(stderr,pcd); +#endif + + if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) + return 0; /* Compare the operands */ if(PCI(pcd)->pcop) { if (PCI(pcd)->pcop->type == PO_WILD) { index = PCOW(PCI(pcd)->pcop)->id; - - fprintf(stderr,"destination is wild\n"); + //DFPRINTF((stderr,"destination is wild\n")); #ifdef DEBUG_PCODEPEEP if (index > peepBlock->nops) { - fprintf(stderr,"%s - variables exceeded\n",__FUNCTION__); + DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__)); exit(1); } #endif + PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop; - if(!peepBlock->wildpCodeOps[index]) { - peepBlock->wildpCodeOps[index] = PCI(pcs)->pcop; + if(!peepBlock->target.wildpCodeOps[index]) { + peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop; //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 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]); } + { char *n; - if(PCI(pcs)->pcop->type == PO_GPR_TEMP) + switch(PCI(pcs)->pcop->type) { + case PO_GPR_TEMP: + case PO_FSR: + //case PO_INDF: n = PCOR(PCI(pcs)->pcop)->r->name; - else + + break; + default: n = PCI(pcs)->pcop->name; + } - if(peepBlock->vars[index]) - return (strcmp(peepBlock->vars[index],n) == 0); + if(peepBlock->target.vars[index]) + return (strcmp(peepBlock->target.vars[index],n) == 0); else { - fprintf(stderr,"first time for a variable: %d, %s\n",index,n); - peepBlock->vars[index] = n; //PCI(pcs)->pcop->name; + DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n)); + peepBlock->target.vars[index] = n; return 1; } } + + } 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 */ @@ -1561,68 +1734,66 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) } } + /* Compare a wild instruction to a regular one. */ if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) { - int labindex; - index = PCW(pcd)->id; - - fprintf(stderr,"%s comparing wild cards\n",__FUNCTION__); +#ifdef PCODE_DEBUG + DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__)); pcs->print(stderr,pcs); pcd->print(stderr,pcd); +#endif + peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs; - peepBlock->wildpCodes[PCW(pcd)->id] = pcs; - - /* Check for a label associated with this wild pCode */ - // If the wild card has a label, make sure the source code does too. - if(pcd->label) { - pCode *pcl; + if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) { + DFPRINTF((stderr," Failing because labels don't match\n")); + return 0; + } - if(!pcs->label) - return 0; + if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) { + // doesn't match because the wild pcode must be a bit skip + DFPRINTF((stderr," Failing match because bit skip is req\n")); + //pcd->print(stderr,pcd); + //pcs->print(stderr,pcs); + return 0; + } - pcl = pcd->label->pc; - //labindex = PCOW(pcl)->id; - labindex = -PCL(pcl)->key; - fprintf(stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex); - if(peepBlock->vars[labindex] == NULL) { - // First time to encounter this label - peepBlock->vars[labindex] = PCL(pcs->label->pc)->label; - fprintf(stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex]); - } else { - if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) { - fprintf(stderr,"labels don't match\n"); - return 0; - } - fprintf(stderr,"matched a label\n"); - } - } else - fprintf(stderr,"wild card doesn't have a label\n"); + if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) { + // doesn't match because the wild pcode must *not* be a bit skip + DFPRINTF((stderr," Failing match because shouldn't be bit skip\n")); + //pcd->print(stderr,pcd); + //pcs->print(stderr,pcs); + return 0; + } if(PCW(pcd)->operand) { PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop; - if(peepBlock->vars[index]) { - int i = (strcmp(peepBlock->vars[index],PCI(pcs)->pcop->name) == 0); + if(peepBlock->target.vars[index]) { + int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0); +#ifdef PCODE_DEBUG + if(i) - fprintf(stderr," (matched)\n"); + DFPRINTF((stderr," (matched)\n")); else { - fprintf(stderr," (no match: wild card operand mismatch\n"); - fprintf(stderr," peepblock= %s, pcodeop= %s\n", - peepBlock->vars[index], - PCI(pcs)->pcop->name); + DFPRINTF((stderr," (no match: wild card operand mismatch\n")); + DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n", + peepBlock->target.vars[index], + PCI(pcs)->pcop->name)); } +#endif return i; } else { - peepBlock->vars[index] = PCI(pcs)->pcop->name; + DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name)); + peepBlock->target.vars[index] = PCI(pcs)->pcop->name; return 1; } } pcs = findNextInstruction(pcs->next); if(pcs) { - fprintf(stderr," (next to match)\n"); - pcs->print(stderr,pcs); + //DFPRINTF((stderr," (next to match)\n")); + //pcs->print(stderr,pcs); } else if(pcd->next) { /* oops, we ran out of code, but there's more to the rule */ return 0; @@ -1642,11 +1813,28 @@ void pCodePeepClrVars(pCodePeep *pcp) int i; if(!pcp) return; +/* + DFPRINTF((stderr," Clearing peep rule vars\n")); + DFPRINTF((stderr," %d %d %d %d %d %d\n", + pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes, + pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes)); +*/ + for(i=0;itarget.nvars; i++) + pcp->target.vars[i] = NULL; + for(i=0;itarget.nops; i++) + pcp->target.wildpCodeOps[i] = NULL; + for(i=0;itarget.nwildpCodes; i++) + pcp->target.wildpCodes[i] = NULL; + + for(i=0;ireplace.nvars; i++) + pcp->replace.vars[i] = NULL; + for(i=0;ireplace.nops; i++) + pcp->replace.wildpCodeOps[i] = NULL; + for(i=0;ireplace.nwildpCodes; i++) + pcp->replace.wildpCodes[i] = NULL; + + - for(i=0;invars; i++) { - pcp->vars[i] = NULL; - pcp->wildpCodeOps[i] = NULL; - } } /*-----------------------------------------------------------------*/ @@ -1672,7 +1860,7 @@ void pCodeInsertAfter(pCode *pc1, pCode *pc2) /*-----------------------------------------------------------------*/ /* pCodeOpCopy - copy a pcode operator */ /*-----------------------------------------------------------------*/ -static pCodeOp *pCodeOpCopy(pCodeOp *pcop) +pCodeOp *pCodeOpCopy(pCodeOp *pcop) { pCodeOp *pcopnew=NULL; @@ -1682,87 +1870,122 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) switch(pcop->type) { case PO_CRY: case PO_BIT: - fprintf(stderr,"pCodeOpCopy bit\n"); - pcopnew = Safe_calloc(1,sizeof(pCodeOpBit) ); - PCOB(pcopnew)->bit = PCOB(pcop)->bit; - PCOB(pcopnew)->inBitSpace = PCOB(pcop)->inBitSpace; + //DFPRINTF((stderr,"pCodeOpCopy bit\n")); + pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) ); + PCORB(pcopnew)->bit = PCORB(pcop)->bit; + PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace; break; case PO_WILD: /* Here we expand the wild card into the appropriate type: */ /* By recursively calling pCodeOpCopy */ - fprintf(stderr,"pCodeOpCopy wild\n"); + //DFPRINTF((stderr,"pCodeOpCopy wild\n")); if(PCOW(pcop)->matched) pcopnew = pCodeOpCopy(PCOW(pcop)->matched); else { // Probably a label pcopnew = pCodeOpCopy(PCOW(pcop)->subtype); - pcopnew->name = Safe_strdup(PCOW(pcop)->pcp->vars[PCOW(pcop)->id]); - fprintf(stderr,"copied a wild op named %s\n",pcopnew->name); + 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: - fprintf(stderr,"pCodeOpCopy label\n"); + //DFPRINTF((stderr,"pCodeOpCopy label\n")); pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) ); PCOLAB(pcopnew)->key = PCOLAB(pcop)->key; break; - case PO_LITERAL: case PO_IMMEDIATE: - fprintf(stderr,"pCodeOpCopy lit\n"); + 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; + case PO_GPR_BIT: + + pcopnew = 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")); + return pcopnew; + break; + case PO_GPR_REGISTER: case PO_GPR_TEMP: - case PO_GPR_BIT: - fprintf(stderr,"pCodeOpCopy GPR register\n"); + case PO_FSR: + case PO_INDF: + //DFPRINTF((stderr,"pCodeOpCopy GPR register\n")); pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcopnew)->r = PCOR(pcop)->r; PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx; - fprintf(stderr," register index %d\n", PCOR(pcop)->r->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"); + //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_SFR_REGISTER: case PO_STR: case PO_NONE: case PO_W: - case PO_STATUS: - case PO_FSR: - case PO_INDF: + case PO_INTCON: case PO_PCL: case PO_PCLATH: - fprintf(stderr,"pCodeOpCopy register type %d\n", pcop->type); + //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type)); pcopnew = Safe_calloc(1,sizeof(pCodeOp) ); } pcopnew->type = pcop->type; - pcopnew->name = Safe_strdup(pcop->name); + if(pcop->name) + pcopnew->name = Safe_strdup(pcop->name); + else + pcopnew->name = NULL; return pcopnew; } -#if 0 + /*-----------------------------------------------------------------*/ /* pCodeCopy - copy a pcode */ /*-----------------------------------------------------------------*/ -static pCode *pCodeCopy(pCode *pc) +static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert) { + pCodeInstruction *new_pci; - pCode *pcnew; + if(invert) + new_pci = PCI(newpCode(pci->inverted_op,pci->pcop)); + else + new_pci = PCI(newpCode(pci->op,pci->pcop)); + + new_pci->pc.pb = pci->pc.pb; + new_pci->from = pci->from; + new_pci->to = pci->to; + new_pci->label = pci->label; + new_pci->pcflow = pci->pcflow; - pcnew = newpCode(pc->type,pc->pcop); + return PCODE(new_pci); } -#endif + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ void pCodeDeleteChain(pCode *f,pCode *t) @@ -1771,9 +1994,9 @@ void pCodeDeleteChain(pCode *f,pCode *t) while(f && f!=t) { - fprintf(stderr,"delete pCode:\n"); + DFPRINTF((stderr,"delete pCode:\n")); pc = f->next; - f->print(stderr,f); + //f->print(stderr,f); //f->delete(f); this dumps core... f = pc; @@ -1787,6 +2010,7 @@ int pCodePeepMatchRule(pCode *pc) { pCodePeep *peepBlock; pCode *pct, *pcin; + pCodeCSource *pc_cline=NULL; _DLL *peeprules; int matched; @@ -1794,13 +2018,27 @@ int pCodePeepMatchRule(pCode *pc) while(peeprules) { peepBlock = ((pCodePeepSnippets*)peeprules)->peep; - if(!peepBlock || !peepBlock->target || !peepBlock->target->pcHead) + + if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) { + fprintf(stderr, "skipping rule because target pb is NULL\n"); goto next_rule; + } pCodePeepClrVars(peepBlock); - +/* pcin = pc; - pct = peepBlock->target->pcHead; + if(IS_PCCOMMENT(pcin)) + pc = pcin = findNextInstruction(pcin->next); +*/ + pcin = pc = findNextInstruction(pc); + + pct = peepBlock->target.pb->pcHead; +#ifdef PCODE_DEBUG + { + pCode *pcr = peepBlock->replace.pb->pcHead; + if(pcr) pct->print(stderr,pcr); + } +#endif matched = 0; while(pct && pcin) { @@ -1810,14 +2048,19 @@ int pCodePeepMatchRule(pCode *pc) pcin = findNextInstruction(pcin->next); pct = pct->next; //debug: - fprintf(stderr," matched\n"); - if(!pcin) - fprintf(stderr," end of code\n"); - if(!pct) - fprintf(stderr," end of rule\n"); + //DFPRINTF((stderr," matched\n")); + + if(!pcin && pct) { + DFPRINTF((stderr," partial match... no more code\n")); + fprintf(stderr," partial match... no more code\n"); + matched = 0; + } + if(!pct) { + DFPRINTF((stderr," end of rule\n")); + } } - if(matched) { + if(matched && pcin) { /* So far we matched the rule up to the point of the conditions . * In other words, all of the opcodes match. Now we need to see @@ -1827,10 +2070,17 @@ int pCodePeepMatchRule(pCode *pc) * following the point just past where we have matched depend on * the `postFalseCond' as input then we abort the match */ - fprintf(stderr," matched rule so far, now checking conditions\n"); + DFPRINTF((stderr," matched rule so far, now checking conditions\n")); + //pcin->print(stderr,pcin); + if (pcin && peepBlock->postFalseCond && (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) ) matched = 0; + + //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond)); + + + //if(!matched) fprintf(stderr,"failed on conditions\n"); } if(matched) { @@ -1841,15 +2091,17 @@ int pCodePeepMatchRule(pCode *pc) /* We matched a rule! Now we have to go through and remove the inefficient code with the optimized version */ - - fprintf(stderr, "Found a pcode peep match:\nRule:\n"); - printpCodeString(stderr,peepBlock->target->pcHead,10); - fprintf(stderr,"first thing matched\n"); +#ifdef PCODE_DEBUG + DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n")); + printpCodeString(stderr,peepBlock->target.pb->pcHead,10); + DFPRINTF((stderr,"first thing matched\n")); pc->print(stderr,pc); if(pcin) { - fprintf(stderr,"last thing matched\n"); + DFPRINTF((stderr,"last thing matched\n")); pcin->print(stderr,pcin); } +#endif + /* Unlink the original code */ pcprev = pc->prev; @@ -1857,31 +2109,50 @@ int pCodePeepMatchRule(pCode *pc) if(pcin) pcin->prev = pc->prev; + +#if 0 { /* DEBUG */ /* Converted the deleted pCodes into comments */ char buf[256]; + pCodeCSource *pc_cline2=NULL; buf[0] = ';'; buf[1] = '#'; while(pc && pc!=pcin) { + + if(pc->type == PC_OPCODE && PCI(pc)->cline) { + if(pc_cline) { + pc_cline2->pc.next = PCODE(PCI(pc)->cline); + pc_cline2 = PCCS(pc_cline2->pc.next); + } else { + pc_cline = pc_cline2 = PCI(pc)->cline; + pc_cline->pc.seq = pc->seq; + } + } + pCode2str(&buf[2], 254, pc); pCodeInsertAfter(pcprev, newpCodeCharP(buf)); pcprev = pcprev->next; pc = pc->next; + } + if(pc_cline2) + pc_cline2->pc.next = NULL; } +#endif if(pcin) pCodeDeleteChain(pc,pcin); /* Generate the replacement code */ pc = pcprev; - pcr = peepBlock->replace->pcHead; // This is the replacement code + pcr = peepBlock->replace.pb->pcHead; // This is the replacement code while (pcr) { pCodeOp *pcop=NULL; + /* If the replace pcode is an instruction with an operand, */ /* then duplicate the operand (and expand wild cards in the process). */ if(pcr->type == PC_OPCODE) { @@ -1890,115 +2161,52 @@ int pCodePeepMatchRule(pCode *pc) * Is it wild? */ if(PCI(pcr)->pcop->type == PO_WILD) { int index = PCOW(PCI(pcr)->pcop)->id; - fprintf(stderr,"copying wildopcode\n"); - if(peepBlock->wildpCodeOps[index]) - pcop = pCodeOpCopy(peepBlock->wildpCodeOps[index]); + //DFPRINTF((stderr,"copying wildopcode\n")); + if(peepBlock->target.wildpCodeOps[index]) + pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]); else - fprintf(stderr,"error, wildopcode in replace but not source?\n"); + DFPRINTF((stderr,"error, wildopcode in replace but not source?\n")); } else pcop = pCodeOpCopy(PCI(pcr)->pcop); } - fprintf(stderr,"inserting pCode\n"); + //DFPRINTF((stderr,"inserting pCode\n")); pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop)); } else if (pcr->type == PC_WILD) { - pCodeInsertAfter(pc,peepBlock->wildpCodes[PCW(pcr)->id]); + if(PCW(pcr)->invertBitSkipInst) + DFPRINTF((stderr,"We need to invert the bit skip instruction\n")); + pCodeInsertAfter(pc, + pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]), + PCW(pcr)->invertBitSkipInst)); } else if (pcr->type == PC_COMMENT) { pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment)); } pc = pc->next; - if(pc) - pc->print(stderr,pc); +#ifdef PCODE_DEBUG + DFPRINTF((stderr," NEW Code:")); + if(pc) pc->print(stderr,pc); +#endif pcr = pcr->next; } + /* We have just replaced the inefficient code with the rule. + * Now, we need to re-add the C-source symbols if there are any */ + pc = pcprev; + while(pc_cline ) { + + pc = findNextInstruction(pc->next); + PCI(pc)->cline = pc_cline; + pc_cline = PCCS(pc_cline->pc.next); + + } + return 1; } next_rule: peeprules = peeprules->next; } + DFPRINTF((stderr," no rule matched\n")); return 0; } - - - - - - - - - - -#if 0 -/*******************/ -pCode *parseLineNode(char *ln) -{ - char buffer[50], *s; - int state=0; //0 label, 1 mnemonic, 2 operand, 3 operand, 4 comment - int var; - pCode *pc = NULL; - // pCodeLabel *pcl = NULL; - - if(!ln || !*ln) - return pc; - - s = buffer; - *s = 0; - - while(*ln) { - - /* skip white space */ - while (isspace (*ln)) - ln++; - - switch(state) { - - case 0: // look for a label - case 1: // look for mnemonic - - if(*ln == '%') { - - // Wild - - ln++; - if(!isdigit(*ln) ) - break; - //goto next_state; - - var = strtol(ln, &ln, 10); - if(*ln == ':') { - // valid wild card label - fprintf(stderr, " wildcard label: %d\n",var); - ln++; - } else - fprintf(stderr, " wild opcode: %d\n",var), state++; - - } else { - // not wild - // Extract the label/mnemonic from the line - - s = buffer; - while(*ln && !(isspace(*ln) || *ln == ':')) - *s++ = *ln++; - - *s = 0; - if(*ln == ':') - fprintf(stderr," regular label: %s\n",buffer), ln++; - else - fprintf(stderr," regular mnem: %s\n",buffer), state++; - } - state++; - break; - - default: - ln++; - - } - } - - return pc; - -} -#endif