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
32 pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype);
33 pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
34 pCode * findNextInstruction(pCode *pc);
35 char *Safe_strdup(char *str);
38 /****************************************************************/
40 * rootRules - defined in SDCCpeep.c
41 * This is a pointer to the (parsed) peephole rules that are
42 * defined in peep.def.
45 //extern peepRule *rootRules;
50 /****************************************************************/
51 /****************************************************************/
59 typedef struct pCodePeepSnippets
66 static pCodePeepSnippets *peepSnippets=NULL;
68 typedef struct pCodeToken
70 int tt; // token type;
79 pCodeToken tokArr[50];
95 typedef struct parsedPattern {
96 struct pcPattern *pcp;
100 #define MAX_PARSEDPATARR 50
101 parsedPattern parsedPatArr[MAX_PARSEDPATARR];
102 unsigned int parsedPatIdx=0;
113 static char pcpat_label[] = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
114 static char pcpat_string[] = {PCT_STRING, 0};
115 static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
116 static char pcpat_wildVar[] = {PCT_PERCENT, PCT_NUMBER, 0};
117 static char pcpat_comma[] = {PCT_COMMA, 0};
120 typedef struct pcPattern {
121 int pt; // Pattern type
122 char *tokens; // list of tokens that describe the pattern
123 void * (*f) (void *);
126 pcPattern pcpArr[] = {
127 {PCP_LABEL, pcpat_label, NULL},
128 {PCP_WILDSTR, pcpat_wildString, NULL},
129 {PCP_STR, pcpat_string, NULL},
130 {PCP_WILDVAR, pcpat_wildVar, NULL},
131 {PCP_COMMA, pcpat_comma, NULL}
134 #define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
136 // Assembly Line Token
144 static char alt_label[] = { PCP_LABEL, 0};
145 static char alt_mnem0[] = { PCP_STR, 0};
146 static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
147 static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
149 static void * cvt_altpat_label(void *pp);
151 pcPattern altArr[] = {
152 {ALT_LABEL, alt_label, cvt_altpat_label},
153 {ALT_MNEM2, alt_mnem2, NULL},
156 /*-----------------------------------------------------------------*/
157 /*-----------------------------------------------------------------*/
158 static void * cvt_altpat_label(void *pp)
160 fprintf(stderr,"altpat_label\n");
165 /*-----------------------------------------------------------------*/
166 /*-----------------------------------------------------------------*/
167 static pCode * cvt_pcpat_wildMnem(parsedPattern *pp)
169 fprintf(stderr,"pcpat_wildMnem\n");
172 /*-----------------------------------------------------------------*/
173 /*-----------------------------------------------------------------*/
174 static pCode * cvt_pcpat_Mnem(parsedPattern *pp)
176 fprintf(stderr,"pcpat_Mnem\n");
179 /*-----------------------------------------------------------------*/
180 /*-----------------------------------------------------------------*/
181 static pCode * cvt_pcpat_wildVar(parsedPattern *pp)
183 fprintf(stderr,"pcpat_wildVar\n");
186 /*-----------------------------------------------------------------*/
187 /*-----------------------------------------------------------------*/
188 static pCode * cvt_pcpat_var(parsedPattern *pp)
190 fprintf(stderr,"pcpat_var\n");
199 /*-----------------------------------------------------------------*/
200 /*-----------------------------------------------------------------*/
203 static void parseLineNode(char *ln)
214 tokArr[tokIdx++].tt = PCT_SPACE;
215 while (isspace (*ln))
222 tokArr[tokIdx].tt = PCT_NUMBER;
223 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 10);
231 tokArr[tokIdx++].tt = PCT_PERCENT;
234 tokArr[tokIdx++].tt = PCT_COLON;
237 tokArr[tokIdx].tok.s = Safe_strdup(ln);
238 tokArr[tokIdx++].tt = PCT_COMMENT;
241 tokArr[tokIdx++].tt = PCT_COMMA;
250 while( (isalpha(*ln) || isdigit(*ln)) && i<49)
256 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
257 //fprintf(stderr," string %s",tokArr[tokIdx].tok.s);
259 tokArr[tokIdx++].tt = PCT_STRING;
270 void dump1Token(pCodeTokens tt)
275 fprintf(stderr, " space ");
278 fprintf(stderr, " pct ");
282 fprintf(stderr, " col ");
286 fprintf(stderr, " com ");
291 fprintf(stderr, " str ");
292 //fprintf(stderr,"%s",tokArr[i].tok.s);
295 fprintf(stderr, " num ");
296 //fprintf(stderr,"%d",tokArr[i].tok.n);
303 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
307 if(!pct || !pat || !*pat)
310 //fprintf(stderr,"comparing against:\n");
312 while(i < max_tokens) {
315 //fprintf(stderr,"matched\n");
319 //dump1Token(*pat); fprintf(stderr,"\n");
333 int advTokIdx(int *v, int amt)
336 if(*v + amt > tokIdx)
344 void dumpTokens(void)
351 for(i=0; i<=tokIdx; i++)
352 dump1Token(tokArr[i].tt);
364 pCodeOp *pcl = NULL; // Storage for a label
365 pCodeOp *pco1 = NULL; // 1st operand
366 pCodeOp *pco2 = NULL; // 2nd operand
367 pCode *pc = NULL; // Mnemonic
378 ParseStates state = PS_START;
384 //fprintf(stderr,"ltokIdx = %d\n",ltokIdx);
386 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )//|| (tokArr[ltokIdx].tt == PCT_COMMA))
387 && (advTokIdx(<okIdx, 1)) ) // eat space
391 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
393 //fprintf(stderr,"found token pattern match\n");
394 switch(pcpArr[lpcpIdx].pt) {
396 if(state == PS_START){
397 fprintf(stderr," label\n");
398 state = PS_HAVE_LABEL;
400 fprintf(stderr," bad state (%d) for label\n",state);
407 fprintf(stderr," mnem\n");
408 state = PS_HAVE_MNEM;
411 fprintf(stderr," 1st operand\n");
412 pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
413 state = PS_HAVE_1OPERAND;
415 case PS_HAVE_1OPERAND:
416 fprintf(stderr," error expecting comma\n");
419 fprintf(stderr," 2 operands\n");
428 fprintf(stderr," wild mnem\n");
429 state = PS_HAVE_MNEM;
432 fprintf(stderr," 1st operand is wild\n");
433 state = PS_HAVE_1OPERAND;
435 case PS_HAVE_1OPERAND:
436 fprintf(stderr," error expecting comma\n");
439 fprintf(stderr," 2nd operand is wild\n");
447 if(state == PS_HAVE_1OPERAND){
448 fprintf(stderr," got a comma\n");
449 state = PS_HAVE_COMMA;
451 fprintf(stderr," unexpected comma\n");
455 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
456 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
459 //dump1Token(tokArr[ltokIdx].tt);
461 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
462 fprintf(stderr," reached end \n");
469 } while ((++lpcpIdx < PCPATTERNS) && !matching);
473 fprintf(stderr,"\nConverting parsed line to pCode:\n\n");
477 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
478 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
481 while(j<lparsedPatIdx);
483 fprintf(stderr,"\n");
491 if(pcComparePattern(&tokArr[0], pcpat_label, tokIdx +1)) {
492 fprintf(stderr,"has a wild label\n");
493 if(advTokIdx(&i, sizeof(pcpat_label) -1))
497 if( (tokArr[i].tt == PCT_SPACE) && (advTokIdx(&i, 1)) ) // eat space
500 if(pcComparePattern(&tokArr[i], pcpat_wildMnem, tokIdx +1 -i)) {
501 fprintf(stderr,"has a wild mnemonic\n");
502 if(advTokIdx(&i, sizeof(pcpat_wildMnem) -1))
504 } else if(pcComparePattern(&tokArr[i], pcpat_Mnem, tokIdx +1 -i)) {
505 fprintf(stderr,"has a mnemonic\n");
506 if(advTokIdx(&i, sizeof(pcpat_Mnem) -1))
509 return; // doesn't matter what follows
511 if( (tokArr[i].tt == PCT_SPACE) && (advTokIdx(&i, 1)) ) // eat space
514 fprintf(stderr,"checking variable; next token ");
515 dump1Token(tokArr[i].tt);
516 fprintf(stderr,"\n");
518 if(pcComparePattern(&tokArr[i], pcpat_wildVar, tokIdx +1 -i)) {
519 fprintf(stderr,"has a wild var\n");
520 if(advTokIdx(&i, sizeof(pcpat_wildVar) -1))
522 } else if(pcComparePattern(&tokArr[i], pcpat_Var, tokIdx +1 -i)) {
523 fprintf(stderr,"has a var\n");
524 if(advTokIdx(&i, sizeof(pcpat_Var) -1))
529 if( ((tokArr[i].tt == PCT_SPACE) || (tokArr[i].tt == PCT_COMMA))
530 && (advTokIdx(&i, 1)) ) // eat space
533 if(pcComparePattern(&tokArr[i], pcpat_wildVar, tokIdx +10 -i)) {
534 fprintf(stderr,"has a wild var\n");
535 if(advTokIdx(&i, sizeof(pcpat_wildVar) -1))
537 } else if(pcComparePattern(&tokArr[i], pcpat_Var, tokIdx +10 -i)) {
538 fprintf(stderr,"has a var\n");
539 if(advTokIdx(&i, sizeof(pcpat_Var) -1))
541 } else if(tokArr[i].tt == PCT_NUMBER) {
542 fprintf(stderr,"has a number\n");
543 if (advTokIdx(&i, 1))
551 void peepRules2pCode(peepRule *rules)
556 for (pr = rules; pr; pr = pr->next) {
557 fprintf(stderr,"\nRule:\n\n");
558 for(ln = pr->match; ln; ln = ln->next) {
559 fprintf(stderr,"%s\n",ln->line);
560 //parseLineNode(ln->line);
561 parseLineNode(ln->line);
566 fprintf(stderr,"\nReplaced by:\n");
567 for(ln = pr->replace; ln; ln = ln->next)
568 fprintf(stderr,"%s\n",ln->line);
571 fprintf(stderr,"\nCondition: %s\n",pr->cond);
577 void printpCodeString(FILE *of, pCode *pc, int max)
581 while(pc && (i++<max)) {
587 /*-----------------------------------------------------------------*/
588 /* _DLL * DLL_append */
590 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
591 /* If The list to which we want to append is non-existant then one */
592 /* is created. Other wise, the end of the list is sought out and */
593 /* a new DLL object is appended to it. In either case, the void */
594 /* *data is added to the newly created DLL object. */
595 /*-----------------------------------------------------------------*/
597 static void * DLL_append(_DLL *list, _DLL *next)
602 /* If there's no list, then create one: */
604 next->next = next->prev = NULL;
609 /* Search for the end of the list. */
614 /* Now append the new DLL object */
625 /*-----------------------------------------------------------------
627 pCode peephole optimization
630 The pCode "peep hole" optimization is not too unlike the peep hole
631 optimization in SDCCpeeph.c. The major difference is that here we
632 use pCode's whereas there we use ASCII strings. The advantage with
633 pCode's is that we can ascertain flow information in the instructions
637 <FIX ME> - elaborate...
639 -----------------------------------------------------------------*/
642 /*-----------------------------------------------------------------*/
644 /*-----------------------------------------------------------------*/
645 int pCodePeepCompare(pCode *pc, pCodePeep *pcp)
650 for( pcto=pcp->target; pcto; pcto=pcto->next) {
652 pcfrom = findNextInstruction(pcfrom);
655 (PCI(pcfrom)->op == PCI(pcto)->op ||
656 PCI(pcto)->op == POC_WILD))
663 /*-----------------------------------------------------------------*/
665 /*-----------------------------------------------------------------*/
666 void pCodePeepSearch(pCodePeep *snippet)
674 /* compare the chain to the pCode that we've
675 got so far. If a match is found, then replace
678 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
679 for(pc = pb->pcHead; pc; pc = pc->next) {
680 pCodePeepCompare(pc,snippet);
688 pBlock *pBlockAppend(pBlock *pb1, pBlock *pb2)
705 void pCodePeepInit(void)
710 pCodePeepSnippets *pcps;
712 /* Declare a peep code snippet */
713 /* <FIXME> do I really need a separate struct just to DLL the snippets? */
714 /* e.g. I could put the DLL into the pCodePeep structure */
715 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
716 pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
717 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
720 pb = newpCodeChain(NULL, 'W', newpCode(POC_MOVWF, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) );
721 addpCode2pBlock( pb, newpCode(POC_MOVFW, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) );
725 pcp->replace = newpCodeChain(NULL, 'W',newpCode(POC_MOVWF, newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER))) );
727 /* Allocate space to store pointers to the wildcard variables */
729 pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *));
730 pcp->nwildpCodes = 0;
731 pcp->wildpCodes = NULL;
733 pcp->postFalseCond = PCC_Z;
734 pcp->postTrueCond = PCC_NONE;
736 fprintf(stderr,"Peep rule\nTarget:\n");
737 printpCodeString(stderr,pcp->target->pcHead, 10);
738 fprintf(stderr,"Replaced with:\n");
739 printpCodeString(stderr,pcp->replace->pcHead, 10);
741 /* Now for another peep example */
742 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
743 pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
744 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
760 The %3 and %4 are wild opcodes. Since the opcodes
761 are stored in a different array than the wild operands,
762 they can have the same indices and not conflict. So
763 below, the %3 is really a %0, %4 is a %1.
770 // Create a new wild operand subtyped as a bit
771 pcwb = newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1));
774 pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSC,pcwb));
776 pcl = newpCodeOpLabel(-1);
777 pcw = newpCodeOpWild(1, pcp, pcl);
778 addpCode2pBlock( pb, newpCode(POC_GOTO, pcw));
779 addpCode2pBlock( pb, newpCodeWild(0,NULL,NULL));
780 addpCode2pBlock( pb, newpCodeWild(1,NULL,pcw));
785 pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSS, pcwb));
786 addpCode2pBlock( pb, newpCodeWild(0,NULL,NULL));
787 addpCode2pBlock( pb, newpCodeWild(1,NULL,pcw));
791 /* Allocate space to store pointers to the wildcard variables */
793 pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *));
794 pcp->nwildpCodes = 2;
795 pcp->wildpCodes = Safe_calloc(pcp->nwildpCodes, sizeof(pCode *));
797 pcp->postFalseCond = PCC_NONE;
798 pcp->postTrueCond = PCC_NONE;
812 /* Now for another peep example */
813 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
814 pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
815 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
820 pcw = newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER));
822 pb = newpCodeChain(NULL, 'W', newpCode(POC_MOVWF, pcw));
823 addpCode2pBlock( pb, newpCode(POC_MOVWF, pcw));
827 pb = newpCodeChain(NULL, 'W',newpCode(POC_MOVWF, pcw));
831 /* Allocate space to store pointers to the wildcard variables */
833 pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *));
834 pcp->nwildpCodes = 0;
835 pcp->wildpCodes = NULL;
837 pcp->postFalseCond = PCC_NONE;
838 pcp->postTrueCond = PCC_NONE;
846 /*-----------------------------------------------------------------*/
847 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
849 /* return conditions */
850 /* 1 - The Condition was found for a pCode's input */
851 /* 0 - No matching condition was found for the whole chain */
852 /* -1 - The Condition was found for a pCode's output */
854 /*-----------------------------------------------------------------*/
855 int pCodeSearchCondition(pCode *pc, unsigned int cond)
860 /* If we reach a function end (presumably an end since we most
861 probably began the search in the middle of a function), then
862 the condition was not found. */
863 if(pc->type == PC_FUNCTION)
866 if(pc->type == PC_OPCODE) {
867 if(PCI(pc)->inCond & cond)
869 if(PCI(pc)->outCond & cond)
878 /*-----------------------------------------------------------------*/
879 /* pCodePeepMatchLine - Compare source and destination pCodes to */
880 /* see they're the same. */
881 /*-----------------------------------------------------------------*/
882 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
884 int index; // index into wild card arrays
886 if(pcs->type == pcd->type) {
888 if(pcs->type == PC_OPCODE) {
890 /* If the opcodes don't match then the line doesn't match */
891 if(PCI(pcs)->op != PCI(pcd)->op)
894 fprintf(stderr,"%s comparing\n",__FUNCTION__);
895 pcs->print(stderr,pcs);
896 pcd->print(stderr,pcd);
898 /* Compare the operands */
900 if (PCI(pcd)->pcop->type == PO_WILD) {
901 index = PCOW(PCI(pcd)->pcop)->id;
903 fprintf(stderr,"destination is wild\n");
904 #ifdef DEBUG_PCODEPEEP
905 if (index > peepBlock->nvars) {
906 fprintf(stderr,"%s - variables exceeded\n",__FUNCTION__);
910 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
914 if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
915 n = PCOR(PCI(pcs)->pcop)->r->name;
917 n = PCI(pcs)->pcop->name;
919 if(peepBlock->vars[index])
920 return (strcmp(peepBlock->vars[index],n) == 0);
922 peepBlock->vars[index] = n; //PCI(pcs)->pcop->name;
928 /* The pcd has no operand. Lines match if pcs has no operand either*/
929 return (PCI(pcs)->pcop == NULL);
934 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
938 index = PCW(pcd)->id;
940 fprintf(stderr,"%s comparing wild cards\n",__FUNCTION__);
941 pcs->print(stderr,pcs);
942 pcd->print(stderr,pcd);
944 peepBlock->wildpCodes[PCW(pcd)->id] = pcs;
946 /* Check for a label associated with this wild pCode */
947 // If the wild card has a label, make sure the source code does too.
948 if(PCW(pcd)->label) {
952 labindex = PCOW(PCW(pcd)->label)->id;
953 if(peepBlock->vars[labindex] == NULL) {
954 // First time to encounter this label
955 peepBlock->vars[labindex] = PCL(pcs->label->pc)->label;
956 fprintf(stderr,"first time for a label\n");
958 if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) {
959 fprintf(stderr,"labels don't match\n");
962 fprintf(stderr,"matched a label\n");
967 if(PCW(pcd)->operand) {
968 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
969 if(peepBlock->vars[index]) {
970 int i = (strcmp(peepBlock->vars[index],PCI(pcs)->pcop->name) == 0);
972 fprintf(stderr," (matched)\n");
974 fprintf(stderr," (no match: wild card operand mismatch\n");
975 fprintf(stderr," peepblock= %s, pcodeop= %s\n",
976 peepBlock->vars[index],
977 PCI(pcs)->pcop->name);
981 peepBlock->vars[index] = PCI(pcs)->pcop->name;
986 pcs = findNextInstruction(pcs->next);
988 fprintf(stderr," (next to match)\n");
989 pcs->print(stderr,pcs);
992 return 1; /* wild card matches */
998 /*-----------------------------------------------------------------*/
999 /*-----------------------------------------------------------------*/
1000 void pCodePeepClrVars(pCodePeep *pcp)
1005 for(i=0;i<pcp->nvars; i++)
1006 pcp->vars[i] = NULL;
1010 /*-----------------------------------------------------------------*/
1011 /*-----------------------------------------------------------------*/
1012 void pCodeInsertAfter(pCode *pc1, pCode *pc2)
1018 pc2->next = pc1->next;
1020 pc1->next->prev = pc2;
1027 /*-----------------------------------------------------------------*/
1028 /* pCodeOpCopy - copy a pcode operator */
1029 /*-----------------------------------------------------------------*/
1030 static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
1032 pCodeOp *pcopnew=NULL;
1037 switch(pcop->type) {
1040 pcopnew = Safe_calloc(1,sizeof(pCodeOpBit) );
1041 PCOB(pcopnew)->bit = PCOB(pcop)->bit;
1042 PCOB(pcopnew)->inBitSpace = PCOB(pcop)->inBitSpace;
1047 /* Here we expand the wild card into the appropriate type: */
1048 /* By recursively calling pCodeOpCopy */
1049 if(PCOW(pcop)->matched)
1050 pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
1053 pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
1054 pcopnew->name = Safe_strdup(PCOW(pcop)->pcp->vars[PCOW(pcop)->id]);
1055 fprintf(stderr,"copied a wild op named %s\n",pcopnew->name);
1062 pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
1063 PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
1068 pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
1069 PCOL(pcopnew)->lit = PCOL(pcop)->lit;
1072 case PO_GPR_REGISTER:
1074 case PO_SFR_REGISTER:
1083 pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
1087 pcopnew->type = pcop->type;
1088 pcopnew->name = Safe_strdup(pcop->name);
1094 /*-----------------------------------------------------------------*/
1095 /* pCodeCopy - copy a pcode */
1096 /*-----------------------------------------------------------------*/
1097 static pCode *pCodeCopy(pCode *pc)
1102 pcnew = newpCode(pc->type,pc->pcop);
1105 /*-----------------------------------------------------------------*/
1106 /*-----------------------------------------------------------------*/
1107 void pCodeDeleteChain(pCode *f,pCode *t)
1112 fprintf(stderr,"delete pCode:\n");
1120 /*-----------------------------------------------------------------*/
1121 /*-----------------------------------------------------------------*/
1122 int pCodePeepMatchRule(pCode *pc)
1124 pCodePeep *peepBlock;
1129 peeprules = (_DLL *)peepSnippets;
1132 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1133 pCodePeepClrVars(peepBlock);
1136 pct = peepBlock->target->pcHead;
1138 while(pct && pcin) {
1140 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1143 pcin = findNextInstruction(pcin->next);
1146 fprintf(stderr," matched\n");
1148 fprintf(stderr," end of code\n");
1150 fprintf(stderr," end of rule\n");
1153 if(matched && pcin) {
1155 /* So far we matched the rule up to the point of the conditions .
1156 * In other words, all of the opcodes match. Now we need to see
1157 * if the post conditions are satisfied.
1158 * First we check the 'postFalseCond'. This means that we check
1159 * to see if any of the subsequent pCode's in the pCode chain
1160 * following the point just past where we have matched depend on
1161 * the `postFalseCond' as input then we abort the match
1163 fprintf(stderr," matched rule so far, now checking conditions\n");
1164 if (peepBlock->postFalseCond &&
1165 (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
1169 if(matched && pcin) {
1175 /* We matched a rule! Now we have to go through and remove the
1176 inefficient code with the optimized version */
1178 fprintf(stderr, "Found a pcode peep match:\nRule:\n");
1179 printpCodeString(stderr,peepBlock->target->pcHead,10);
1180 fprintf(stderr,"first thing matched\n");
1181 pc->print(stderr,pc);
1182 fprintf(stderr,"last thing matched\n");
1183 pcin->print(stderr,pcin);
1185 /* Unlink the original code */
1187 pcprev->next = pcin;
1188 pcin->prev = pc->prev;
1189 pCodeDeleteChain(pc,pcin);
1191 /* Generate the replacement code */
1193 pcr = peepBlock->replace->pcHead; // This is the replacement code
1196 /* If the replace pcode is an instruction with an operand, */
1197 /* then duplicate the operand (and expand wild cards in the process). */
1198 if(pcr->type == PC_OPCODE) {
1200 pcop = pCodeOpCopy(PCI(pcr)->pcop);
1201 fprintf(stderr,"inserting pCode\n");
1202 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
1203 } else if (pcr->type == PC_WILD) {
1204 pCodeInsertAfter(pc,peepBlock->wildpCodes[PCW(pcr)->id]);
1209 pc->print(stderr,pc);
1216 peeprules = peeprules->next;
1232 /*******************/
1233 pCode *parseLineNode(char *ln)
1235 char buffer[50], *s;
1236 int state=0; //0 label, 1 mnemonic, 2 operand, 3 operand, 4 comment
1239 // pCodeLabel *pcl = NULL;
1249 /* skip white space */
1250 while (isspace (*ln))
1255 case 0: // look for a label
1256 case 1: // look for mnemonic
1267 var = strtol(ln, &ln, 10);
1269 // valid wild card label
1270 fprintf(stderr, " wildcard label: %d\n",var);
1273 fprintf(stderr, " wild opcode: %d\n",var), state++;
1277 // Extract the label/mnemonic from the line
1280 while(*ln && !(isspace(*ln) || *ln == ':'))
1285 fprintf(stderr," regular label: %s\n",buffer), ln++;
1287 fprintf(stderr," regular mnem: %s\n",buffer), state++;