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 -------------------------------------------------------------------------*/
22 #include "pcodeflow.h"
27 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
30 /****************************************************************/
31 /****************************************************************/
39 typedef struct pCodePeepSnippets
46 /****************************************************************/
50 /****************************************************************/
52 static pCodePeepSnippets *peepSnippets=NULL;
55 typedef struct pCodeToken
57 int tt; // token type;
66 static pCodeToken tokArr[50];
67 static unsigned tokIdx=0;
85 typedef struct parsedPattern {
86 struct pcPattern *pcp;
90 #define MAX_PARSEDPATARR 50
91 static parsedPattern parsedPatArr[MAX_PARSEDPATARR];
103 static char pcpat_label[] = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
104 static char pcpat_number[] = {PCT_NUMBER, 0};
105 static char pcpat_string[] = {PCT_STRING, 0};
106 static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
107 static char pcpat_wildVar[] = {PCT_PERCENT, PCT_NUMBER, 0};
108 static char pcpat_comma[] = {PCT_COMMA, 0};
109 static char pcpat_comment[] = {PCT_COMMENT, 0};
112 typedef struct pcPattern {
113 char pt; // Pattern type
114 char *tokens; // list of tokens that describe the pattern
115 void * (*f) (void *,pCodeWildBlock *);
118 static pcPattern pcpArr[] = {
119 {PCP_LABEL, pcpat_label, NULL},
120 {PCP_WILDSTR, pcpat_wildString, NULL},
121 {PCP_STR, pcpat_string, NULL},
122 {PCP_WILDVAR, pcpat_wildVar, NULL},
123 {PCP_COMMA, pcpat_comma, NULL},
124 {PCP_COMMENT, pcpat_comment, NULL},
125 {PCP_NUMBER, pcpat_number, NULL}
128 #define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
130 // Assembly Line Token
144 static char alt_comment[] = { PCP_COMMENT, 0};
145 static char alt_label[] = { PCP_LABEL, 0};
146 static char alt_mnem0[] = { PCP_STR, 0};
147 static char alt_mnem0a[] = { PCP_WILDVAR, 0};
148 static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
149 static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0};
150 static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
151 static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
152 static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
153 static char alt_mnem3[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
155 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
156 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
157 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
158 static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
159 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
160 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
161 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
162 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
163 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
164 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
166 static pcPattern altArr[] = {
167 {ALT_LABEL, alt_label, cvt_altpat_label},
168 {ALT_COMMENT, alt_comment,cvt_altpat_comment},
169 {ALT_MNEM3, alt_mnem3, cvt_altpat_mnem3},
170 {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
171 {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
172 {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
173 {ALT_MNEM1A, alt_mnem1a, cvt_altpat_mnem1a},
174 {ALT_MNEM1, alt_mnem1, cvt_altpat_mnem1},
175 {ALT_MNEM0A, alt_mnem0a, cvt_altpat_mnem0a},
176 {ALT_MNEM0, alt_mnem0, cvt_altpat_mnem0},
180 #define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
182 // forward declarations
183 static void * DLL_append(_DLL *list, _DLL *next);
185 /*-----------------------------------------------------------------*/
186 /* cvt_extract_destination - helper function extracts the register */
187 /* destination from a parsedPattern. */
189 /*-----------------------------------------------------------------*/
190 static int cvt_extract_destination(parsedPattern *pp)
193 if(pp->pct[0].tt == PCT_STRING) {
195 // just check first letter for now
197 if(toupper((unsigned char)*pp->pct[0].tok.s) == 'F')
200 } else if (pp->pct[0].tt == PCT_NUMBER) {
210 /*-----------------------------------------------------------------*/
211 /* pCodeOp *cvt_extract_status(char *reg, char *bit) */
212 /* if *reg is the "status" register and *bit is one of the */
213 /* status bits, then this function will create a new pCode op */
214 /* containing the status register. */
215 /*-----------------------------------------------------------------*/
217 static pCodeOp *cvt_extract_status(char *reg, char *bit)
221 if(STRCASECMP(reg, pc_status.pcop.name))
228 if(toupper((unsigned char)*bit) == 'C')
229 return PCOP(popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT));
230 if(toupper((unsigned char)*bit) == 'Z')
231 return PCOP(popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT));
235 if(len ==2 && toupper((unsigned char)bit[0]) == 'D' && toupper((unsigned char)bit[1]) == 'C')
236 return PCOP(popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT));
242 /*-----------------------------------------------------------------*/
243 /* cvt_altpat_label - convert assembly line type to a pCode label */
244 /* INPUT: pointer to the parsedPattern */
248 /* label pattern => '%' number ':' */
249 /* at this point, we wish to extract only the 'number' */
251 /*-----------------------------------------------------------------*/
252 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
254 parsedPattern *p = pp;
256 DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
257 return newpCodeLabel(NULL,-p->pct[1].tok.n);
261 /*-----------------------------------------------------------------*/
262 /* cvt_altpat_comment - convert assembly line type to a comment */
263 /* INPUT: pointer to the parsedPattern */
265 /* pp[0] - comment */
268 /*-----------------------------------------------------------------*/
269 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
271 parsedPattern *p = pp;
273 DFPRINTF((stderr,"altpat_comment = %s\n",p->pct[0].tok.s));
274 return newpCodeCharP(p->pct[0].tok.s);
278 /*-----------------------------------------------------------------*/
279 /* cvt_altpat_mem0 - convert assembly line type to a wild pCode */
284 /*-----------------------------------------------------------------*/
285 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
287 parsedPattern *p = pp;
290 pCodeInstruction *pci=NULL;
292 DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s));
294 opcode = getpCode(p->pct[0].tok.s,0);
297 /* look for special command strings like _NOTBITSKIP_ */
299 //fprintf(stderr, "Bad mnemonic\n");
301 opcode = getpCodePeepCommand(p->pct[0].tok.s);
303 // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
307 pci = PCI(newpCode(opcode, NULL));
310 fprintf(stderr,"couldn't find mnemonic\n");
316 /*-----------------------------------------------------------------*/
317 /* cvt_altpat_mem0a - convert assembly line type to a wild pCode */
320 /* pp[0] - wild var */
322 /*-----------------------------------------------------------------*/
323 static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
325 parsedPattern *p = pp;
327 DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n));
329 /* Save the index of the maximum wildcard mnemonic */
330 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
331 pcwb->nwildpCodes = p[0].pct[1].tok.n;
333 return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
337 /*-----------------------------------------------------------------*/
338 /* cvt_altpat_mem1 - convert assembly line type to a pCode */
339 /* instruction with 1 operand. */
342 /* pp[1] - Operand */
344 /*-----------------------------------------------------------------*/
345 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
348 parsedPattern *p = pp;
351 pCodeInstruction *pci=NULL;
354 DFPRINTF((stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s));
356 opcode = getpCode(p->pct[0].tok.s,0);
358 //fprintf(stderr, "Bad mnemonic\n");
359 opcode = getpCodePeepCommand(p->pct[0].tok.s);
361 //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
366 if(pic14Mnemonics[opcode]->isBitInst)
367 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
369 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
372 pci = PCI(newpCode(opcode, pcosubtype));
375 fprintf(stderr,"couldn't find mnemonic\n");
381 /*-----------------------------------------------------------------*/
382 /* cvt_altpat_mem1a - convert assembly line type to a pCode */
383 /* instruction with 1 wild operand. */
386 /* pp[1] - wild var */
388 /*-----------------------------------------------------------------*/
389 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
391 parsedPattern *p = pp;
394 pCodeInstruction *pci=NULL;
397 DFPRINTF((stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n));
399 opcode = getpCode(p->pct[0].tok.s,0);
401 int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
405 fprintf(stderr, "Bad mnemonic\n");
409 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
410 pcwb->nwildpCodes = p[0].pct[1].tok.n;
412 pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
416 PCW(pc)->mustNotBeBitSkipInst = 1;
419 PCW(pc)->mustBeBitSkipInst = 1;
422 PCW(pc)->invertBitSkipInst = 1;
427 if(pic14Mnemonics[opcode]->isBitInst)
428 pcosubtype = newpCodeOpBit(NULL,-1,0);
430 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
433 pci = PCI(newpCode(opcode,
434 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
436 /* Save the index of the maximum wildcard variable */
437 if(p[1].pct[1].tok.n > pcwb->nvars)
438 pcwb->nvars = p[1].pct[1].tok.n;
441 fprintf(stderr,"couldn't find mnemonic\n");
447 /*-----------------------------------------------------------------*/
448 /*-----------------------------------------------------------------*/
449 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
451 parsedPattern *p = pp;
454 pCodeInstruction *pci=NULL;
456 DFPRINTF((stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n));
458 opcode = getpCode(p->pct[0].tok.s,0);
460 fprintf(stderr, "Bad mnemonic\n");
464 pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
467 fprintf(stderr,"couldn't find mnemonic\n");
473 /*-----------------------------------------------------------------*/
474 /* cvt_altpat_mnem2 */
479 /* pp[3] - destination */
480 /*-----------------------------------------------------------------*/
481 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
483 parsedPattern *p = pp;
487 pCodeInstruction *pci=NULL;
490 dest = cvt_extract_destination(&p[3]);
492 DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
499 opcode = getpCode(p->pct[0].tok.s,dest);
501 fprintf(stderr, "Bad mnemonic\n");
505 if(pic14Mnemonics[opcode]->isBitInst) {
506 pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
507 if(pcosubtype == NULL) {
508 fprintf(stderr, "bad operand?\n");
513 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
516 pci = PCI(newpCode(opcode,pcosubtype));
519 fprintf(stderr,"couldn't find mnemonic\n");
525 /*-----------------------------------------------------------------*/
526 /* cvt_altpat_mem2a - convert assembly line type to a pCode */
527 /* instruction with 1 wild operand and a */
528 /* destination operand (e.g. w or f) */
531 /* pp[1] - wild var */
533 /* pp[3] - destination */
535 /*-----------------------------------------------------------------*/
536 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
538 parsedPattern *p = pp;
542 pCodeInstruction *pci=NULL;
546 fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
550 dest = cvt_extract_destination(&p[3]);
552 DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
559 opcode = getpCode(p->pct[0].tok.s,dest);
561 fprintf(stderr, "Bad mnemonic\n");
565 if(pic14Mnemonics[opcode]->isBitInst)
566 pcosubtype = newpCodeOp(NULL,PO_BIT);
568 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
571 pci = PCI(newpCode(opcode,
572 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
574 /* Save the index of the maximum wildcard variable */
575 if(p[1].pct[1].tok.n > pcwb->nvars)
576 pcwb->nvars = p[1].pct[1].tok.n;
579 fprintf(stderr,"couldn't find mnemonic\n");
586 /*-----------------------------------------------------------------*/
587 /* cvt_altpat_mem3 - convert assembly line type to a pCode */
588 /* This rule is for bsf/bcf type instructions */
592 /* pp[1] - register */
596 /*-----------------------------------------------------------------*/
597 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
599 parsedPattern *p = pp;
601 int dest; // or could be bit position in the register
603 pCodeInstruction *pci=NULL;
604 pCodeOp *pcosubtype=NULL;
606 dest = cvt_extract_destination(&p[3]);
608 DFPRINTF((stderr,"altpat_mnem3 %s var %s bit (%d)\n",
614 opcode = getpCode(p->pct[0].tok.s,0);
616 fprintf(stderr, "Bad mnemonic\n");
621 if(pic14Mnemonics[opcode]->isBitInst) {
622 //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
624 //if(pcosubtype == NULL) {
625 pcosubtype = newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0);
628 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
630 if(pcosubtype == NULL) {
631 fprintf(stderr, "Bad operand\n");
635 pci = PCI(newpCode(opcode, pcosubtype));
638 fprintf(stderr,"couldn't find mnemonic\n");
644 /*-----------------------------------------------------------------*/
645 /* tokenizeLineNode - Convert a string (of char's) that was parsed */
646 /* by SDCCpeeph.c into a string of tokens. */
649 /* The tokenizer is of the classic type. When an item is encounterd*/
650 /* it is converted into a token. The token is a structure that */
651 /* encodes the item's type and it's value (when appropriate). */
653 /* Accepted token types: */
654 /* SPACE NUMBER STRING % : , ; */
658 /*-----------------------------------------------------------------*/
661 static void tokenizeLineNode(char *ln)
664 tokIdx = 0; // Starting off at the beginning
665 tokArr[0].tt = PCT_NULL; // and assume invalid character for first token.
673 if(isspace((unsigned char)*ln)) {
674 // add a SPACE token and eat the extra spaces.
675 tokArr[tokIdx++].tt = PCT_SPACE;
676 while (isspace ((unsigned char)*ln))
681 if(isdigit((unsigned char)*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((unsigned char)*ln) || (*ln == '_') ) {
718 while( (isalpha((unsigned char)*ln) || isdigit((unsigned char)*ln) || (*ln == '_')) && i<49)
724 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
725 tokArr[tokIdx++].tt = PCT_STRING;
728 fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
729 fprintf(stderr, "Line: %s\n",lnstart);
730 fprintf(stderr, "Token: '%c'\n",*ln);
735 /* Advance to next character in input string .
736 * Note, if none of the tests passed above, then
737 * we effectively ignore the `bad' character.
738 * Since the line has already been parsed by SDCCpeeph,
739 * chance are that there are no invalid characters... */
745 tokArr[tokIdx].tt = 0;
749 /*-----------------------------------------------------------------*/
750 /*-----------------------------------------------------------------*/
754 static void dump1Token(pCodeTokens tt)
759 fprintf(stderr, " space ");
762 fprintf(stderr, " pct %%");
765 fprintf(stderr, " pct <");
767 case PCT_GREATERTHAN:
768 fprintf(stderr, " pct >");
771 fprintf(stderr, " col :");
774 fprintf(stderr, " comma , ");
777 fprintf(stderr, " comment ");
778 //fprintf(stderr,"%s",tokArr[i].tok.s);
781 fprintf(stderr, " str ");
782 //fprintf(stderr,"%s",tokArr[i].tok.s);
785 fprintf(stderr, " num ");
786 //fprintf(stderr,"%d",tokArr[i].tok.n);
789 fprintf(stderr, " null ");
796 /*-----------------------------------------------------------------*/
797 /*-----------------------------------------------------------------*/
799 static int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
803 if(!pct || !pat || !*pat)
806 //DFPRINTF((stderr,"comparing against:\n"));
808 while(i < max_tokens) {
811 //DFPRINTF((stderr,"matched\n"));
815 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
829 /*-----------------------------------------------------------------*/
830 /*-----------------------------------------------------------------*/
832 static int altComparePattern(char *pct, parsedPattern *pat, int max_tokens)
836 if(!pct || !pat || !*pct)
840 while(i < max_tokens) {
843 //DFPRINTF((stderr,"matched\n"));
847 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
849 if( !pat || !pat->pcp )
852 if (pat->pcp->pt != *pct)
855 //DFPRINTF((stderr," pct=%d\n",*pct));
864 /*-----------------------------------------------------------------*/
865 /*-----------------------------------------------------------------*/
867 static int advTokIdx(int *v, int amt)
870 if((unsigned) (*v + amt) > tokIdx)
878 /*-----------------------------------------------------------------*/
879 /* parseTokens - convert the tokens corresponding to a single line */
880 /* of a peep hole assembly into a pCode object. */
885 /* This is a simple parser that looks for strings of the type */
886 /* allowed in the peep hole definition file. Essentially the format*/
887 /* is the same as a line of assembly: */
889 /* label: mnemonic op1, op2, op3 ; comment */
891 /* Some of these items aren't present. It's the job of the parser */
892 /* to determine which are and convert those into the appropriate */
894 /*-----------------------------------------------------------------*/
896 static int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
907 for(i=0; i<=tokIdx; i++)
908 dump1Token(tokArr[i].tt);
921 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
922 char * cP1stop = NULL;
923 char * cP2ndop = NULL;
925 //pCodeOp *pcl = NULL; // Storage for a label
926 //pCodeOp *pco1 = NULL; // 1st operand
927 //pCodeOp *pco2 = NULL; // 2nd operand
928 //pCode *pc = NULL; // Mnemonic
939 ParseStates state = PS_START;
946 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
947 && (advTokIdx(<okIdx, 1)) ) // eat space
951 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
954 switch(pcpArr[lpcpIdx].pt) {
956 if(state == PS_START){
957 DFPRINTF((stderr," label\n"));
958 state = PS_HAVE_LABEL;
960 DFPRINTF((stderr," bad state (%d) for label\n",state));
964 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
968 DFPRINTF((stderr," mnem\n"));
969 cPmnem = tokArr[ltokIdx].tok.s;
970 state = PS_HAVE_MNEM;
973 DFPRINTF((stderr," 1st operand\n"));
974 cP1stop = tokArr[ltokIdx].tok.s;
975 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
976 state = PS_HAVE_1OPERAND;
978 case PS_HAVE_1OPERAND:
979 DFPRINTF((stderr," error expecting comma\n"));
982 DFPRINTF((stderr," 2 operands\n"));
983 cP2ndop = tokArr[ltokIdx].tok.s;
985 case PS_HAVE_2OPERANDS:
994 DFPRINTF((stderr," wild mnem\n"));
995 state = PS_HAVE_MNEM;
998 DFPRINTF((stderr," 1st operand is wild\n"));
999 state = PS_HAVE_1OPERAND;
1001 case PS_HAVE_1OPERAND:
1002 DFPRINTF((stderr," error expecting comma\n"));
1005 DFPRINTF((stderr," 2nd operand is wild\n"));
1007 case PS_HAVE_2OPERANDS:
1016 fprintf(stderr," ERROR number\n");
1019 DFPRINTF((stderr," 1st operand is a number\n"));
1020 state = PS_HAVE_1OPERAND;
1022 case PS_HAVE_1OPERAND:
1023 fprintf(stderr," error expecting comma\n");
1026 DFPRINTF((stderr," 2nd operand is a number\n"));
1028 case PS_HAVE_2OPERANDS:
1036 if(state == PS_HAVE_1OPERAND){
1037 DFPRINTF((stderr," got a comma\n"));
1038 state = PS_HAVE_COMMA;
1040 fprintf(stderr," unexpected comma\n");
1046 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1047 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1050 //dump1Token(tokArr[ltokIdx].tt);
1052 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1053 DFPRINTF((stderr," reached end \n"));
1060 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1064 parsedPatArr[lparsedPatIdx].pcp = NULL;
1065 parsedPatArr[lparsedPatIdx].pct = NULL;
1071 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1074 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1075 //if(pc && pc->print)
1076 // pc->print(stderr,pc);
1077 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1082 return 0; // Only accept one line for now.
1084 addpCode2pBlock(pcwb->pb, pc);
1092 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1095 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1099 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1100 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1101 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1104 while(j<lparsedPatIdx);
1106 DFPRINTF((stderr,"\n"));
1113 /*-----------------------------------------------------------------*/
1115 /*-----------------------------------------------------------------*/
1116 static void peepRuleBlock2pCodeBlock(lineNode *ln, pCodeWildBlock *pcwb)
1122 for( ; ln; ln = ln->next) {
1124 //DFPRINTF((stderr,"%s\n",ln->line));
1126 tokenizeLineNode(ln->line);
1128 if(parseTokens(pcwb,NULL)) {
1130 fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
1131 fprintf(stderr,"Tokens:\n");
1133 dump1Token(tokArr[i].tt);
1140 /*-----------------------------------------------------------------*/
1141 /* peepRuleCondition */
1142 /*-----------------------------------------------------------------*/
1143 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1148 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1149 /* brute force compares for now */
1151 if(STRCASECMP(cond, "NZ") == 0) {
1152 //DFPRINTF((stderr,"found NZ\n"));
1153 pcp->postFalseCond = PCC_Z;
1159 static void initpCodeWildBlock(pCodeWildBlock *pcwb)
1162 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1168 pcwb->wildpCodes = NULL;
1169 pcwb->wildpCodeOps = NULL;
1172 pcwb->nwildpCodes = 0;
1177 static void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1184 pcwb->nops = pcwb->nvars;
1186 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1187 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1189 pcwb->nwildpCodes+=2;
1190 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1194 static void initpCodePeep(pCodePeep *pcp)
1197 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1202 initpCodeWildBlock(&pcp->target);
1203 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1205 initpCodeWildBlock(&pcp->replace);
1206 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1210 /*-----------------------------------------------------------------*/
1211 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1214 /* SDCCpeeph parses the peep rules file and extracts variables, */
1215 /* removes white space, and checks the syntax. This function */
1216 /* extends that processing to produce pCode objects. You can kind */
1217 /* think of this function as an "assembler", though instead of */
1218 /* taking raw text to produce machine code, it produces pCode. */
1220 /*-----------------------------------------------------------------*/
1221 void peepRules2pCode(peepRule *rules)
1225 pCodePeep *currentRule;
1226 pCodePeepSnippets *pcps;
1228 pic14initpCodePeepCommands();
1230 /* The rules are in a linked-list. Each rule has two portions */
1231 /* There's the `target' and there's the `replace'. The target */
1232 /* is compared against the SDCC generated code and if it */
1233 /* matches, it gets replaced by the `replace' block of code. */
1235 /* Here we loop through each rule and convert the target's and*/
1236 /* replace's into pCode target and replace blocks */
1238 for (pr = rules; pr; pr = pr->next) {
1240 //DFPRINTF((stderr,"\nRule:\n\n"));
1242 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1243 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1245 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1246 initpCodePeep(currentRule);
1248 /* Convert the target block */
1249 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1251 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1252 //printpBlock(stderr, currentRule->target.pb);
1254 pBlockMergeLabels(currentRule->target.pb);
1255 //printpBlock(stderr, currentRule->replace.pb);
1257 /* Convert the replace block */
1258 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1260 //DFPRINTF((stderr,"replace with labels merged:\n"));
1262 pBlockMergeLabels(currentRule->replace.pb);
1263 //printpBlock(stderr, currentRule->replace.pb);
1265 peepRuleCondition(pr->cond,currentRule);
1267 /* The rule has been converted to pCode. Now allocate
1268 * space for the wildcards */
1270 postinit_pCodeWildBlock(¤tRule->target);
1271 postinit_pCodeWildBlock(¤tRule->replace);
1273 //return; // debug ... don't want to go through all the rules yet
1277 pCodePeep *peepBlock;
1280 peeprules = (_DLL *)peepSnippets;
1281 //fprintf(stderr,"target rules\n");
1283 //fprintf(stderr," rule:\n");
1284 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1285 //printpBlock(stderr, peepBlock->target.pb);
1286 peeprules = peeprules->next;
1288 //fprintf(stderr," ... done\n");
1293 /*-----------------------------------------------------------------*/
1294 /* _DLL * DLL_append */
1296 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1297 /* If The list to which we want to append is non-existant then one */
1298 /* is created. Other wise, the end of the list is sought out and */
1299 /* a new DLL object is appended to it. In either case, the void */
1300 /* *data is added to the newly created DLL object. */
1301 /*-----------------------------------------------------------------*/
1303 static void * DLL_append(_DLL *list, _DLL *next)
1308 /* If there's no list, then create one: */
1310 next->next = next->prev = NULL;
1315 /* Search for the end of the list. */
1320 /* Now append the new DLL object */
1331 /*-----------------------------------------------------------------
1333 pCode peephole optimization
1336 The pCode "peep hole" optimization is not too unlike the peep hole
1337 optimization in SDCCpeeph.c. The major difference is that here we
1338 use pCode's whereas there we use ASCII strings. The advantage with
1339 pCode's is that we can ascertain flow information in the instructions
1343 <FIX ME> - elaborate...
1345 -----------------------------------------------------------------*/
1349 /*-----------------------------------------------------------------*/
1350 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1352 /* return conditions */
1353 /* 1 - The Condition was found for a pCode's input */
1354 /* 0 - No matching condition was found for the whole chain */
1355 /* -1 - The Condition was found for a pCode's output */
1357 /*-----------------------------------------------------------------*/
1358 int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip)
1362 /* If we reach a function end (presumably an end since we most
1363 probably began the search in the middle of a function), then
1364 the condition was not found. */
1365 if(pc->type == PC_FUNCTION)
1368 if(pc->type == PC_OPCODE) {
1369 if(PCI(pc)->inCond & cond) {
1371 /* If previous instruction is a skip then continue search as condiction is not certain */
1372 pCode *pcp = findPrevInstruction(pc->prev);
1373 if (pcp && !isPCI_SKIP(pcp)) {
1380 if(PCI(pc)->outCond & cond) {
1382 /* If previous instruction is a skip then continue search as condiction is not certain */
1383 pCode *pcp = findPrevInstruction(pc->prev);
1384 if (pcp && !isPCI_SKIP(pcp)) {
1399 /*-----------------------------------------------------------------
1400 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1402 * Compare two pCodeOp's and return 1 if they're the same
1403 *-----------------------------------------------------------------*/
1404 static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1408 if(!pcops || !pcopd)
1411 fprintf(stderr," Comparing operands %s",
1412 get_op( pcops,NULL,0));
1414 fprintf(stderr," to %s\n",
1415 get_op( pcopd,NULL,0));
1418 if(pcops->type != pcopd->type) {
1419 //fprintf(stderr," - fail - diff types\n");
1420 return 0; // different types
1423 if(pcops->type == PO_LITERAL) {
1425 if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit))
1434 n2 = get_op(pcopd,NULL,0);
1436 if( !n2 || strcmp(b,n2)) {
1437 //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
1438 return 0; // different names
1441 switch(pcops->type) {
1443 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1444 //fprintf(stderr, " - fail different instances\n");
1452 //fprintf(stderr," - pass\n");
1457 static int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1461 /* Check for a label associated with this wild pCode */
1462 // If the wild card has a label, make sure the source code does too.
1463 if(PCI(pcd)->label) {
1464 pCode *pcl = PCI(pcd)->label->pc;
1467 int li = -PCL(pcl)->key;
1469 if(peepBlock->target.vars[li] == NULL) {
1470 if(PCI(pcs)->label) {
1471 DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
1474 // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
1475 DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
1476 if(PCI(pcs)->label) {
1477 DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
1483 if(!PCI(pcs)->label)
1486 labindex = -PCL(pcl)->key;
1487 if(peepBlock->target.vars[labindex] == NULL) {
1488 // First time to encounter this label
1489 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1490 DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
1493 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1494 DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
1497 DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
1500 //DFPRINTF((stderr,"destination doesn't have a label\n"));
1505 //DFPRINTF((stderr,"neither src nor dest have labels\n"));
1513 /*-----------------------------------------------------------------*/
1514 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1515 /* see they're the same. */
1517 /* In this context, "source" refers to the coded generated by gen.c*/
1518 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1519 /* ination has no wild cards, then MatchLine will compare the two */
1520 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1521 /* has wildcards, then those get expanded. When a wild card is */
1522 /* encountered for the first time it autmatically is considered a */
1523 /* match and the object that matches it is referenced in the */
1524 /* variables or opcodes array (depending on the type of match). */
1528 /* *peepBlock - A pointer to the peepBlock that contains the */
1529 /* entire rule to which the destination pcode belongs*/
1530 /* *pcs - a pointer to the source pcode */
1531 /* *pcd - a pointer to the destination pcode */
1534 /* 1 - pcodes match */
1535 /* 0 - pcodes don't match */
1538 /*-----------------------------------------------------------------*/
1540 static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1542 int index; // index into wild card arrays
1544 /* one-for-one match. Here the source and destination opcodes
1545 * are not wild. However, there may be a label or a wild operand */
1548 if(PCI(pcs)->label) {
1549 DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
1553 if(pcs->type == pcd->type) {
1555 if(pcs->type == PC_OPCODE) {
1557 /* If the opcodes don't match then the line doesn't match */
1558 if(PCI(pcs)->op != PCI(pcd)->op)
1562 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1563 pcs->print(stderr,pcs);
1564 pcd->print(stderr,pcd);
1567 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1570 /* Compare the operands */
1571 if(PCI(pcd)->pcop) {
1572 // Volatile types should not be deleted or modified, these include SFR, externs and publics
1573 // They can be used as a matched, however if a match is found then the optimiser intends
1574 // to change some aspect of a block of code, which is most likely a critcal one. As this
1575 // method of optimisation does not allow a means to distiguishing what may change, it is
1576 // best to just negate any match.
1577 if (PCI(pcs)->pcop) {
1579 pCodeOp *pcop = PCI(pcs)->pcop;
1580 switch(pcop->type) {
1588 case PO_SFR_REGISTER:
1589 return 0; // SFR - do not modify
1591 case PO_GPR_REGISTER:
1594 case PO_GPR_POINTER:
1596 if (r->isPublic||r->isExtern||r->isFixed) // Changes to these types of registers should not be changed as they may be used else where
1602 if (PCI(pcd)->pcop->type == PO_WILD) {
1604 index = PCOW(PCI(pcd)->pcop)->id;
1605 //DFPRINTF((stderr,"destination is wild\n"));
1606 #ifdef DEBUG_PCODEPEEP
1607 if (index > peepBlock->nops) {
1608 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1612 n = PCI(pcs)->pcop->name;
1613 if(peepBlock->target.vars[index]) {
1614 if ((!n)||(strcmp(peepBlock->target.vars[index],n) != 0))
1615 return 0; // variable is different
1617 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1618 peepBlock->target.vars[index] = n;
1621 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1622 if(!peepBlock->target.wildpCodeOps[index]) {
1623 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1625 //fprintf(stderr, "first time for wild opcode #%d\n",index);
1630 pcs->print(stderr,pcs);
1631 pcd->print(stderr,pcd);
1632 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1633 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1637 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1643 switch(PCI(pcs)->pcop->type) {
1647 //n = PCOR(PCI(pcs)->pcop)->r->name;
1648 n = PCI(pcs)->pcop->name;
1652 n = PCI(pcs)->pcop->name;
1655 if(peepBlock->target.vars[index])
1656 return (strcmp(peepBlock->target.vars[index],n) == 0);
1658 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1659 peepBlock->target.vars[index] = n;
1664 } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
1666 pcs->print(stderr,pcs);
1667 pcd->print(stderr,pcd);
1669 fprintf(stderr, "comparing literal operands of these instructions, result %d\n",
1670 pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop));
1672 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1675 /* FIXME - need an else to check the case when the destination
1676 * isn't a wild card */
1678 fprintf(stderr, "Destination is not wild: operand compare =%d\n",
1679 pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop));
1681 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1685 /* The pcd has no operand. Lines match if pcs has no operand either*/
1686 return (PCI(pcs)->pcop == NULL);
1690 /* Compare a wild instruction to a regular one. */
1692 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1694 index = PCW(pcd)->id;
1696 DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1697 pcs->print(stderr,pcs);
1698 pcd->print(stderr,pcd);
1700 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1702 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
1703 DFPRINTF((stderr," Failing because labels don't match\n"));
1707 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1708 // doesn't match because the wild pcode must be a bit skip
1709 DFPRINTF((stderr," Failing match because bit skip is req\n"));
1710 //pcd->print(stderr,pcd);
1711 //pcs->print(stderr,pcs);
1715 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1716 // doesn't match because the wild pcode must *not* be a bit skip
1717 DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
1718 //pcd->print(stderr,pcd);
1719 //pcs->print(stderr,pcs);
1723 if(PCW(pcd)->operand) {
1724 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1725 if(peepBlock->target.vars[index]) {
1726 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1730 DFPRINTF((stderr," (matched)\n"));
1732 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1733 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n",
1734 peepBlock->target.vars[index],
1735 PCI(pcs)->pcop->name));
1740 DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
1741 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1746 pcs = findNextInstruction(pcs->next);
1748 //DFPRINTF((stderr," (next to match)\n"));
1749 //pcs->print(stderr,pcs);
1750 } else if(pcd->next) {
1751 /* oops, we ran out of code, but there's more to the rule */
1755 return 1; /* wild card matches */
1761 /*-----------------------------------------------------------------*/
1762 /*-----------------------------------------------------------------*/
1763 static void pCodePeepClrVars(pCodePeep *pcp)
1770 DFPRINTF((stderr," Clearing peep rule vars\n"));
1771 DFPRINTF((stderr," %d %d %d %d %d %d\n",
1772 pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
1773 pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
1775 for(i=0;i<pcp->target.nvars; i++)
1776 pcp->target.vars[i] = NULL;
1777 for(i=0;i<pcp->target.nops; i++)
1778 pcp->target.wildpCodeOps[i] = NULL;
1779 for(i=0;i<pcp->target.nwildpCodes; i++)
1780 pcp->target.wildpCodes[i] = NULL;
1782 for(i=0;i<pcp->replace.nvars; i++)
1783 pcp->replace.vars[i] = NULL;
1784 for(i=0;i<pcp->replace.nops; i++)
1785 pcp->replace.wildpCodeOps[i] = NULL;
1786 for(i=0;i<pcp->replace.nwildpCodes; i++)
1787 pcp->replace.wildpCodes[i] = NULL;
1793 /*-----------------------------------------------------------------*/
1794 /*-----------------------------------------------------------------*/
1795 int pCodePeepMatchRule(pCode *pc)
1797 pCodePeep *peepBlock;
1799 pCodeCSource *pc_cline=NULL;
1803 peeprules = (_DLL *)peepSnippets;
1806 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1808 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
1809 fprintf(stderr, "skipping rule because target pb is NULL\n");
1813 pCodePeepClrVars(peepBlock);
1816 if(IS_PCCOMMENT(pcin))
1817 pc = pcin = findNextInstruction(pcin->next);
1819 pcin = pc = findNextInstruction(pc);
1821 pct = peepBlock->target.pb->pcHead;
1824 pCode *pcr = peepBlock->replace.pb->pcHead;
1825 if(pcr) pct->print(stderr,pcr);
1829 while(pct && pcin) {
1831 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1834 pcin = findNextInstruction(pcin->next);
1837 //DFPRINTF((stderr," matched\n"));
1840 DFPRINTF((stderr," partial match... no more code\n"));
1844 DFPRINTF((stderr," end of rule\n"));
1848 if(matched && pcin) {
1850 /* So far we matched the rule up to the point of the conditions .
1851 * In other words, all of the opcodes match. Now we need to see
1852 * if the post conditions are satisfied.
1853 * First we check the 'postFalseCond'. This means that we check
1854 * to see if any of the subsequent pCode's in the pCode chain
1855 * following the point just past where we have matched depend on
1856 * the `postFalseCond' as input then we abort the match
1858 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
1859 //pcin->print(stderr,pcin);
1861 if (pcin && peepBlock->postFalseCond &&
1862 (pCodeSearchCondition(pcin,peepBlock->postFalseCond,0) > 0) )
1865 //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
1868 //if(!matched) fprintf(stderr,"failed on conditions\n");
1877 /* We matched a rule! Now we have to go through and remove the
1878 inefficient code with the optimized version */
1880 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
1881 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
1882 DFPRINTF((stderr,"first thing matched\n"));
1883 pc->print(stderr,pc);
1885 DFPRINTF((stderr,"last thing matched\n"));
1886 pcin->print(stderr,pcin);
1891 /* Unlink the original code */
1894 pcprev->next = pcin;
1896 pcin->prev = pc->prev;
1902 /* Converted the deleted pCodes into comments */
1905 pCodeCSource *pc_cline2=NULL;
1910 while(pc && pc!=pcin) {
1912 if(pc->type == PC_OPCODE && PCI(pc)->cline) {
1914 pc_cline2->pc.next = PCODE(PCI(pc)->cline);
1915 pc_cline2 = PCCS(pc_cline2->pc.next);
1917 pc_cline = pc_cline2 = PCI(pc)->cline;
1918 pc_cline->pc.seq = pc->seq;
1922 pCode2str(&buf[2], 254, pc);
1923 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
1924 pcprev = pcprev->next;
1929 pc_cline2->pc.next = NULL;
1934 pCodeDeleteChain(pc,pcin);
1936 /* Generate the replacement code */
1938 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
1942 /* If the replace pcode is an instruction with an operand, */
1943 /* then duplicate the operand (and expand wild cards in the process). */
1944 if(pcr->type == PC_OPCODE) {
1945 if(PCI(pcr)->pcop) {
1946 /* The replacing instruction has an operand.
1948 if(PCI(pcr)->pcop->type == PO_WILD) {
1949 int index = PCOW(PCI(pcr)->pcop)->id;
1950 //DFPRINTF((stderr,"copying wildopcode\n"));
1951 if(peepBlock->target.wildpCodeOps[index])
1952 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
1954 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
1956 pcop = pCodeOpCopy(PCI(pcr)->pcop);
1958 //DFPRINTF((stderr,"inserting pCode\n"));
1959 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
1960 } else if (pcr->type == PC_WILD) {
1961 if(PCW(pcr)->invertBitSkipInst)
1962 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
1963 pCodeInsertAfter(pc,
1964 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
1965 PCW(pcr)->invertBitSkipInst));
1966 } else if (pcr->type == PC_COMMENT) {
1967 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
1972 DFPRINTF((stderr," NEW Code:"));
1973 if(pc) pc->print(stderr,pc);
1978 /* We have just replaced the inefficient code with the rule.
1979 * Now, we need to re-add the C-source symbols if there are any */
1981 while(pc && pc_cline ) {
1983 pc = findNextInstruction(pc->next);
1985 PCI(pc)->cline = pc_cline;
1986 pc_cline = PCCS(pc_cline->pc.next);
1990 /* Copy C code comments to new code. */
1993 for (; pc && pcout!=pcin; pcout=pcout->next) {
1994 if (pcout->type==PC_OPCODE && PCI(pcout)->cline) {
1995 while (pc->type!=PC_OPCODE || PCI(pc)->cline) {
2001 PCI(pc)->cline = PCI(pcout)->cline;
2009 peeprules = peeprules->next;
2011 DFPRINTF((stderr," no rule matched\n"));