1 /*-------------------------------------------------------------------------
3 pcodepeep.c - post code generation
4 Written By - Scott Dattalo scott@dattalo.com
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
24 #include "common.h" // Include everything in the SDCC src directory
29 #include "pcodeflow.h"
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
35 #define STRCASECMP strcasecmp
38 pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
41 pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype);
42 pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
43 pCode * findNextInstruction(pCode *pc);
44 int getpCode(char *mnem,int dest);
45 int getpCodePeepCommand(char *cmd);
46 void pBlockMergeLabels(pBlock *pb);
47 char *pCode2str(char *str, int size, pCode *pc);
48 char *get_op( pCodeOp *pcop);
50 extern pCodeInstruction *pic14Mnemonics[];
53 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
55 /****************************************************************/
57 * rootRules - defined in SDCCpeep.c
58 * This is a pointer to the (parsed) peephole rules that are
59 * defined in peep.def.
62 //extern peepRule *rootRules;
67 /****************************************************************/
68 /****************************************************************/
76 typedef struct pCodePeepSnippets
83 /****************************************************************/
87 /****************************************************************/
89 static pCodePeepSnippets *peepSnippets=NULL;
91 /****************************************************************/
95 /****************************************************************/
97 //static pCodePeep *curPeep=NULL;
99 /****************************************************************/
103 /****************************************************************/
105 //static pBlock *curBlock=NULL;
108 /****************************************************************/
110 /* max wild cards in a peep rule */
112 /****************************************************************/
114 //static int sMaxWildVar = 0;
115 //static int sMaxWildMnem = 0;
118 typedef struct pCodeToken
120 int tt; // token type;
129 pCodeToken tokArr[50];
148 typedef struct parsedPattern {
149 struct pcPattern *pcp;
153 #define MAX_PARSEDPATARR 50
154 parsedPattern parsedPatArr[MAX_PARSEDPATARR];
155 unsigned int parsedPatIdx=0;
168 static char pcpat_label[] = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
169 static char pcpat_number[] = {PCT_NUMBER, 0};
170 static char pcpat_string[] = {PCT_STRING, 0};
171 static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
172 static char pcpat_wildVar[] = {PCT_PERCENT, PCT_NUMBER, 0};
173 static char pcpat_comma[] = {PCT_COMMA, 0};
174 static char pcpat_comment[] = {PCT_COMMENT, 0};
177 typedef struct pcPattern {
178 char pt; // Pattern type
179 char *tokens; // list of tokens that describe the pattern
180 void * (*f) (void *,pCodeWildBlock *);
183 pcPattern pcpArr[] = {
184 {PCP_LABEL, pcpat_label, NULL},
185 {PCP_WILDSTR, pcpat_wildString, NULL},
186 {PCP_STR, pcpat_string, NULL},
187 {PCP_WILDVAR, pcpat_wildVar, NULL},
188 {PCP_COMMA, pcpat_comma, NULL},
189 {PCP_COMMENT, pcpat_comment, NULL},
190 {PCP_NUMBER, pcpat_number, NULL}
193 #define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
195 // Assembly Line Token
208 static char alt_comment[] = { PCP_COMMENT, 0};
209 static char alt_label[] = { PCP_LABEL, 0};
210 static char alt_mnem0[] = { PCP_STR, 0};
211 static char alt_mnem0a[] = { PCP_WILDVAR, 0};
212 static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
213 static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0};
214 static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
215 static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
216 static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
218 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
219 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
220 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
221 static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
222 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
223 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
224 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
225 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
226 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
228 pcPattern altArr[] = {
229 {ALT_LABEL, alt_label, cvt_altpat_label},
230 {ALT_COMMENT, alt_comment,cvt_altpat_comment},
231 {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
232 {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
233 {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
234 {ALT_MNEM1A, alt_mnem1a, cvt_altpat_mnem1a},
235 {ALT_MNEM1, alt_mnem1, cvt_altpat_mnem1},
236 {ALT_MNEM0A, alt_mnem0a, cvt_altpat_mnem0a},
237 {ALT_MNEM0, alt_mnem0, cvt_altpat_mnem0},
241 #define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
243 // forward declarations
244 static void * DLL_append(_DLL *list, _DLL *next);
246 /*-----------------------------------------------------------------*/
247 /* cvt_extract_destination - helper function extracts the register */
248 /* destination from a parsedPattern. */
250 /*-----------------------------------------------------------------*/
251 static int cvt_extract_destination(parsedPattern *pp)
254 if(pp->pct[0].tt == PCT_STRING) {
256 // just check first letter for now
258 if(toupper(*pp->pct[0].tok.s) == 'F')
261 } else if (pp->pct[0].tt == PCT_NUMBER) {
271 /*-----------------------------------------------------------------*/
272 /* pCodeOp *cvt_extract_status(char *reg, char *bit) */
273 /* if *reg is the "status" register and *bit is one of the */
274 /* status bits, then this function will create a new pCode op */
275 /* containing the status register. */
276 /*-----------------------------------------------------------------*/
278 static pCodeOp *cvt_extract_status(char *reg, char *bit)
282 if(STRCASECMP(reg, pc_status.pcop.name))
289 if(toupper(*bit) == 'C')
290 return PCOP(popCopyGPR2Bit(&pc_status,PIC_C_BIT));
291 if(toupper(*bit) == 'Z')
292 return PCOP(popCopyGPR2Bit(&pc_status,PIC_Z_BIT));
296 if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C')
297 return PCOP(popCopyGPR2Bit(&pc_status,PIC_DC_BIT));
303 /*-----------------------------------------------------------------*/
304 /* cvt_altpat_label - convert assembly line type to a pCode label */
305 /* INPUT: pointer to the parsedPattern */
309 /* label pattern => '%' number ':' */
310 /* at this point, we wish to extract only the 'number' */
312 /*-----------------------------------------------------------------*/
313 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
315 parsedPattern *p = pp;
317 DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
318 return newpCodeLabel(NULL,-p->pct[1].tok.n);
322 /*-----------------------------------------------------------------*/
323 /* cvt_altpat_comment - convert assembly line type to a comment */
324 /* INPUT: pointer to the parsedPattern */
326 /* pp[0] - comment */
329 /*-----------------------------------------------------------------*/
330 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
332 parsedPattern *p = pp;
334 DFPRINTF((stderr,"altpat_comment = %s\n",p->pct[0].tok.s));
335 return newpCodeCharP(p->pct[0].tok.s);
339 /*-----------------------------------------------------------------*/
340 /* cvt_altpat_mem0 - convert assembly line type to a wild pCode */
345 /*-----------------------------------------------------------------*/
346 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
348 parsedPattern *p = pp;
351 pCodeInstruction *pci=NULL;
353 DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s));
355 opcode = getpCode(p->pct[0].tok.s,0);
358 /* look for special command strings like _NOTBITSKIP_ */
360 //fprintf(stderr, "Bad mnemonic\n");
362 opcode = getpCodePeepCommand(p->pct[0].tok.s);
364 // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
368 pci = PCI(newpCode(opcode, NULL));
371 fprintf(stderr,"couldn't find mnemonic\n");
377 /*-----------------------------------------------------------------*/
378 /* cvt_altpat_mem0a - convert assembly line type to a wild pCode */
381 /* pp[0] - wild var */
383 /*-----------------------------------------------------------------*/
384 static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
386 parsedPattern *p = pp;
388 DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n));
390 /* Save the index of the maximum wildcard mnemonic */
392 //if(p[0].pct[1].tok.n > sMaxWildVar)
393 // sMaxWildMnem = p[0].pct[1].tok.n;
395 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
396 pcwb->nwildpCodes = p[0].pct[1].tok.n;
398 return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
402 /*-----------------------------------------------------------------*/
403 /* cvt_altpat_mem1 - convert assembly line type to a pCode */
404 /* instruction with 1 operand. */
407 /* pp[1] - Operand */
409 /*-----------------------------------------------------------------*/
410 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
413 parsedPattern *p = pp;
416 pCodeInstruction *pci=NULL;
419 DFPRINTF((stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s));
421 opcode = getpCode(p->pct[0].tok.s,0);
423 //fprintf(stderr, "Bad mnemonic\n");
424 opcode = getpCodePeepCommand(p->pct[0].tok.s);
426 //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
431 if(pic14Mnemonics[opcode]->isBitInst)
432 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
434 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
437 pci = PCI(newpCode(opcode, pcosubtype));
440 fprintf(stderr,"couldn't find mnemonic\n");
446 /*-----------------------------------------------------------------*/
447 /* cvt_altpat_mem1a - convert assembly line type to a pCode */
448 /* instruction with 1 wild operand. */
451 /* pp[1] - wild var */
453 /*-----------------------------------------------------------------*/
454 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
456 parsedPattern *p = pp;
459 pCodeInstruction *pci=NULL;
462 DFPRINTF((stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n));
464 opcode = getpCode(p->pct[0].tok.s,0);
466 int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
470 fprintf(stderr, "Bad mnemonic\n");
474 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
475 pcwb->nwildpCodes = p[0].pct[1].tok.n;
477 pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
481 PCW(pc)->mustNotBeBitSkipInst = 1;
484 PCW(pc)->mustBeBitSkipInst = 1;
487 PCW(pc)->invertBitSkipInst = 1;
492 if(pic14Mnemonics[opcode]->isBitInst)
493 pcosubtype = newpCodeOpBit(NULL,-1,0);
495 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
498 pci = PCI(newpCode(opcode,
499 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
501 /* Save the index of the maximum wildcard variable */
502 //if(p[1].pct[1].tok.n > sMaxWildVar)
503 // sMaxWildVar = p[1].pct[1].tok.n;
505 if(p[1].pct[1].tok.n > pcwb->nvars)
506 pcwb->nvars = p[1].pct[1].tok.n;
509 fprintf(stderr,"couldn't find mnemonic\n");
515 /*-----------------------------------------------------------------*/
516 /*-----------------------------------------------------------------*/
517 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
519 parsedPattern *p = pp;
522 pCodeInstruction *pci=NULL;
524 DFPRINTF((stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n));
526 opcode = getpCode(p->pct[0].tok.s,0);
528 fprintf(stderr, "Bad mnemonic\n");
532 pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
535 fprintf(stderr,"couldn't find mnemonic\n");
541 /*-----------------------------------------------------------------*/
542 /*-----------------------------------------------------------------*/
543 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
545 parsedPattern *p = pp;
549 pCodeInstruction *pci=NULL;
552 dest = cvt_extract_destination(&p[3]);
554 DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
561 opcode = getpCode(p->pct[0].tok.s,dest);
563 fprintf(stderr, "Bad mnemonic\n");
567 if(pic14Mnemonics[opcode]->isBitInst) {
568 pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
569 if(pcosubtype == NULL) {
570 fprintf(stderr, "bad operand?\n");
575 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
578 pci = PCI(newpCode(opcode,pcosubtype));
581 fprintf(stderr,"couldn't find mnemonic\n");
587 /*-----------------------------------------------------------------*/
588 /* cvt_altpat_mem2a - convert assembly line type to a pCode */
589 /* instruction with 1 wild operand and a */
590 /* destination operand (e.g. w or f) */
593 /* pp[1] - wild var */
595 /* pp[3] - destination */
597 /*-----------------------------------------------------------------*/
598 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
600 parsedPattern *p = pp;
604 pCodeInstruction *pci=NULL;
607 dest = cvt_extract_destination(&p[3]);
609 DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
616 opcode = getpCode(p->pct[0].tok.s,dest);
618 fprintf(stderr, "Bad mnemonic\n");
622 if(pic14Mnemonics[opcode]->isBitInst)
623 pcosubtype = newpCodeOp(NULL,PO_BIT);
625 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
628 pci = PCI(newpCode(opcode,
629 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
631 /* Save the index of the maximum wildcard variable */
632 //if(p[1].pct[1].tok.n > sMaxWildVar)
633 // sMaxWildVar = p[1].pct[1].tok.n;
635 if(p[1].pct[1].tok.n > pcwb->nvars)
636 pcwb->nvars = p[1].pct[1].tok.n;
639 fprintf(stderr,"couldn't find mnemonic\n");
645 /*-----------------------------------------------------------------*/
646 /* tokenizeLineNode - Convert a string (of char's) that was parsed */
647 /* by SDCCpeeph.c into a string of tokens. */
650 /* The tokenizer is of the classic type. When an item is encounterd*/
651 /* it is converted into a token. The token is a structure that */
652 /* encodes the item's type and it's value (when appropriate). */
654 /* Accepted token types: */
655 /* SPACE NUMBER STRING % : , ; */
659 /*-----------------------------------------------------------------*/
662 static void tokenizeLineNode(char *ln)
665 tokIdx = 0; // Starting off at the beginning
666 tokArr[0].tt = PCT_NULL; // and assume invalid character for first token.
674 // add a SPACE token and eat the extra spaces.
675 tokArr[tokIdx++].tt = PCT_SPACE;
676 while (isspace (*ln))
683 tokArr[tokIdx].tt = PCT_NUMBER;
684 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
692 tokArr[tokIdx++].tt = PCT_PERCENT;
695 tokArr[tokIdx++].tt = PCT_LESSTHAN;
698 tokArr[tokIdx++].tt = PCT_GREATERTHAN;
701 tokArr[tokIdx++].tt = PCT_COLON;
704 tokArr[tokIdx].tok.s = Safe_strdup(ln);
705 tokArr[tokIdx++].tt = PCT_COMMENT;
706 tokArr[tokIdx].tt = PCT_NULL;
709 tokArr[tokIdx++].tt = PCT_COMMA;
714 if(isalpha(*ln) || (*ln == '_') ) {
718 while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
724 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
725 tokArr[tokIdx++].tt = PCT_STRING;
730 /* Advance to next character in input string .
731 * Note, if none of the tests passed above, then
732 * we effectively ignore the `bad' character.
733 * Since the line has already been parsed by SDCCpeeph,
734 * chance are that there are no invalid characters... */
740 tokArr[tokIdx].tt = 0;
744 /*-----------------------------------------------------------------*/
745 /*-----------------------------------------------------------------*/
749 void dump1Token(pCodeTokens tt)
754 fprintf(stderr, " space ");
757 fprintf(stderr, " pct %%");
760 fprintf(stderr, " pct <");
762 case PCT_GREATERTHAN:
763 fprintf(stderr, " pct >");
766 fprintf(stderr, " col :");
769 fprintf(stderr, " comma , ");
772 fprintf(stderr, " comment ");
773 //fprintf(stderr,"%s",tokArr[i].tok.s);
776 fprintf(stderr, " str ");
777 //fprintf(stderr,"%s",tokArr[i].tok.s);
780 fprintf(stderr, " num ");
781 //fprintf(stderr,"%d",tokArr[i].tok.n);
784 fprintf(stderr, " null ");
791 /*-----------------------------------------------------------------*/
792 /*-----------------------------------------------------------------*/
794 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
798 if(!pct || !pat || !*pat)
801 //DFPRINTF((stderr,"comparing against:\n"));
803 while(i < max_tokens) {
806 //DFPRINTF((stderr,"matched\n"));
810 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
824 /*-----------------------------------------------------------------*/
825 /*-----------------------------------------------------------------*/
827 int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
831 if(!pct || !pat || !*pct)
835 while(i < max_tokens) {
838 //DFPRINTF((stderr,"matched\n"));
842 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
844 if( !pat || !pat->pcp )
847 if (pat->pcp->pt != *pct)
850 //DFPRINTF((stderr," pct=%d\n",*pct));
859 /*-----------------------------------------------------------------*/
860 /*-----------------------------------------------------------------*/
862 int advTokIdx(int *v, int amt)
865 if((unsigned) (*v + amt) > tokIdx)
873 /*-----------------------------------------------------------------*/
874 /* parseTokens - convert the tokens corresponding to a single line */
875 /* of a peep hole assembly into a pCode object. */
880 /* This is a simple parser that looks for strings of the type */
881 /* allowed in the peep hole definition file. Essentially the format*/
882 /* is the same as a line of assembly: */
884 /* label: mnemonic op1, op2, op3 ; comment */
886 /* Some of these items aren't present. It's the job of the parser */
887 /* to determine which are and convert those into the appropriate */
889 /*-----------------------------------------------------------------*/
891 void parseTokens(pCodeWildBlock *pcwb)
899 for(i=0; i<=tokIdx; i++)
900 dump1Token(tokArr[i].tt);
912 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
913 char * cP1stop = NULL;
914 char * cP2ndop = NULL;
916 //pCodeOp *pcl = NULL; // Storage for a label
917 //pCodeOp *pco1 = NULL; // 1st operand
918 //pCodeOp *pco2 = NULL; // 2nd operand
919 //pCode *pc = NULL; // Mnemonic
930 ParseStates state = PS_START;
937 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
938 && (advTokIdx(<okIdx, 1)) ) // eat space
942 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
945 switch(pcpArr[lpcpIdx].pt) {
947 if(state == PS_START){
948 DFPRINTF((stderr," label\n"));
949 state = PS_HAVE_LABEL;
951 DFPRINTF((stderr," bad state (%d) for label\n",state));
955 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
959 DFPRINTF((stderr," mnem\n"));
960 cPmnem = tokArr[ltokIdx].tok.s;
961 state = PS_HAVE_MNEM;
964 DFPRINTF((stderr," 1st operand\n"));
965 cP1stop = tokArr[ltokIdx].tok.s;
966 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
967 state = PS_HAVE_1OPERAND;
969 case PS_HAVE_1OPERAND:
970 DFPRINTF((stderr," error expecting comma\n"));
973 DFPRINTF((stderr," 2 operands\n"));
974 cP2ndop = tokArr[ltokIdx].tok.s;
976 case PS_HAVE_2OPERANDS:
985 DFPRINTF((stderr," wild mnem\n"));
986 state = PS_HAVE_MNEM;
989 DFPRINTF((stderr," 1st operand is wild\n"));
990 state = PS_HAVE_1OPERAND;
992 case PS_HAVE_1OPERAND:
993 DFPRINTF((stderr," error expecting comma\n"));
996 DFPRINTF((stderr," 2nd operand is wild\n"));
998 case PS_HAVE_2OPERANDS:
1007 fprintf(stderr," ERROR number\n");
1010 DFPRINTF((stderr," 1st operand is a number\n"));
1011 state = PS_HAVE_1OPERAND;
1013 case PS_HAVE_1OPERAND:
1014 fprintf(stderr," error expecting comma\n");
1017 DFPRINTF((stderr," 2nd operand is a number\n"));
1019 case PS_HAVE_2OPERANDS:
1027 if(state == PS_HAVE_1OPERAND){
1028 DFPRINTF((stderr," got a comma\n"));
1029 state = PS_HAVE_COMMA;
1031 fprintf(stderr," unexpected comma\n");
1035 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1036 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1039 //dump1Token(tokArr[ltokIdx].tt);
1041 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1042 DFPRINTF((stderr," reached end \n"));
1049 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1053 parsedPatArr[lparsedPatIdx].pcp = NULL;
1054 parsedPatArr[lparsedPatIdx].pct = NULL;
1060 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1063 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1064 //if(pc && pc->print)
1065 // pc->print(stderr,pc);
1066 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1068 //if(curBlock && pc)
1069 //addpCode2pBlock(curBlock, pc);
1070 addpCode2pBlock(pcwb->pb, pc);
1076 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1079 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1083 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1084 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1085 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1088 while(j<lparsedPatIdx);
1090 DFPRINTF((stderr,"\n"));
1097 /*-----------------------------------------------------------------*/
1099 /*-----------------------------------------------------------------*/
1100 void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
1106 for( ; ln; ln = ln->next) {
1108 //DFPRINTF((stderr,"%s\n",ln->line));
1110 tokenizeLineNode(ln->line);
1116 /*-----------------------------------------------------------------*/
1117 /* peepRuleCondition */
1118 /*-----------------------------------------------------------------*/
1119 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1124 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1125 /* brute force compares for now */
1127 if(STRCASECMP(cond, "NZ") == 0) {
1128 //DFPRINTF((stderr,"found NZ\n"));
1129 pcp->postFalseCond = PCC_Z;
1136 void initpCodeWildBlock(pCodeWildBlock *pcwb)
1139 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1145 pcwb->wildpCodes = NULL;
1146 pcwb->wildpCodeOps = NULL;
1149 pcwb->nwildpCodes = 0;
1154 void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1161 pcwb->nops = pcwb->nvars;
1163 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1164 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1166 pcwb->nwildpCodes++;
1167 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1171 void initpCodePeep(pCodePeep *pcp)
1174 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1179 initpCodeWildBlock(&pcp->target);
1180 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1182 initpCodeWildBlock(&pcp->replace);
1183 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1187 /*-----------------------------------------------------------------*/
1188 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1191 /* SDCCpeeph parses the peep rules file and extracts variables, */
1192 /* removes white space, and checks the syntax. This function */
1193 /* extends that processing to produce pCode objects. You can kind */
1194 /* think of this function as an "assembler", though instead of */
1195 /* taking raw text to produce machine code, it produces pCode. */
1197 /*-----------------------------------------------------------------*/
1198 extern void pic14initpCodePeepCommands(void);
1200 void peepRules2pCode(peepRule *rules)
1204 pCodePeep *currentRule;
1205 pCodePeepSnippets *pcps;
1207 pic14initpCodePeepCommands();
1209 /* The rules are in a linked-list. Each rule has two portions */
1210 /* There's the `target' and there's the `replace'. The target */
1211 /* is compared against the SDCC generated code and if it */
1212 /* matches, it gets replaced by the `replace' block of code. */
1214 /* Here we loop through each rule and convert the target's and*/
1215 /* replace's into pCode target and replace blocks */
1217 for (pr = rules; pr; pr = pr->next) {
1219 //DFPRINTF((stderr,"\nRule:\n\n"));
1221 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1222 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1225 curPeep = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1227 curPeep->vars = NULL;
1228 curPeep->wildpCodes = NULL; curPeep->wildpCodeOps = NULL;
1229 curPeep->postFalseCond = PCC_NONE;
1230 curPeep->postTrueCond = PCC_NONE;
1233 curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL);
1237 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1238 initpCodePeep(currentRule);
1240 /* Convert the target block */
1241 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1243 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1244 //printpBlock(stderr, curBlock);
1246 //DFPRINTF((stderr,"target with labels merged:\n"));
1247 //pBlockMergeLabels(curBlock);
1248 pBlockMergeLabels(currentRule->target.pb);
1249 //printpBlock(stderr, currentRule->replace.pb);
1251 //#ifdef PCODE_DEBUG
1252 // printpBlock(stderr, curBlock);
1254 //DFPRINTF((stderr,"\nReplaced by:\n"));
1257 //curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL);
1259 /* Convert the replace block */
1260 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1262 //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
1263 //printpBlock(stderr, curBlock);
1265 //DFPRINTF((stderr,"replace with labels merged:\n"));
1266 //pBlockMergeLabels(curBlock);
1267 pBlockMergeLabels(currentRule->replace.pb);
1268 //printpBlock(stderr, currentRule->replace.pb);
1270 peepRuleCondition(pr->cond,currentRule);
1272 /* The rule has been converted to pCode. Now allocate
1273 * space for the wildcards */
1277 curPeep->nvars = sMaxWildVar;
1278 curPeep->vars = Safe_calloc(sMaxWildVar, sizeof(char *));
1280 curPeep->nops = sMaxWildVar;
1281 curPeep->wildpCodeOps = Safe_calloc(sMaxWildVar, sizeof(pCodeOp *));
1283 curPeep->nwildpCodes = ++sMaxWildMnem;
1284 curPeep->wildpCodes = Safe_calloc(sMaxWildMnem, sizeof(char *));
1286 postinit_pCodeWildBlock(¤tRule->target);
1288 //return; // debug ... don't want to go through all the rules yet
1292 pCodePeep *peepBlock;
1295 peeprules = (_DLL *)peepSnippets;
1296 //fprintf(stderr,"target rules\n");
1298 //fprintf(stderr," rule:\n");
1299 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1300 //printpBlock(stderr, peepBlock->target.pb);
1301 peeprules = peeprules->next;
1303 //fprintf(stderr," ... done\n");
1308 void printpCodeString(FILE *of, pCode *pc, int max)
1312 while(pc && (i++<max)) {
1318 /*-----------------------------------------------------------------*/
1319 /* _DLL * DLL_append */
1321 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1322 /* If The list to which we want to append is non-existant then one */
1323 /* is created. Other wise, the end of the list is sought out and */
1324 /* a new DLL object is appended to it. In either case, the void */
1325 /* *data is added to the newly created DLL object. */
1326 /*-----------------------------------------------------------------*/
1328 static void * DLL_append(_DLL *list, _DLL *next)
1333 /* If there's no list, then create one: */
1335 next->next = next->prev = NULL;
1340 /* Search for the end of the list. */
1345 /* Now append the new DLL object */
1356 /*-----------------------------------------------------------------
1358 pCode peephole optimization
1361 The pCode "peep hole" optimization is not too unlike the peep hole
1362 optimization in SDCCpeeph.c. The major difference is that here we
1363 use pCode's whereas there we use ASCII strings. The advantage with
1364 pCode's is that we can ascertain flow information in the instructions
1368 <FIX ME> - elaborate...
1370 -----------------------------------------------------------------*/
1374 /*-----------------------------------------------------------------*/
1375 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1377 /* return conditions */
1378 /* 1 - The Condition was found for a pCode's input */
1379 /* 0 - No matching condition was found for the whole chain */
1380 /* -1 - The Condition was found for a pCode's output */
1382 /*-----------------------------------------------------------------*/
1383 int pCodeSearchCondition(pCode *pc, unsigned int cond)
1388 /* If we reach a function end (presumably an end since we most
1389 probably began the search in the middle of a function), then
1390 the condition was not found. */
1391 if(pc->type == PC_FUNCTION)
1394 if(pc->type == PC_OPCODE) {
1395 if(PCI(pc)->inCond & cond)
1397 if(PCI(pc)->outCond & cond)
1407 /*-----------------------------------------------------------------
1408 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1410 * Compare two pCodeOp's and return 1 if they're the same
1411 *-----------------------------------------------------------------*/
1412 int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1415 if(!pcops || !pcopd)
1418 fprintf(stderr," Comparing operands %s",
1421 fprintf(stderr," to %s\n",
1425 if(pcops->type != pcopd->type) {
1426 //fprintf(stderr," - fail - diff types\n");
1427 return 0; // different types
1430 if(!pcops->name || !pcopd->name || strcmp(pcops->name,pcopd->name)) {
1431 //fprintf(stderr," - fail - diff names\n");
1432 return 0; // different names
1435 switch(pcops->type) {
1437 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1438 //fprintf(stderr, " - fail different instances\n");
1446 //fprintf(stderr," - pass\n");
1451 int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1455 /* Check for a label associated with this wild pCode */
1456 // If the wild card has a label, make sure the source code does too.
1457 if(PCI(pcd)->label) {
1460 if(!PCI(pcs)->label)
1463 pcl = PCI(pcd)->label->pc;
1465 labindex = -PCL(pcl)->key;
1466 //DFPRINTF((stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex));
1467 if(peepBlock->target.vars[labindex] == NULL) {
1468 // First time to encounter this label
1469 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1470 //DFPRINTF((stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex]));
1472 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1473 // DFPRINTF((stderr,"labels don't match\n"));
1476 //DFPRINTF((stderr,"matched a label\n"));
1479 // DFPRINTF((stderr,"destination doesn't have a label\n"));
1489 /*-----------------------------------------------------------------*/
1490 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1491 /* see they're the same. */
1493 /* In this context, "source" refers to the coded generated by gen.c*/
1494 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1495 /* ination has no wild cards, then MatchLine will compare the two */
1496 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1497 /* has wildcards, then those get expanded. When a wild card is */
1498 /* encountered for the first time it autmatically is considered a */
1499 /* match and the object that matches it is referenced in the */
1500 /* variables or opcodes array (depending on the type of match). */
1504 /* *peepBlock - A pointer to the peepBlock that contains the */
1505 /* entire rule to which the destination pcode belongs*/
1506 /* *pcs - a pointer to the source pcode */
1507 /* *pcd - a pointer to the destination pcode */
1510 /* 1 - pcodes match */
1511 /* 0 - pcodes don't match */
1514 /*-----------------------------------------------------------------*/
1516 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1518 int index; // index into wild card arrays
1520 /* one-for-one match. Here the source and destination opcodes
1521 * are not wild. However, there may be a label or a wild operand */
1523 if(pcs->type == pcd->type) {
1525 if(pcs->type == PC_OPCODE) {
1527 /* If the opcodes don't match then the line doesn't match */
1528 if(PCI(pcs)->op != PCI(pcd)->op)
1532 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1533 pcs->print(stderr,pcs);
1534 pcd->print(stderr,pcd);
1537 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1540 /* Compare the operands */
1541 if(PCI(pcd)->pcop) {
1542 if (PCI(pcd)->pcop->type == PO_WILD) {
1543 index = PCOW(PCI(pcd)->pcop)->id;
1545 //DFPRINTF((stderr,"destination is wild\n"));
1546 #ifdef DEBUG_PCODEPEEP
1547 if (index > peepBlock->nops) {
1548 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1553 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1554 if(!peepBlock->target.wildpCodeOps[index]) {
1555 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1557 //if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
1561 pcs->print(stderr,pcs);
1562 pcd->print(stderr,pcd);
1564 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1565 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1569 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1575 switch(PCI(pcs)->pcop->type) {
1579 n = PCOR(PCI(pcs)->pcop)->r->name;
1583 n = PCI(pcs)->pcop->name;
1586 if(peepBlock->target.vars[index])
1587 return (strcmp(peepBlock->target.vars[index],n) == 0);
1589 // DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1590 peepBlock->target.vars[index] = n;
1596 /* FIXME - need an else to check the case when the destination
1597 * isn't a wild card */
1599 /* The pcd has no operand. Lines match if pcs has no operand either*/
1600 return (PCI(pcs)->pcop == NULL);
1604 /* Compare a wild instruction to a regular one. */
1606 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1609 index = PCW(pcd)->id;
1611 // DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1612 //pcs->print(stderr,pcs);
1613 //pcd->print(stderr,pcd);
1615 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1617 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1620 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1621 // doesn't match because the wild pcode must be a bit skip
1622 //fprintf(stderr," Failing match because bit skip is req:\n");
1623 //pcd->print(stderr,pcd);
1624 //pcs->print(stderr,pcs);
1628 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1629 // doesn't match because the wild pcode must *not* be a bit skip
1630 //fprintf(stderr," Failing match because don't want skip :\n");
1631 //pcd->print(stderr,pcd);
1632 //pcs->print(stderr,pcs);
1636 if(PCW(pcd)->operand) {
1637 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1638 if(peepBlock->target.vars[index]) {
1639 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1642 DFPRINTF((stderr," (matched)\n"));
1644 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1645 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n"),
1646 peepBlock->vars[index],
1647 PCI(pcs)->pcop->name);
1652 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1657 pcs = findNextInstruction(pcs->next);
1659 //DFPRINTF((stderr," (next to match)\n"));
1660 //pcs->print(stderr,pcs);
1661 } else if(pcd->next) {
1662 /* oops, we ran out of code, but there's more to the rule */
1666 return 1; /* wild card matches */
1672 /*-----------------------------------------------------------------*/
1673 /*-----------------------------------------------------------------*/
1674 void pCodePeepClrVars(pCodePeep *pcp)
1681 for(i=0;i<pcp->target.nvars; i++) {
1682 pcp->target.vars[i] = NULL;
1683 pcp->target.wildpCodeOps[i] = NULL;
1687 /*-----------------------------------------------------------------*/
1688 /* pCodeInsertAfter - splice in the pCode chain starting with pc2 */
1689 /* into the pCode chain containing pc1 */
1690 /*-----------------------------------------------------------------*/
1691 void pCodeInsertAfter(pCode *pc1, pCode *pc2)
1697 pc2->next = pc1->next;
1699 pc1->next->prev = pc2;
1707 /*-----------------------------------------------------------------*/
1708 /* pCodeOpCopy - copy a pcode operator */
1709 /*-----------------------------------------------------------------*/
1710 pCodeOp *pCodeOpCopy(pCodeOp *pcop)
1712 pCodeOp *pcopnew=NULL;
1717 switch(pcop->type) {
1720 //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
1721 pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1722 PCORB(pcopnew)->bit = PCORB(pcop)->bit;
1723 PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
1728 /* Here we expand the wild card into the appropriate type: */
1729 /* By recursively calling pCodeOpCopy */
1730 //DFPRINTF((stderr,"pCodeOpCopy wild\n"));
1731 if(PCOW(pcop)->matched)
1732 pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
1735 pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
1736 pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
1737 //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
1744 //DFPRINTF((stderr,"pCodeOpCopy label\n"));
1745 pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
1746 PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
1750 pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
1751 PCOI(pcopnew)->index = PCOI(pcop)->index;
1752 PCOI(pcopnew)->offset = PCOI(pcop)->offset;
1753 PCOI(pcopnew)->_const = PCOI(pcop)->_const;
1757 //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
1758 pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
1759 PCOL(pcopnew)->lit = PCOL(pcop)->lit;
1764 pcopnew = newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
1765 PCOR(pcopnew)->r = PCOR(pcop)->r;
1766 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1767 DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
1771 case PO_GPR_REGISTER:
1775 //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
1776 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1777 PCOR(pcopnew)->r = PCOR(pcop)->r;
1778 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1779 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1780 DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
1784 //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
1785 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1786 PCOR(pcopnew)->r = PCOR(pcop)->r;
1787 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1788 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1791 DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
1792 case PO_SFR_REGISTER:
1800 //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
1801 pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
1805 pcopnew->type = pcop->type;
1807 pcopnew->name = Safe_strdup(pcop->name);
1809 pcopnew->name = NULL;
1815 /*-----------------------------------------------------------------*/
1816 /* pCodeCopy - copy a pcode */
1817 /*-----------------------------------------------------------------*/
1818 static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert)
1820 pCodeInstruction *new_pci;
1823 new_pci = PCI(newpCode(pci->inverted_op,pci->pcop));
1825 new_pci = PCI(newpCode(pci->op,pci->pcop));
1827 new_pci->pc.pb = pci->pc.pb;
1828 new_pci->from = pci->from;
1829 new_pci->to = pci->to;
1830 new_pci->label = pci->label;
1831 new_pci->pcflow = pci->pcflow;
1833 return PCODE(new_pci);
1836 /*-----------------------------------------------------------------*/
1837 /*-----------------------------------------------------------------*/
1838 void pCodeDeleteChain(pCode *f,pCode *t)
1844 DFPRINTF((stderr,"delete pCode:\n"));
1847 //f->delete(f); this dumps core...
1854 /*-----------------------------------------------------------------*/
1855 /*-----------------------------------------------------------------*/
1856 int pCodePeepMatchRule(pCode *pc)
1858 pCodePeep *peepBlock;
1863 peeprules = (_DLL *)peepSnippets;
1866 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1868 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
1869 fprintf(stderr, "skipping rule because target pb is NULL\n");
1873 pCodePeepClrVars(peepBlock);
1876 if(IS_PCCOMMENT(pcin))
1877 pc = pcin = findNextInstruction(pcin->next);
1879 pct = peepBlock->target.pb->pcHead;
1881 while(pct && pcin) {
1883 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1886 pcin = findNextInstruction(pcin->next);
1889 //DFPRINTF((stderr," matched\n"));
1891 DFPRINTF((stderr," partial match... no more code\n"));
1895 DFPRINTF((stderr," end of rule\n"));
1900 /* So far we matched the rule up to the point of the conditions .
1901 * In other words, all of the opcodes match. Now we need to see
1902 * if the post conditions are satisfied.
1903 * First we check the 'postFalseCond'. This means that we check
1904 * to see if any of the subsequent pCode's in the pCode chain
1905 * following the point just past where we have matched depend on
1906 * the `postFalseCond' as input then we abort the match
1908 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
1909 if (pcin && peepBlock->postFalseCond &&
1910 (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
1920 /* We matched a rule! Now we have to go through and remove the
1921 inefficient code with the optimized version */
1923 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
1924 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
1925 DFPRINTF((stderr,"first thing matched\n"));
1926 pc->print(stderr,pc);
1929 DFPRINTF((stderr,"last thing matched\n"));
1930 pcin->print(stderr,pcin);
1933 /* Unlink the original code */
1935 pcprev->next = pcin;
1937 pcin->prev = pc->prev;
1941 /* Converted the deleted pCodes into comments */
1948 while(pc && pc!=pcin) {
1949 pCode2str(&buf[2], 254, pc);
1950 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
1951 pcprev = pcprev->next;
1957 pCodeDeleteChain(pc,pcin);
1959 /* Generate the replacement code */
1961 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
1964 /* If the replace pcode is an instruction with an operand, */
1965 /* then duplicate the operand (and expand wild cards in the process). */
1966 if(pcr->type == PC_OPCODE) {
1967 if(PCI(pcr)->pcop) {
1968 /* The replacing instruction has an operand.
1970 if(PCI(pcr)->pcop->type == PO_WILD) {
1971 int index = PCOW(PCI(pcr)->pcop)->id;
1972 //DFPRINTF((stderr,"copying wildopcode\n"));
1973 if(peepBlock->target.wildpCodeOps[index])
1974 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
1976 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
1978 pcop = pCodeOpCopy(PCI(pcr)->pcop);
1980 //DFPRINTF((stderr,"inserting pCode\n"));
1981 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
1982 } else if (pcr->type == PC_WILD) {
1983 if(PCW(pcr)->invertBitSkipInst)
1984 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
1985 pCodeInsertAfter(pc,
1986 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
1987 PCW(pcr)->invertBitSkipInst));
1988 } else if (pcr->type == PC_COMMENT) {
1989 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
1995 // pc->print(stderr,pc);
2002 peeprules = peeprules->next;