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
28 #include "pcodeflow.h"
31 pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
32 pCodeOp *popRegFromString(char *str, int size, int offset);
34 pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype);
35 pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
36 pCode * findNextInstruction(pCode *pc);
37 int getpCode(char *mnem,int dest);
38 int getpCodePeepCommand(char *cmd);
39 void pBlockMergeLabels(pBlock *pb);
40 char *pCode2str(char *str, int size, pCode *pc);
41 char *get_op( pCodeOp *pcop,char *buf,int buf_size);
43 extern pCodeInstruction *pic14Mnemonics[];
44 extern pCode * findPrevInstruction(pCode *pci);
47 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
49 /****************************************************************/
51 * rootRules - defined in SDCCpeep.c
52 * This is a pointer to the (parsed) peephole rules that are
53 * defined in peep.def.
56 //extern peepRule *rootRules;
61 /****************************************************************/
62 /****************************************************************/
70 typedef struct pCodePeepSnippets
77 /****************************************************************/
81 /****************************************************************/
83 static pCodePeepSnippets *peepSnippets=NULL;
85 /****************************************************************/
89 /****************************************************************/
91 //static pCodePeep *curPeep=NULL;
93 /****************************************************************/
97 /****************************************************************/
99 //static pBlock *curBlock=NULL;
102 /****************************************************************/
104 /* max wild cards in a peep rule */
106 /****************************************************************/
108 //static int sMaxWildVar = 0;
109 //static int sMaxWildMnem = 0;
112 typedef struct pCodeToken
114 int tt; // token type;
123 pCodeToken tokArr[50];
142 typedef struct parsedPattern {
143 struct pcPattern *pcp;
147 #define MAX_PARSEDPATARR 50
148 parsedPattern parsedPatArr[MAX_PARSEDPATARR];
149 unsigned int parsedPatIdx=0;
162 static char pcpat_label[] = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
163 static char pcpat_number[] = {PCT_NUMBER, 0};
164 static char pcpat_string[] = {PCT_STRING, 0};
165 static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
166 static char pcpat_wildVar[] = {PCT_PERCENT, PCT_NUMBER, 0};
167 static char pcpat_comma[] = {PCT_COMMA, 0};
168 static char pcpat_comment[] = {PCT_COMMENT, 0};
171 typedef struct pcPattern {
172 char pt; // Pattern type
173 char *tokens; // list of tokens that describe the pattern
174 void * (*f) (void *,pCodeWildBlock *);
177 pcPattern pcpArr[] = {
178 {PCP_LABEL, pcpat_label, NULL},
179 {PCP_WILDSTR, pcpat_wildString, NULL},
180 {PCP_STR, pcpat_string, NULL},
181 {PCP_WILDVAR, pcpat_wildVar, NULL},
182 {PCP_COMMA, pcpat_comma, NULL},
183 {PCP_COMMENT, pcpat_comment, NULL},
184 {PCP_NUMBER, pcpat_number, NULL}
187 #define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
189 // Assembly Line Token
203 static char alt_comment[] = { PCP_COMMENT, 0};
204 static char alt_label[] = { PCP_LABEL, 0};
205 static char alt_mnem0[] = { PCP_STR, 0};
206 static char alt_mnem0a[] = { PCP_WILDVAR, 0};
207 static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
208 static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0};
209 static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
210 static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
211 static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
212 static char alt_mnem3[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
214 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
215 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
216 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
217 static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
218 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
219 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
220 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
221 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
222 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
223 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
225 pcPattern altArr[] = {
226 {ALT_LABEL, alt_label, cvt_altpat_label},
227 {ALT_COMMENT, alt_comment,cvt_altpat_comment},
228 {ALT_MNEM3, alt_mnem3, cvt_altpat_mnem3},
229 {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
230 {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
231 {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
232 {ALT_MNEM1A, alt_mnem1a, cvt_altpat_mnem1a},
233 {ALT_MNEM1, alt_mnem1, cvt_altpat_mnem1},
234 {ALT_MNEM0A, alt_mnem0a, cvt_altpat_mnem0a},
235 {ALT_MNEM0, alt_mnem0, cvt_altpat_mnem0},
239 #define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
241 // forward declarations
242 static void * DLL_append(_DLL *list, _DLL *next);
244 /*-----------------------------------------------------------------*/
245 /* cvt_extract_destination - helper function extracts the register */
246 /* destination from a parsedPattern. */
248 /*-----------------------------------------------------------------*/
249 static int cvt_extract_destination(parsedPattern *pp)
252 if(pp->pct[0].tt == PCT_STRING) {
254 // just check first letter for now
256 if(toupper((unsigned char)*pp->pct[0].tok.s) == 'F')
259 } else if (pp->pct[0].tt == PCT_NUMBER) {
269 /*-----------------------------------------------------------------*/
270 /* pCodeOp *cvt_extract_status(char *reg, char *bit) */
271 /* if *reg is the "status" register and *bit is one of the */
272 /* status bits, then this function will create a new pCode op */
273 /* containing the status register. */
274 /*-----------------------------------------------------------------*/
276 static pCodeOp *cvt_extract_status(char *reg, char *bit)
280 if(STRCASECMP(reg, pc_status.pcop.name))
287 if(toupper((unsigned char)*bit) == 'C')
288 return PCOP(popCopyGPR2Bit(&pc_status,PIC_C_BIT));
289 if(toupper((unsigned char)*bit) == 'Z')
290 return PCOP(popCopyGPR2Bit(&pc_status,PIC_Z_BIT));
294 if(len ==2 && toupper((unsigned char)bit[0]) == 'D' && toupper((unsigned char)bit[1]) == 'C')
295 return PCOP(popCopyGPR2Bit(&pc_status,PIC_DC_BIT));
301 /*-----------------------------------------------------------------*/
302 /* cvt_altpat_label - convert assembly line type to a pCode label */
303 /* INPUT: pointer to the parsedPattern */
307 /* label pattern => '%' number ':' */
308 /* at this point, we wish to extract only the 'number' */
310 /*-----------------------------------------------------------------*/
311 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
313 parsedPattern *p = pp;
315 DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
316 return newpCodeLabel(NULL,-p->pct[1].tok.n);
320 /*-----------------------------------------------------------------*/
321 /* cvt_altpat_comment - convert assembly line type to a comment */
322 /* INPUT: pointer to the parsedPattern */
324 /* pp[0] - comment */
327 /*-----------------------------------------------------------------*/
328 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
330 parsedPattern *p = pp;
332 DFPRINTF((stderr,"altpat_comment = %s\n",p->pct[0].tok.s));
333 return newpCodeCharP(p->pct[0].tok.s);
337 /*-----------------------------------------------------------------*/
338 /* cvt_altpat_mem0 - convert assembly line type to a wild pCode */
343 /*-----------------------------------------------------------------*/
344 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
346 parsedPattern *p = pp;
349 pCodeInstruction *pci=NULL;
351 DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s));
353 opcode = getpCode(p->pct[0].tok.s,0);
356 /* look for special command strings like _NOTBITSKIP_ */
358 //fprintf(stderr, "Bad mnemonic\n");
360 opcode = getpCodePeepCommand(p->pct[0].tok.s);
362 // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
366 pci = PCI(newpCode(opcode, NULL));
369 fprintf(stderr,"couldn't find mnemonic\n");
375 /*-----------------------------------------------------------------*/
376 /* cvt_altpat_mem0a - convert assembly line type to a wild pCode */
379 /* pp[0] - wild var */
381 /*-----------------------------------------------------------------*/
382 static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
384 parsedPattern *p = pp;
386 DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n));
388 /* Save the index of the maximum wildcard mnemonic */
390 //if(p[0].pct[1].tok.n > sMaxWildVar)
391 // sMaxWildMnem = p[0].pct[1].tok.n;
393 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
394 pcwb->nwildpCodes = p[0].pct[1].tok.n;
396 return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
400 /*-----------------------------------------------------------------*/
401 /* cvt_altpat_mem1 - convert assembly line type to a pCode */
402 /* instruction with 1 operand. */
405 /* pp[1] - Operand */
407 /*-----------------------------------------------------------------*/
408 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
411 parsedPattern *p = pp;
414 pCodeInstruction *pci=NULL;
417 DFPRINTF((stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s));
419 opcode = getpCode(p->pct[0].tok.s,0);
421 //fprintf(stderr, "Bad mnemonic\n");
422 opcode = getpCodePeepCommand(p->pct[0].tok.s);
424 //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
429 if(pic14Mnemonics[opcode]->isBitInst)
430 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
432 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
435 pci = PCI(newpCode(opcode, pcosubtype));
438 fprintf(stderr,"couldn't find mnemonic\n");
444 /*-----------------------------------------------------------------*/
445 /* cvt_altpat_mem1a - convert assembly line type to a pCode */
446 /* instruction with 1 wild operand. */
449 /* pp[1] - wild var */
451 /*-----------------------------------------------------------------*/
452 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
454 parsedPattern *p = pp;
457 pCodeInstruction *pci=NULL;
460 DFPRINTF((stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n));
462 opcode = getpCode(p->pct[0].tok.s,0);
464 int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
468 fprintf(stderr, "Bad mnemonic\n");
472 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
473 pcwb->nwildpCodes = p[0].pct[1].tok.n;
475 pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
479 PCW(pc)->mustNotBeBitSkipInst = 1;
482 PCW(pc)->mustBeBitSkipInst = 1;
485 PCW(pc)->invertBitSkipInst = 1;
490 if(pic14Mnemonics[opcode]->isBitInst)
491 pcosubtype = newpCodeOpBit(NULL,-1,0);
493 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
496 pci = PCI(newpCode(opcode,
497 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
499 /* Save the index of the maximum wildcard variable */
500 //if(p[1].pct[1].tok.n > sMaxWildVar)
501 // sMaxWildVar = p[1].pct[1].tok.n;
503 if(p[1].pct[1].tok.n > pcwb->nvars)
504 pcwb->nvars = p[1].pct[1].tok.n;
507 fprintf(stderr,"couldn't find mnemonic\n");
513 /*-----------------------------------------------------------------*/
514 /*-----------------------------------------------------------------*/
515 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
517 parsedPattern *p = pp;
520 pCodeInstruction *pci=NULL;
522 DFPRINTF((stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n));
524 opcode = getpCode(p->pct[0].tok.s,0);
526 fprintf(stderr, "Bad mnemonic\n");
530 pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
533 fprintf(stderr,"couldn't find mnemonic\n");
539 /*-----------------------------------------------------------------*/
540 /* cvt_altpat_mnem2 */
545 /* pp[3] - destination */
546 /*-----------------------------------------------------------------*/
547 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
549 parsedPattern *p = pp;
553 pCodeInstruction *pci=NULL;
556 dest = cvt_extract_destination(&p[3]);
558 DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
565 opcode = getpCode(p->pct[0].tok.s,dest);
567 fprintf(stderr, "Bad mnemonic\n");
571 if(pic14Mnemonics[opcode]->isBitInst) {
572 pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
573 if(pcosubtype == NULL) {
574 fprintf(stderr, "bad operand?\n");
579 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
582 pci = PCI(newpCode(opcode,pcosubtype));
585 fprintf(stderr,"couldn't find mnemonic\n");
591 /*-----------------------------------------------------------------*/
592 /* cvt_altpat_mem2a - convert assembly line type to a pCode */
593 /* instruction with 1 wild operand and a */
594 /* destination operand (e.g. w or f) */
597 /* pp[1] - wild var */
599 /* pp[3] - destination */
601 /*-----------------------------------------------------------------*/
602 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
604 parsedPattern *p = pp;
608 pCodeInstruction *pci=NULL;
612 fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
616 dest = cvt_extract_destination(&p[3]);
618 DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
625 opcode = getpCode(p->pct[0].tok.s,dest);
627 fprintf(stderr, "Bad mnemonic\n");
631 if(pic14Mnemonics[opcode]->isBitInst)
632 pcosubtype = newpCodeOp(NULL,PO_BIT);
634 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
637 pci = PCI(newpCode(opcode,
638 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
640 /* Save the index of the maximum wildcard variable */
641 //if(p[1].pct[1].tok.n > sMaxWildVar)
642 // sMaxWildVar = p[1].pct[1].tok.n;
644 if(p[1].pct[1].tok.n > pcwb->nvars)
645 pcwb->nvars = p[1].pct[1].tok.n;
648 fprintf(stderr,"couldn't find mnemonic\n");
655 /*-----------------------------------------------------------------*/
656 /* cvt_altpat_mem3 - convert assembly line type to a pCode */
657 /* This rule is for bsf/bcf type instructions */
661 /* pp[1] - register */
665 /*-----------------------------------------------------------------*/
666 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
668 parsedPattern *p = pp;
670 int dest; // or could be bit position in the register
672 pCodeInstruction *pci=NULL;
673 pCodeOp *pcosubtype=NULL;
675 dest = cvt_extract_destination(&p[3]);
677 DFPRINTF((stderr,"altpat_mnem3 %s var %s bit (%d)\n",
683 opcode = getpCode(p->pct[0].tok.s,0);
685 fprintf(stderr, "Bad mnemonic\n");
690 if(pic14Mnemonics[opcode]->isBitInst) {
691 //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
693 //if(pcosubtype == NULL) {
694 pcosubtype = newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0);
697 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
699 if(pcosubtype == NULL) {
700 fprintf(stderr, "Bad operand\n");
704 pci = PCI(newpCode(opcode, pcosubtype));
707 fprintf(stderr,"couldn't find mnemonic\n");
713 /*-----------------------------------------------------------------*/
714 /* tokenizeLineNode - Convert a string (of char's) that was parsed */
715 /* by SDCCpeeph.c into a string of tokens. */
718 /* The tokenizer is of the classic type. When an item is encounterd*/
719 /* it is converted into a token. The token is a structure that */
720 /* encodes the item's type and it's value (when appropriate). */
722 /* Accepted token types: */
723 /* SPACE NUMBER STRING % : , ; */
727 /*-----------------------------------------------------------------*/
730 static void tokenizeLineNode(char *ln)
733 tokIdx = 0; // Starting off at the beginning
734 tokArr[0].tt = PCT_NULL; // and assume invalid character for first token.
742 if(isspace((unsigned char)*ln)) {
743 // add a SPACE token and eat the extra spaces.
744 tokArr[tokIdx++].tt = PCT_SPACE;
745 while (isspace ((unsigned char)*ln))
750 if(isdigit((unsigned char)*ln)) {
752 tokArr[tokIdx].tt = PCT_NUMBER;
753 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
761 tokArr[tokIdx++].tt = PCT_PERCENT;
764 tokArr[tokIdx++].tt = PCT_LESSTHAN;
767 tokArr[tokIdx++].tt = PCT_GREATERTHAN;
770 tokArr[tokIdx++].tt = PCT_COLON;
773 tokArr[tokIdx].tok.s = Safe_strdup(ln);
774 tokArr[tokIdx++].tt = PCT_COMMENT;
775 tokArr[tokIdx].tt = PCT_NULL;
778 tokArr[tokIdx++].tt = PCT_COMMA;
783 if(isalpha((unsigned char)*ln) || (*ln == '_') ) {
787 while( (isalpha((unsigned char)*ln) || isdigit((unsigned char)*ln) || (*ln == '_')) && i<49)
793 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
794 tokArr[tokIdx++].tt = PCT_STRING;
797 fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
798 fprintf(stderr, "Line: %s\n",lnstart);
799 fprintf(stderr, "Token: '%c'\n",*ln);
804 /* Advance to next character in input string .
805 * Note, if none of the tests passed above, then
806 * we effectively ignore the `bad' character.
807 * Since the line has already been parsed by SDCCpeeph,
808 * chance are that there are no invalid characters... */
814 tokArr[tokIdx].tt = 0;
818 /*-----------------------------------------------------------------*/
819 /*-----------------------------------------------------------------*/
823 void dump1Token(pCodeTokens tt)
828 fprintf(stderr, " space ");
831 fprintf(stderr, " pct %%");
834 fprintf(stderr, " pct <");
836 case PCT_GREATERTHAN:
837 fprintf(stderr, " pct >");
840 fprintf(stderr, " col :");
843 fprintf(stderr, " comma , ");
846 fprintf(stderr, " comment ");
847 //fprintf(stderr,"%s",tokArr[i].tok.s);
850 fprintf(stderr, " str ");
851 //fprintf(stderr,"%s",tokArr[i].tok.s);
854 fprintf(stderr, " num ");
855 //fprintf(stderr,"%d",tokArr[i].tok.n);
858 fprintf(stderr, " null ");
865 /*-----------------------------------------------------------------*/
866 /*-----------------------------------------------------------------*/
868 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
872 if(!pct || !pat || !*pat)
875 //DFPRINTF((stderr,"comparing against:\n"));
877 while(i < max_tokens) {
880 //DFPRINTF((stderr,"matched\n"));
884 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
898 /*-----------------------------------------------------------------*/
899 /*-----------------------------------------------------------------*/
901 int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
905 if(!pct || !pat || !*pct)
909 while(i < max_tokens) {
912 //DFPRINTF((stderr,"matched\n"));
916 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
918 if( !pat || !pat->pcp )
921 if (pat->pcp->pt != *pct)
924 //DFPRINTF((stderr," pct=%d\n",*pct));
933 /*-----------------------------------------------------------------*/
934 /*-----------------------------------------------------------------*/
936 int advTokIdx(int *v, int amt)
939 if((unsigned) (*v + amt) > tokIdx)
947 /*-----------------------------------------------------------------*/
948 /* parseTokens - convert the tokens corresponding to a single line */
949 /* of a peep hole assembly into a pCode object. */
954 /* This is a simple parser that looks for strings of the type */
955 /* allowed in the peep hole definition file. Essentially the format*/
956 /* is the same as a line of assembly: */
958 /* label: mnemonic op1, op2, op3 ; comment */
960 /* Some of these items aren't present. It's the job of the parser */
961 /* to determine which are and convert those into the appropriate */
963 /*-----------------------------------------------------------------*/
965 int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
976 for(i=0; i<=tokIdx; i++)
977 dump1Token(tokArr[i].tt);
990 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
991 char * cP1stop = NULL;
992 char * cP2ndop = NULL;
994 //pCodeOp *pcl = NULL; // Storage for a label
995 //pCodeOp *pco1 = NULL; // 1st operand
996 //pCodeOp *pco2 = NULL; // 2nd operand
997 //pCode *pc = NULL; // Mnemonic
1008 ParseStates state = PS_START;
1015 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
1016 && (advTokIdx(<okIdx, 1)) ) // eat space
1020 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
1023 switch(pcpArr[lpcpIdx].pt) {
1025 if(state == PS_START){
1026 DFPRINTF((stderr," label\n"));
1027 state = PS_HAVE_LABEL;
1029 DFPRINTF((stderr," bad state (%d) for label\n",state));
1033 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
1037 DFPRINTF((stderr," mnem\n"));
1038 cPmnem = tokArr[ltokIdx].tok.s;
1039 state = PS_HAVE_MNEM;
1042 DFPRINTF((stderr," 1st operand\n"));
1043 cP1stop = tokArr[ltokIdx].tok.s;
1044 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
1045 state = PS_HAVE_1OPERAND;
1047 case PS_HAVE_1OPERAND:
1048 DFPRINTF((stderr," error expecting comma\n"));
1051 DFPRINTF((stderr," 2 operands\n"));
1052 cP2ndop = tokArr[ltokIdx].tok.s;
1054 case PS_HAVE_2OPERANDS:
1063 DFPRINTF((stderr," wild mnem\n"));
1064 state = PS_HAVE_MNEM;
1067 DFPRINTF((stderr," 1st operand is wild\n"));
1068 state = PS_HAVE_1OPERAND;
1070 case PS_HAVE_1OPERAND:
1071 DFPRINTF((stderr," error expecting comma\n"));
1074 DFPRINTF((stderr," 2nd operand is wild\n"));
1076 case PS_HAVE_2OPERANDS:
1085 fprintf(stderr," ERROR number\n");
1088 DFPRINTF((stderr," 1st operand is a number\n"));
1089 state = PS_HAVE_1OPERAND;
1091 case PS_HAVE_1OPERAND:
1092 fprintf(stderr," error expecting comma\n");
1095 DFPRINTF((stderr," 2nd operand is a number\n"));
1097 case PS_HAVE_2OPERANDS:
1105 if(state == PS_HAVE_1OPERAND){
1106 DFPRINTF((stderr," got a comma\n"));
1107 state = PS_HAVE_COMMA;
1109 fprintf(stderr," unexpected comma\n");
1115 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1116 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1119 //dump1Token(tokArr[ltokIdx].tt);
1121 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1122 DFPRINTF((stderr," reached end \n"));
1129 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1133 parsedPatArr[lparsedPatIdx].pcp = NULL;
1134 parsedPatArr[lparsedPatIdx].pct = NULL;
1140 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1143 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1144 //if(pc && pc->print)
1145 // pc->print(stderr,pc);
1146 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1148 //if(curBlock && pc)
1149 //addpCode2pBlock(curBlock, pc);
1153 return 0; // Only accept one line for now.
1155 addpCode2pBlock(pcwb->pb, pc);
1163 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1166 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1170 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1171 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1172 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1175 while(j<lparsedPatIdx);
1177 DFPRINTF((stderr,"\n"));
1184 /*-----------------------------------------------------------------*/
1186 /*-----------------------------------------------------------------*/
1187 void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
1193 for( ; ln; ln = ln->next) {
1195 //DFPRINTF((stderr,"%s\n",ln->line));
1197 tokenizeLineNode(ln->line);
1199 if(parseTokens(pcwb,NULL)) {
1201 fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
1202 fprintf(stderr,"Tokens:\n");
1204 dump1Token(tokArr[i].tt);
1211 /*-----------------------------------------------------------------*/
1213 /*-----------------------------------------------------------------*/
1214 pCode *AssembleLine(char *line)
1218 if(!line || !*line) {
1219 fprintf(stderr,"WARNING returning NULL in AssembleLine\n");
1223 tokenizeLineNode(line);
1225 if(parseTokens(NULL,&pc))
1226 fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
1232 /*-----------------------------------------------------------------*/
1233 /* peepRuleCondition */
1234 /*-----------------------------------------------------------------*/
1235 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1240 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1241 /* brute force compares for now */
1243 if(STRCASECMP(cond, "NZ") == 0) {
1244 //DFPRINTF((stderr,"found NZ\n"));
1245 pcp->postFalseCond = PCC_Z;
1252 void initpCodeWildBlock(pCodeWildBlock *pcwb)
1255 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1261 pcwb->wildpCodes = NULL;
1262 pcwb->wildpCodeOps = NULL;
1265 pcwb->nwildpCodes = 0;
1270 void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1277 pcwb->nops = pcwb->nvars;
1279 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1280 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1282 pcwb->nwildpCodes+=2;
1283 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1287 void initpCodePeep(pCodePeep *pcp)
1290 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1295 initpCodeWildBlock(&pcp->target);
1296 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1298 initpCodeWildBlock(&pcp->replace);
1299 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1303 /*-----------------------------------------------------------------*/
1304 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1307 /* SDCCpeeph parses the peep rules file and extracts variables, */
1308 /* removes white space, and checks the syntax. This function */
1309 /* extends that processing to produce pCode objects. You can kind */
1310 /* think of this function as an "assembler", though instead of */
1311 /* taking raw text to produce machine code, it produces pCode. */
1313 /*-----------------------------------------------------------------*/
1314 extern void pic14initpCodePeepCommands(void);
1316 void peepRules2pCode(peepRule *rules)
1320 pCodePeep *currentRule;
1321 pCodePeepSnippets *pcps;
1323 pic14initpCodePeepCommands();
1325 /* The rules are in a linked-list. Each rule has two portions */
1326 /* There's the `target' and there's the `replace'. The target */
1327 /* is compared against the SDCC generated code and if it */
1328 /* matches, it gets replaced by the `replace' block of code. */
1330 /* Here we loop through each rule and convert the target's and*/
1331 /* replace's into pCode target and replace blocks */
1333 for (pr = rules; pr; pr = pr->next) {
1335 //DFPRINTF((stderr,"\nRule:\n\n"));
1337 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1338 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1340 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1341 initpCodePeep(currentRule);
1343 /* Convert the target block */
1344 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1346 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1347 //printpBlock(stderr, currentRule->target.pb);
1349 //DFPRINTF((stderr,"target with labels merged:\n"));
1350 //pBlockMergeLabels(curBlock);
1351 pBlockMergeLabels(currentRule->target.pb);
1352 //printpBlock(stderr, currentRule->replace.pb);
1354 //#ifdef PCODE_DEBUG
1355 // printpBlock(stderr, curBlock);
1357 //DFPRINTF((stderr,"\nReplaced by:\n"));
1360 /* Convert the replace block */
1361 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1363 //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
1364 //printpBlock(stderr, curBlock);
1366 //DFPRINTF((stderr,"replace with labels merged:\n"));
1368 pBlockMergeLabels(currentRule->replace.pb);
1369 //printpBlock(stderr, currentRule->replace.pb);
1371 peepRuleCondition(pr->cond,currentRule);
1373 /* The rule has been converted to pCode. Now allocate
1374 * space for the wildcards */
1376 postinit_pCodeWildBlock(¤tRule->target);
1377 postinit_pCodeWildBlock(¤tRule->replace);
1379 //return; // debug ... don't want to go through all the rules yet
1383 pCodePeep *peepBlock;
1386 peeprules = (_DLL *)peepSnippets;
1387 //fprintf(stderr,"target rules\n");
1389 //fprintf(stderr," rule:\n");
1390 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1391 //printpBlock(stderr, peepBlock->target.pb);
1392 peeprules = peeprules->next;
1394 //fprintf(stderr," ... done\n");
1399 void printpCodeString(FILE *of, pCode *pc, int max)
1403 while(pc && (i++<max)) {
1409 /*-----------------------------------------------------------------*/
1410 /* _DLL * DLL_append */
1412 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1413 /* If The list to which we want to append is non-existant then one */
1414 /* is created. Other wise, the end of the list is sought out and */
1415 /* a new DLL object is appended to it. In either case, the void */
1416 /* *data is added to the newly created DLL object. */
1417 /*-----------------------------------------------------------------*/
1419 static void * DLL_append(_DLL *list, _DLL *next)
1424 /* If there's no list, then create one: */
1426 next->next = next->prev = NULL;
1431 /* Search for the end of the list. */
1436 /* Now append the new DLL object */
1447 /*-----------------------------------------------------------------
1449 pCode peephole optimization
1452 The pCode "peep hole" optimization is not too unlike the peep hole
1453 optimization in SDCCpeeph.c. The major difference is that here we
1454 use pCode's whereas there we use ASCII strings. The advantage with
1455 pCode's is that we can ascertain flow information in the instructions
1459 <FIX ME> - elaborate...
1461 -----------------------------------------------------------------*/
1465 /*-----------------------------------------------------------------*/
1466 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1468 /* return conditions */
1469 /* 1 - The Condition was found for a pCode's input */
1470 /* 0 - No matching condition was found for the whole chain */
1471 /* -1 - The Condition was found for a pCode's output */
1473 /*-----------------------------------------------------------------*/
1474 int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip)
1478 /* If we reach a function end (presumably an end since we most
1479 probably began the search in the middle of a function), then
1480 the condition was not found. */
1481 if(pc->type == PC_FUNCTION)
1484 if(pc->type == PC_OPCODE) {
1485 if(PCI(pc)->inCond & cond) {
1487 /* If previous instruction is a skip then continue search as condiction is not certain */
1488 pCode *pcp = findPrevInstruction(pc->prev);
1489 if (pcp && !isPCI_SKIP(pcp)) {
1496 if(PCI(pc)->outCond & cond) {
1498 /* If previous instruction is a skip then continue search as condiction is not certain */
1499 pCode *pcp = findPrevInstruction(pc->prev);
1500 if (pcp && !isPCI_SKIP(pcp)) {
1515 /*-----------------------------------------------------------------
1516 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1518 * Compare two pCodeOp's and return 1 if they're the same
1519 *-----------------------------------------------------------------*/
1520 int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1524 if(!pcops || !pcopd)
1527 fprintf(stderr," Comparing operands %s",
1528 get_op( pcops,NULL,0));
1530 fprintf(stderr," to %s\n",
1531 get_op( pcopd,NULL,0));
1534 if(pcops->type != pcopd->type) {
1535 //fprintf(stderr," - fail - diff types\n");
1536 return 0; // different types
1539 if(pcops->type == PO_LITERAL) {
1541 if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit))
1550 n2 = get_op(pcopd,NULL,0);
1552 if( !n2 || strcmp(b,n2)) {
1553 //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
1554 return 0; // different names
1557 switch(pcops->type) {
1559 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1560 //fprintf(stderr, " - fail different instances\n");
1568 //fprintf(stderr," - pass\n");
1573 int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1577 /* Check for a label associated with this wild pCode */
1578 // If the wild card has a label, make sure the source code does too.
1579 if(PCI(pcd)->label) {
1580 pCode *pcl = PCI(pcd)->label->pc;
1583 int li = -PCL(pcl)->key;
1585 if(peepBlock->target.vars[li] == NULL) {
1586 if(PCI(pcs)->label) {
1587 DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
1590 // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
1591 DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
1592 if(PCI(pcs)->label) {
1593 DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
1599 if(!PCI(pcs)->label)
1602 labindex = -PCL(pcl)->key;
1603 if(peepBlock->target.vars[labindex] == NULL) {
1604 // First time to encounter this label
1605 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1606 DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
1609 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1610 DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
1613 DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
1616 //DFPRINTF((stderr,"destination doesn't have a label\n"));
1621 //DFPRINTF((stderr,"neither src nor dest have labels\n"));
1629 /*-----------------------------------------------------------------*/
1630 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1631 /* see they're the same. */
1633 /* In this context, "source" refers to the coded generated by gen.c*/
1634 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1635 /* ination has no wild cards, then MatchLine will compare the two */
1636 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1637 /* has wildcards, then those get expanded. When a wild card is */
1638 /* encountered for the first time it autmatically is considered a */
1639 /* match and the object that matches it is referenced in the */
1640 /* variables or opcodes array (depending on the type of match). */
1644 /* *peepBlock - A pointer to the peepBlock that contains the */
1645 /* entire rule to which the destination pcode belongs*/
1646 /* *pcs - a pointer to the source pcode */
1647 /* *pcd - a pointer to the destination pcode */
1650 /* 1 - pcodes match */
1651 /* 0 - pcodes don't match */
1654 /*-----------------------------------------------------------------*/
1656 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1658 int index; // index into wild card arrays
1660 /* one-for-one match. Here the source and destination opcodes
1661 * are not wild. However, there may be a label or a wild operand */
1664 if(PCI(pcs)->label) {
1665 DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
1669 if(pcs->type == pcd->type) {
1671 if(pcs->type == PC_OPCODE) {
1673 /* If the opcodes don't match then the line doesn't match */
1674 if(PCI(pcs)->op != PCI(pcd)->op)
1678 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1679 pcs->print(stderr,pcs);
1680 pcd->print(stderr,pcd);
1683 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1686 /* Compare the operands */
1687 if(PCI(pcd)->pcop) {
1688 // Volatile types should not be deleted or modified, these include SFR, externs and publics
1689 // They can be used as a matched, however if a match is found then the optimiser intends
1690 // to change some aspect of a block of code, which is most likely a critcal one. As this
1691 // method of optimisation does not allow a means to distiguishing what may change, it is
1692 // best to just negate any match.
1693 if (PCI(pcs)->pcop) {
1695 pCodeOp *pcop = PCI(pcs)->pcop;
1696 switch(pcop->type) {
1704 case PO_SFR_REGISTER:
1705 return 0; // SFR - do not modify
1707 case PO_GPR_REGISTER:
1710 case PO_GPR_POINTER:
1712 if (r->isPublic||r->isExtern||r->isFixed) // Changes to these types of registers should not be changed as they may be used else where
1718 if (PCI(pcd)->pcop->type == PO_WILD) {
1720 index = PCOW(PCI(pcd)->pcop)->id;
1721 //DFPRINTF((stderr,"destination is wild\n"));
1722 #ifdef DEBUG_PCODEPEEP
1723 if (index > peepBlock->nops) {
1724 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1728 n = PCI(pcs)->pcop->name;
1729 if(peepBlock->target.vars[index]) {
1730 if ((!n)||(strcmp(peepBlock->target.vars[index],n) != 0))
1731 return 0; // variable is different
1733 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1734 peepBlock->target.vars[index] = n;
1737 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1738 if(!peepBlock->target.wildpCodeOps[index]) {
1739 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1741 //fprintf(stderr, "first time for wild opcode #%d\n",index);
1746 pcs->print(stderr,pcs);
1747 pcd->print(stderr,pcd);
1748 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1749 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1753 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1759 switch(PCI(pcs)->pcop->type) {
1763 //n = PCOR(PCI(pcs)->pcop)->r->name;
1764 n = PCI(pcs)->pcop->name;
1768 n = PCI(pcs)->pcop->name;
1771 if(peepBlock->target.vars[index])
1772 return (strcmp(peepBlock->target.vars[index],n) == 0);
1774 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1775 peepBlock->target.vars[index] = n;
1780 } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
1782 pcs->print(stderr,pcs);
1783 pcd->print(stderr,pcd);
1785 fprintf(stderr, "comparing literal operands of these instructions, result %d\n",
1786 pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop));
1788 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1791 /* FIXME - need an else to check the case when the destination
1792 * isn't a wild card */
1794 fprintf(stderr, "Destination is not wild: operand compare =%d\n",
1795 pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop));
1797 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1801 /* The pcd has no operand. Lines match if pcs has no operand either*/
1802 return (PCI(pcs)->pcop == NULL);
1806 /* Compare a wild instruction to a regular one. */
1808 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1810 index = PCW(pcd)->id;
1812 DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1813 pcs->print(stderr,pcs);
1814 pcd->print(stderr,pcd);
1816 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1818 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
1819 DFPRINTF((stderr," Failing because labels don't match\n"));
1823 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1824 // doesn't match because the wild pcode must be a bit skip
1825 DFPRINTF((stderr," Failing match because bit skip is req\n"));
1826 //pcd->print(stderr,pcd);
1827 //pcs->print(stderr,pcs);
1831 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1832 // doesn't match because the wild pcode must *not* be a bit skip
1833 DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
1834 //pcd->print(stderr,pcd);
1835 //pcs->print(stderr,pcs);
1839 if(PCW(pcd)->operand) {
1840 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1841 if(peepBlock->target.vars[index]) {
1842 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1846 DFPRINTF((stderr," (matched)\n"));
1848 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1849 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n",
1850 peepBlock->target.vars[index],
1851 PCI(pcs)->pcop->name));
1856 DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
1857 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1862 pcs = findNextInstruction(pcs->next);
1864 //DFPRINTF((stderr," (next to match)\n"));
1865 //pcs->print(stderr,pcs);
1866 } else if(pcd->next) {
1867 /* oops, we ran out of code, but there's more to the rule */
1871 return 1; /* wild card matches */
1877 /*-----------------------------------------------------------------*/
1878 /*-----------------------------------------------------------------*/
1879 void pCodePeepClrVars(pCodePeep *pcp)
1886 DFPRINTF((stderr," Clearing peep rule vars\n"));
1887 DFPRINTF((stderr," %d %d %d %d %d %d\n",
1888 pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
1889 pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
1891 for(i=0;i<pcp->target.nvars; i++)
1892 pcp->target.vars[i] = NULL;
1893 for(i=0;i<pcp->target.nops; i++)
1894 pcp->target.wildpCodeOps[i] = NULL;
1895 for(i=0;i<pcp->target.nwildpCodes; i++)
1896 pcp->target.wildpCodes[i] = NULL;
1898 for(i=0;i<pcp->replace.nvars; i++)
1899 pcp->replace.vars[i] = NULL;
1900 for(i=0;i<pcp->replace.nops; i++)
1901 pcp->replace.wildpCodeOps[i] = NULL;
1902 for(i=0;i<pcp->replace.nwildpCodes; i++)
1903 pcp->replace.wildpCodes[i] = NULL;
1909 /*-----------------------------------------------------------------*/
1910 /*-----------------------------------------------------------------*/
1911 int pCodePeepMatchRule(pCode *pc)
1913 pCodePeep *peepBlock;
1915 pCodeCSource *pc_cline=NULL;
1919 peeprules = (_DLL *)peepSnippets;
1922 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1924 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
1925 fprintf(stderr, "skipping rule because target pb is NULL\n");
1929 pCodePeepClrVars(peepBlock);
1932 if(IS_PCCOMMENT(pcin))
1933 pc = pcin = findNextInstruction(pcin->next);
1935 pcin = pc = findNextInstruction(pc);
1937 pct = peepBlock->target.pb->pcHead;
1940 pCode *pcr = peepBlock->replace.pb->pcHead;
1941 if(pcr) pct->print(stderr,pcr);
1945 while(pct && pcin) {
1947 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1950 pcin = findNextInstruction(pcin->next);
1953 //DFPRINTF((stderr," matched\n"));
1956 DFPRINTF((stderr," partial match... no more code\n"));
1960 DFPRINTF((stderr," end of rule\n"));
1964 if(matched && pcin) {
1966 /* So far we matched the rule up to the point of the conditions .
1967 * In other words, all of the opcodes match. Now we need to see
1968 * if the post conditions are satisfied.
1969 * First we check the 'postFalseCond'. This means that we check
1970 * to see if any of the subsequent pCode's in the pCode chain
1971 * following the point just past where we have matched depend on
1972 * the `postFalseCond' as input then we abort the match
1974 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
1975 //pcin->print(stderr,pcin);
1977 if (pcin && peepBlock->postFalseCond &&
1978 (pCodeSearchCondition(pcin,peepBlock->postFalseCond,0) > 0) )
1981 //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
1984 //if(!matched) fprintf(stderr,"failed on conditions\n");
1993 /* We matched a rule! Now we have to go through and remove the
1994 inefficient code with the optimized version */
1996 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
1997 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
1998 DFPRINTF((stderr,"first thing matched\n"));
1999 pc->print(stderr,pc);
2001 DFPRINTF((stderr,"last thing matched\n"));
2002 pcin->print(stderr,pcin);
2007 /* Unlink the original code */
2010 pcprev->next = pcin;
2012 pcin->prev = pc->prev;
2018 /* Converted the deleted pCodes into comments */
2021 pCodeCSource *pc_cline2=NULL;
2026 while(pc && pc!=pcin) {
2028 if(pc->type == PC_OPCODE && PCI(pc)->cline) {
2030 pc_cline2->pc.next = PCODE(PCI(pc)->cline);
2031 pc_cline2 = PCCS(pc_cline2->pc.next);
2033 pc_cline = pc_cline2 = PCI(pc)->cline;
2034 pc_cline->pc.seq = pc->seq;
2038 pCode2str(&buf[2], 254, pc);
2039 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
2040 pcprev = pcprev->next;
2045 pc_cline2->pc.next = NULL;
2050 pCodeDeleteChain(pc,pcin);
2052 /* Generate the replacement code */
2054 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
2058 /* If the replace pcode is an instruction with an operand, */
2059 /* then duplicate the operand (and expand wild cards in the process). */
2060 if(pcr->type == PC_OPCODE) {
2061 if(PCI(pcr)->pcop) {
2062 /* The replacing instruction has an operand.
2064 if(PCI(pcr)->pcop->type == PO_WILD) {
2065 int index = PCOW(PCI(pcr)->pcop)->id;
2066 //DFPRINTF((stderr,"copying wildopcode\n"));
2067 if(peepBlock->target.wildpCodeOps[index])
2068 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
2070 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
2072 pcop = pCodeOpCopy(PCI(pcr)->pcop);
2074 //DFPRINTF((stderr,"inserting pCode\n"));
2075 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
2076 } else if (pcr->type == PC_WILD) {
2077 if(PCW(pcr)->invertBitSkipInst)
2078 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
2079 pCodeInsertAfter(pc,
2080 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
2081 PCW(pcr)->invertBitSkipInst));
2082 } else if (pcr->type == PC_COMMENT) {
2083 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
2088 DFPRINTF((stderr," NEW Code:"));
2089 if(pc) pc->print(stderr,pc);
2094 /* We have just replaced the inefficient code with the rule.
2095 * Now, we need to re-add the C-source symbols if there are any */
2097 while(pc && pc_cline ) {
2099 pc = findNextInstruction(pc->next);
2101 PCI(pc)->cline = pc_cline;
2102 pc_cline = PCCS(pc_cline->pc.next);
2106 /* Copy C code comments to new code. */
2109 for (; pc && pcout!=pcin; pcout=pcout->next) {
2110 if (pcout->type==PC_OPCODE && PCI(pcout)->cline) {
2111 while (pc->type!=PC_OPCODE || PCI(pc)->cline) {
2117 PCI(pc)->cline = PCI(pcout)->cline;
2125 peeprules = peeprules->next;
2127 DFPRINTF((stderr," no rule matched\n"));