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 #if defined(__BORLANDC__) || defined(_MSC_VER)
32 #define STRCASECMP stricmp
34 #define STRCASECMP strcasecmp
37 pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
40 pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype);
41 pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
42 pCode * findNextInstruction(pCode *pc);
43 int getpCode(char *mnem,int dest);
44 int getpCodePeepCommand(char *cmd);
45 void pBlockMergeLabels(pBlock *pb);
46 char *pCode2str(char *str, int size, pCode *pc);
47 char *get_op( pCodeOp *pcop,char *buf,int buf_size);
49 extern pCodeInstruction *pic14Mnemonics[];
52 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
54 /****************************************************************/
56 * rootRules - defined in SDCCpeep.c
57 * This is a pointer to the (parsed) peephole rules that are
58 * defined in peep.def.
61 //extern peepRule *rootRules;
66 /****************************************************************/
67 /****************************************************************/
75 typedef struct pCodePeepSnippets
82 /****************************************************************/
86 /****************************************************************/
88 static pCodePeepSnippets *peepSnippets=NULL;
90 /****************************************************************/
94 /****************************************************************/
96 //static pCodePeep *curPeep=NULL;
98 /****************************************************************/
102 /****************************************************************/
104 //static pBlock *curBlock=NULL;
107 /****************************************************************/
109 /* max wild cards in a peep rule */
111 /****************************************************************/
113 //static int sMaxWildVar = 0;
114 //static int sMaxWildMnem = 0;
117 typedef struct pCodeToken
119 int tt; // token type;
128 pCodeToken tokArr[50];
147 typedef struct parsedPattern {
148 struct pcPattern *pcp;
152 #define MAX_PARSEDPATARR 50
153 parsedPattern parsedPatArr[MAX_PARSEDPATARR];
154 unsigned int parsedPatIdx=0;
167 static char pcpat_label[] = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
168 static char pcpat_number[] = {PCT_NUMBER, 0};
169 static char pcpat_string[] = {PCT_STRING, 0};
170 static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
171 static char pcpat_wildVar[] = {PCT_PERCENT, PCT_NUMBER, 0};
172 static char pcpat_comma[] = {PCT_COMMA, 0};
173 static char pcpat_comment[] = {PCT_COMMENT, 0};
176 typedef struct pcPattern {
177 char pt; // Pattern type
178 char *tokens; // list of tokens that describe the pattern
179 void * (*f) (void *,pCodeWildBlock *);
182 pcPattern pcpArr[] = {
183 {PCP_LABEL, pcpat_label, NULL},
184 {PCP_WILDSTR, pcpat_wildString, NULL},
185 {PCP_STR, pcpat_string, NULL},
186 {PCP_WILDVAR, pcpat_wildVar, NULL},
187 {PCP_COMMA, pcpat_comma, NULL},
188 {PCP_COMMENT, pcpat_comment, NULL},
189 {PCP_NUMBER, pcpat_number, NULL}
192 #define PCPATTERNS (sizeof(pcpArr)/sizeof(pcPattern))
194 // Assembly Line Token
207 static char alt_comment[] = { PCP_COMMENT, 0};
208 static char alt_label[] = { PCP_LABEL, 0};
209 static char alt_mnem0[] = { PCP_STR, 0};
210 static char alt_mnem0a[] = { PCP_WILDVAR, 0};
211 static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
212 static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0};
213 static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
214 static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
215 static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
217 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
218 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
219 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
220 static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
221 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
222 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
223 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
224 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
225 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
227 pcPattern altArr[] = {
228 {ALT_LABEL, alt_label, cvt_altpat_label},
229 {ALT_COMMENT, alt_comment,cvt_altpat_comment},
230 {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
231 {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
232 {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
233 {ALT_MNEM1A, alt_mnem1a, cvt_altpat_mnem1a},
234 {ALT_MNEM1, alt_mnem1, cvt_altpat_mnem1},
235 {ALT_MNEM0A, alt_mnem0a, cvt_altpat_mnem0a},
236 {ALT_MNEM0, alt_mnem0, cvt_altpat_mnem0},
240 #define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
242 // forward declarations
243 static void * DLL_append(_DLL *list, _DLL *next);
245 /*-----------------------------------------------------------------*/
246 /* cvt_extract_destination - helper function extracts the register */
247 /* destination from a parsedPattern. */
249 /*-----------------------------------------------------------------*/
250 static int cvt_extract_destination(parsedPattern *pp)
253 if(pp->pct[0].tt == PCT_STRING) {
255 // just check first letter for now
257 if(toupper(*pp->pct[0].tok.s) == 'F')
260 } else if (pp->pct[0].tt == PCT_NUMBER) {
270 /*-----------------------------------------------------------------*/
271 /* pCodeOp *cvt_extract_status(char *reg, char *bit) */
272 /* if *reg is the "status" register and *bit is one of the */
273 /* status bits, then this function will create a new pCode op */
274 /* containing the status register. */
275 /*-----------------------------------------------------------------*/
277 static pCodeOp *cvt_extract_status(char *reg, char *bit)
281 if(STRCASECMP(reg, pc_status.pcop.name))
288 if(toupper(*bit) == 'C')
289 return PCOP(popCopyGPR2Bit(&pc_status,PIC_C_BIT));
290 if(toupper(*bit) == 'Z')
291 return PCOP(popCopyGPR2Bit(&pc_status,PIC_Z_BIT));
295 if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C')
296 return PCOP(popCopyGPR2Bit(&pc_status,PIC_DC_BIT));
302 /*-----------------------------------------------------------------*/
303 /* cvt_altpat_label - convert assembly line type to a pCode label */
304 /* INPUT: pointer to the parsedPattern */
308 /* label pattern => '%' number ':' */
309 /* at this point, we wish to extract only the 'number' */
311 /*-----------------------------------------------------------------*/
312 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
314 parsedPattern *p = pp;
316 DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
317 return newpCodeLabel(NULL,-p->pct[1].tok.n);
321 /*-----------------------------------------------------------------*/
322 /* cvt_altpat_comment - convert assembly line type to a comment */
323 /* INPUT: pointer to the parsedPattern */
325 /* pp[0] - comment */
328 /*-----------------------------------------------------------------*/
329 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
331 parsedPattern *p = pp;
333 DFPRINTF((stderr,"altpat_comment = %s\n",p->pct[0].tok.s));
334 return newpCodeCharP(p->pct[0].tok.s);
338 /*-----------------------------------------------------------------*/
339 /* cvt_altpat_mem0 - convert assembly line type to a wild pCode */
344 /*-----------------------------------------------------------------*/
345 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
347 parsedPattern *p = pp;
350 pCodeInstruction *pci=NULL;
352 DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s));
354 opcode = getpCode(p->pct[0].tok.s,0);
357 /* look for special command strings like _NOTBITSKIP_ */
359 //fprintf(stderr, "Bad mnemonic\n");
361 opcode = getpCodePeepCommand(p->pct[0].tok.s);
363 // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
367 pci = PCI(newpCode(opcode, NULL));
370 fprintf(stderr,"couldn't find mnemonic\n");
376 /*-----------------------------------------------------------------*/
377 /* cvt_altpat_mem0a - convert assembly line type to a wild pCode */
380 /* pp[0] - wild var */
382 /*-----------------------------------------------------------------*/
383 static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
385 parsedPattern *p = pp;
387 DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n));
389 /* Save the index of the maximum wildcard mnemonic */
391 //if(p[0].pct[1].tok.n > sMaxWildVar)
392 // sMaxWildMnem = p[0].pct[1].tok.n;
394 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
395 pcwb->nwildpCodes = p[0].pct[1].tok.n;
397 return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
401 /*-----------------------------------------------------------------*/
402 /* cvt_altpat_mem1 - convert assembly line type to a pCode */
403 /* instruction with 1 operand. */
406 /* pp[1] - Operand */
408 /*-----------------------------------------------------------------*/
409 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
412 parsedPattern *p = pp;
415 pCodeInstruction *pci=NULL;
418 DFPRINTF((stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s));
420 opcode = getpCode(p->pct[0].tok.s,0);
422 //fprintf(stderr, "Bad mnemonic\n");
423 opcode = getpCodePeepCommand(p->pct[0].tok.s);
425 //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
430 if(pic14Mnemonics[opcode]->isBitInst)
431 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
433 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
436 pci = PCI(newpCode(opcode, pcosubtype));
439 fprintf(stderr,"couldn't find mnemonic\n");
445 /*-----------------------------------------------------------------*/
446 /* cvt_altpat_mem1a - convert assembly line type to a pCode */
447 /* instruction with 1 wild operand. */
450 /* pp[1] - wild var */
452 /*-----------------------------------------------------------------*/
453 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
455 parsedPattern *p = pp;
458 pCodeInstruction *pci=NULL;
461 DFPRINTF((stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n));
463 opcode = getpCode(p->pct[0].tok.s,0);
465 int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
469 fprintf(stderr, "Bad mnemonic\n");
473 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
474 pcwb->nwildpCodes = p[0].pct[1].tok.n;
476 pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
480 PCW(pc)->mustNotBeBitSkipInst = 1;
483 PCW(pc)->mustBeBitSkipInst = 1;
486 PCW(pc)->invertBitSkipInst = 1;
491 if(pic14Mnemonics[opcode]->isBitInst)
492 pcosubtype = newpCodeOpBit(NULL,-1,0);
494 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
497 pci = PCI(newpCode(opcode,
498 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
500 /* Save the index of the maximum wildcard variable */
501 //if(p[1].pct[1].tok.n > sMaxWildVar)
502 // sMaxWildVar = p[1].pct[1].tok.n;
504 if(p[1].pct[1].tok.n > pcwb->nvars)
505 pcwb->nvars = p[1].pct[1].tok.n;
508 fprintf(stderr,"couldn't find mnemonic\n");
514 /*-----------------------------------------------------------------*/
515 /*-----------------------------------------------------------------*/
516 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
518 parsedPattern *p = pp;
521 pCodeInstruction *pci=NULL;
523 DFPRINTF((stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n));
525 opcode = getpCode(p->pct[0].tok.s,0);
527 fprintf(stderr, "Bad mnemonic\n");
531 pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
534 fprintf(stderr,"couldn't find mnemonic\n");
540 /*-----------------------------------------------------------------*/
541 /*-----------------------------------------------------------------*/
542 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
544 parsedPattern *p = pp;
548 pCodeInstruction *pci=NULL;
551 dest = cvt_extract_destination(&p[3]);
553 DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
560 opcode = getpCode(p->pct[0].tok.s,dest);
562 fprintf(stderr, "Bad mnemonic\n");
566 if(pic14Mnemonics[opcode]->isBitInst) {
567 pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
568 if(pcosubtype == NULL) {
569 fprintf(stderr, "bad operand?\n");
574 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
577 pci = PCI(newpCode(opcode,pcosubtype));
580 fprintf(stderr,"couldn't find mnemonic\n");
586 /*-----------------------------------------------------------------*/
587 /* cvt_altpat_mem2a - convert assembly line type to a pCode */
588 /* instruction with 1 wild operand and a */
589 /* destination operand (e.g. w or f) */
592 /* pp[1] - wild var */
594 /* pp[3] - destination */
596 /*-----------------------------------------------------------------*/
597 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
599 parsedPattern *p = pp;
603 pCodeInstruction *pci=NULL;
606 dest = cvt_extract_destination(&p[3]);
608 DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
615 opcode = getpCode(p->pct[0].tok.s,dest);
617 fprintf(stderr, "Bad mnemonic\n");
621 if(pic14Mnemonics[opcode]->isBitInst)
622 pcosubtype = newpCodeOp(NULL,PO_BIT);
624 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
627 pci = PCI(newpCode(opcode,
628 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
630 /* Save the index of the maximum wildcard variable */
631 //if(p[1].pct[1].tok.n > sMaxWildVar)
632 // sMaxWildVar = p[1].pct[1].tok.n;
634 if(p[1].pct[1].tok.n > pcwb->nvars)
635 pcwb->nvars = p[1].pct[1].tok.n;
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 // add a SPACE token and eat the extra spaces.
674 tokArr[tokIdx++].tt = PCT_SPACE;
675 while (isspace (*ln))
682 tokArr[tokIdx].tt = PCT_NUMBER;
683 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
691 tokArr[tokIdx++].tt = PCT_PERCENT;
694 tokArr[tokIdx++].tt = PCT_LESSTHAN;
697 tokArr[tokIdx++].tt = PCT_GREATERTHAN;
700 tokArr[tokIdx++].tt = PCT_COLON;
703 tokArr[tokIdx].tok.s = Safe_strdup(ln);
704 tokArr[tokIdx++].tt = PCT_COMMENT;
705 tokArr[tokIdx].tt = PCT_NULL;
708 tokArr[tokIdx++].tt = PCT_COMMA;
713 if(isalpha(*ln) || (*ln == '_') ) {
717 while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
723 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
724 tokArr[tokIdx++].tt = PCT_STRING;
729 /* Advance to next character in input string .
730 * Note, if none of the tests passed above, then
731 * we effectively ignore the `bad' character.
732 * Since the line has already been parsed by SDCCpeeph,
733 * chance are that there are no invalid characters... */
739 tokArr[tokIdx].tt = 0;
743 /*-----------------------------------------------------------------*/
744 /*-----------------------------------------------------------------*/
748 void dump1Token(pCodeTokens tt)
753 fprintf(stderr, " space ");
756 fprintf(stderr, " pct %%");
759 fprintf(stderr, " pct <");
761 case PCT_GREATERTHAN:
762 fprintf(stderr, " pct >");
765 fprintf(stderr, " col :");
768 fprintf(stderr, " comma , ");
771 fprintf(stderr, " comment ");
772 //fprintf(stderr,"%s",tokArr[i].tok.s);
775 fprintf(stderr, " str ");
776 //fprintf(stderr,"%s",tokArr[i].tok.s);
779 fprintf(stderr, " num ");
780 //fprintf(stderr,"%d",tokArr[i].tok.n);
783 fprintf(stderr, " null ");
790 /*-----------------------------------------------------------------*/
791 /*-----------------------------------------------------------------*/
793 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
797 if(!pct || !pat || !*pat)
800 //DFPRINTF((stderr,"comparing against:\n"));
802 while(i < max_tokens) {
805 //DFPRINTF((stderr,"matched\n"));
809 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
823 /*-----------------------------------------------------------------*/
824 /*-----------------------------------------------------------------*/
826 int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
830 if(!pct || !pat || !*pct)
834 while(i < max_tokens) {
837 //DFPRINTF((stderr,"matched\n"));
841 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
843 if( !pat || !pat->pcp )
846 if (pat->pcp->pt != *pct)
849 //DFPRINTF((stderr," pct=%d\n",*pct));
858 /*-----------------------------------------------------------------*/
859 /*-----------------------------------------------------------------*/
861 int advTokIdx(int *v, int amt)
864 if((unsigned) (*v + amt) > tokIdx)
872 /*-----------------------------------------------------------------*/
873 /* parseTokens - convert the tokens corresponding to a single line */
874 /* of a peep hole assembly into a pCode object. */
879 /* This is a simple parser that looks for strings of the type */
880 /* allowed in the peep hole definition file. Essentially the format*/
881 /* is the same as a line of assembly: */
883 /* label: mnemonic op1, op2, op3 ; comment */
885 /* Some of these items aren't present. It's the job of the parser */
886 /* to determine which are and convert those into the appropriate */
888 /*-----------------------------------------------------------------*/
890 void parseTokens(pCodeWildBlock *pcwb)
898 for(i=0; i<=tokIdx; i++)
899 dump1Token(tokArr[i].tt);
911 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
912 char * cP1stop = NULL;
913 char * cP2ndop = NULL;
915 //pCodeOp *pcl = NULL; // Storage for a label
916 //pCodeOp *pco1 = NULL; // 1st operand
917 //pCodeOp *pco2 = NULL; // 2nd operand
918 //pCode *pc = NULL; // Mnemonic
929 ParseStates state = PS_START;
936 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
937 && (advTokIdx(<okIdx, 1)) ) // eat space
941 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
944 switch(pcpArr[lpcpIdx].pt) {
946 if(state == PS_START){
947 DFPRINTF((stderr," label\n"));
948 state = PS_HAVE_LABEL;
950 DFPRINTF((stderr," bad state (%d) for label\n",state));
954 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
958 DFPRINTF((stderr," mnem\n"));
959 cPmnem = tokArr[ltokIdx].tok.s;
960 state = PS_HAVE_MNEM;
963 DFPRINTF((stderr," 1st operand\n"));
964 cP1stop = tokArr[ltokIdx].tok.s;
965 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
966 state = PS_HAVE_1OPERAND;
968 case PS_HAVE_1OPERAND:
969 DFPRINTF((stderr," error expecting comma\n"));
972 DFPRINTF((stderr," 2 operands\n"));
973 cP2ndop = tokArr[ltokIdx].tok.s;
975 case PS_HAVE_2OPERANDS:
984 DFPRINTF((stderr," wild mnem\n"));
985 state = PS_HAVE_MNEM;
988 DFPRINTF((stderr," 1st operand is wild\n"));
989 state = PS_HAVE_1OPERAND;
991 case PS_HAVE_1OPERAND:
992 DFPRINTF((stderr," error expecting comma\n"));
995 DFPRINTF((stderr," 2nd operand is wild\n"));
997 case PS_HAVE_2OPERANDS:
1006 fprintf(stderr," ERROR number\n");
1009 DFPRINTF((stderr," 1st operand is a number\n"));
1010 state = PS_HAVE_1OPERAND;
1012 case PS_HAVE_1OPERAND:
1013 fprintf(stderr," error expecting comma\n");
1016 DFPRINTF((stderr," 2nd operand is a number\n"));
1018 case PS_HAVE_2OPERANDS:
1026 if(state == PS_HAVE_1OPERAND){
1027 DFPRINTF((stderr," got a comma\n"));
1028 state = PS_HAVE_COMMA;
1030 fprintf(stderr," unexpected comma\n");
1034 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1035 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1038 //dump1Token(tokArr[ltokIdx].tt);
1040 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1041 DFPRINTF((stderr," reached end \n"));
1048 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1052 parsedPatArr[lparsedPatIdx].pcp = NULL;
1053 parsedPatArr[lparsedPatIdx].pct = NULL;
1059 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1062 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1063 //if(pc && pc->print)
1064 // pc->print(stderr,pc);
1065 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1067 //if(curBlock && pc)
1068 //addpCode2pBlock(curBlock, pc);
1069 addpCode2pBlock(pcwb->pb, pc);
1075 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1078 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1082 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1083 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1084 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1087 while(j<lparsedPatIdx);
1089 DFPRINTF((stderr,"\n"));
1096 /*-----------------------------------------------------------------*/
1098 /*-----------------------------------------------------------------*/
1099 void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
1105 for( ; ln; ln = ln->next) {
1107 //DFPRINTF((stderr,"%s\n",ln->line));
1109 tokenizeLineNode(ln->line);
1115 /*-----------------------------------------------------------------*/
1116 /* peepRuleCondition */
1117 /*-----------------------------------------------------------------*/
1118 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1123 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1124 /* brute force compares for now */
1126 if(STRCASECMP(cond, "NZ") == 0) {
1127 //DFPRINTF((stderr,"found NZ\n"));
1128 pcp->postFalseCond = PCC_Z;
1135 void initpCodeWildBlock(pCodeWildBlock *pcwb)
1138 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1144 pcwb->wildpCodes = NULL;
1145 pcwb->wildpCodeOps = NULL;
1148 pcwb->nwildpCodes = 0;
1153 void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1160 pcwb->nops = pcwb->nvars;
1162 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1163 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1165 pcwb->nwildpCodes+=2;
1166 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1170 void initpCodePeep(pCodePeep *pcp)
1173 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1178 initpCodeWildBlock(&pcp->target);
1179 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1181 initpCodeWildBlock(&pcp->replace);
1182 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1186 /*-----------------------------------------------------------------*/
1187 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1190 /* SDCCpeeph parses the peep rules file and extracts variables, */
1191 /* removes white space, and checks the syntax. This function */
1192 /* extends that processing to produce pCode objects. You can kind */
1193 /* think of this function as an "assembler", though instead of */
1194 /* taking raw text to produce machine code, it produces pCode. */
1196 /*-----------------------------------------------------------------*/
1197 extern void pic14initpCodePeepCommands(void);
1199 void peepRules2pCode(peepRule *rules)
1203 pCodePeep *currentRule;
1204 pCodePeepSnippets *pcps;
1206 pic14initpCodePeepCommands();
1208 /* The rules are in a linked-list. Each rule has two portions */
1209 /* There's the `target' and there's the `replace'. The target */
1210 /* is compared against the SDCC generated code and if it */
1211 /* matches, it gets replaced by the `replace' block of code. */
1213 /* Here we loop through each rule and convert the target's and*/
1214 /* replace's into pCode target and replace blocks */
1216 for (pr = rules; pr; pr = pr->next) {
1218 //DFPRINTF((stderr,"\nRule:\n\n"));
1220 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1221 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1223 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1224 initpCodePeep(currentRule);
1226 /* Convert the target block */
1227 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1229 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1230 //printpBlock(stderr, curBlock);
1232 //DFPRINTF((stderr,"target with labels merged:\n"));
1233 //pBlockMergeLabels(curBlock);
1234 pBlockMergeLabels(currentRule->target.pb);
1235 //printpBlock(stderr, currentRule->replace.pb);
1237 //#ifdef PCODE_DEBUG
1238 // printpBlock(stderr, curBlock);
1240 //DFPRINTF((stderr,"\nReplaced by:\n"));
1243 /* Convert the replace block */
1244 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1246 //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
1247 //printpBlock(stderr, curBlock);
1249 //DFPRINTF((stderr,"replace with labels merged:\n"));
1251 pBlockMergeLabels(currentRule->replace.pb);
1252 //printpBlock(stderr, currentRule->replace.pb);
1254 peepRuleCondition(pr->cond,currentRule);
1256 /* The rule has been converted to pCode. Now allocate
1257 * space for the wildcards */
1259 postinit_pCodeWildBlock(¤tRule->target);
1260 postinit_pCodeWildBlock(¤tRule->replace);
1262 //return; // debug ... don't want to go through all the rules yet
1266 pCodePeep *peepBlock;
1269 peeprules = (_DLL *)peepSnippets;
1270 //fprintf(stderr,"target rules\n");
1272 //fprintf(stderr," rule:\n");
1273 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1274 //printpBlock(stderr, peepBlock->target.pb);
1275 peeprules = peeprules->next;
1277 //fprintf(stderr," ... done\n");
1282 void printpCodeString(FILE *of, pCode *pc, int max)
1286 while(pc && (i++<max)) {
1292 /*-----------------------------------------------------------------*/
1293 /* _DLL * DLL_append */
1295 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1296 /* If The list to which we want to append is non-existant then one */
1297 /* is created. Other wise, the end of the list is sought out and */
1298 /* a new DLL object is appended to it. In either case, the void */
1299 /* *data is added to the newly created DLL object. */
1300 /*-----------------------------------------------------------------*/
1302 static void * DLL_append(_DLL *list, _DLL *next)
1307 /* If there's no list, then create one: */
1309 next->next = next->prev = NULL;
1314 /* Search for the end of the list. */
1319 /* Now append the new DLL object */
1330 /*-----------------------------------------------------------------
1332 pCode peephole optimization
1335 The pCode "peep hole" optimization is not too unlike the peep hole
1336 optimization in SDCCpeeph.c. The major difference is that here we
1337 use pCode's whereas there we use ASCII strings. The advantage with
1338 pCode's is that we can ascertain flow information in the instructions
1342 <FIX ME> - elaborate...
1344 -----------------------------------------------------------------*/
1348 /*-----------------------------------------------------------------*/
1349 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1351 /* return conditions */
1352 /* 1 - The Condition was found for a pCode's input */
1353 /* 0 - No matching condition was found for the whole chain */
1354 /* -1 - The Condition was found for a pCode's output */
1356 /*-----------------------------------------------------------------*/
1357 int pCodeSearchCondition(pCode *pc, unsigned int cond)
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 //fprintf(stderr," checking conditions of: ");
1370 //pc->print(stderr,pc);
1371 if(PCI(pc)->inCond & cond)
1373 if(PCI(pc)->outCond & cond)
1383 /*-----------------------------------------------------------------
1384 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1386 * Compare two pCodeOp's and return 1 if they're the same
1387 *-----------------------------------------------------------------*/
1388 int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1392 if(!pcops || !pcopd)
1395 fprintf(stderr," Comparing operands %s",
1396 get_op( pcops,NULL,0));
1398 fprintf(stderr," to %s\n",
1399 get_op( pcopd,NULL,0));
1402 if(pcops->type != pcopd->type) {
1403 //fprintf(stderr," - fail - diff types\n");
1404 return 0; // different types
1408 get_op(pcops,b,sizeof(b));
1409 n2 = get_op(pcopd,NULL,0);
1411 if( !n2 || strcmp(b,n2)) {
1412 //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
1413 return 0; // different names
1416 switch(pcops->type) {
1418 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1419 //fprintf(stderr, " - fail different instances\n");
1427 // fprintf(stderr," - pass\n");
1432 int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1436 /* Check for a label associated with this wild pCode */
1437 // If the wild card has a label, make sure the source code does too.
1438 if(PCI(pcd)->label) {
1439 pCode *pcl = PCI(pcd)->label->pc;
1442 int li = -PCL(pcl)->key;
1444 if(peepBlock->target.vars[li] == NULL) {
1445 if(PCI(pcs)->label) {
1446 DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
1449 // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
1450 DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
1451 if(PCI(pcs)->label) {
1452 DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
1458 if(!PCI(pcs)->label)
1461 labindex = -PCL(pcl)->key;
1462 if(peepBlock->target.vars[labindex] == NULL) {
1463 // First time to encounter this label
1464 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1465 DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
1468 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1469 DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
1472 DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
1475 //DFPRINTF((stderr,"destination doesn't have a label\n"));
1480 //DFPRINTF((stderr,"neither src nor dest have labels\n"));
1488 /*-----------------------------------------------------------------*/
1489 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1490 /* see they're the same. */
1492 /* In this context, "source" refers to the coded generated by gen.c*/
1493 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1494 /* ination has no wild cards, then MatchLine will compare the two */
1495 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1496 /* has wildcards, then those get expanded. When a wild card is */
1497 /* encountered for the first time it autmatically is considered a */
1498 /* match and the object that matches it is referenced in the */
1499 /* variables or opcodes array (depending on the type of match). */
1503 /* *peepBlock - A pointer to the peepBlock that contains the */
1504 /* entire rule to which the destination pcode belongs*/
1505 /* *pcs - a pointer to the source pcode */
1506 /* *pcd - a pointer to the destination pcode */
1509 /* 1 - pcodes match */
1510 /* 0 - pcodes don't match */
1513 /*-----------------------------------------------------------------*/
1515 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1517 int index; // index into wild card arrays
1519 /* one-for-one match. Here the source and destination opcodes
1520 * are not wild. However, there may be a label or a wild operand */
1523 if(PCI(pcs)->label) {
1524 DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
1528 if(pcs->type == pcd->type) {
1530 if(pcs->type == PC_OPCODE) {
1532 /* If the opcodes don't match then the line doesn't match */
1533 if(PCI(pcs)->op != PCI(pcd)->op)
1537 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1538 pcs->print(stderr,pcs);
1539 pcd->print(stderr,pcd);
1542 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1545 /* Compare the operands */
1546 if(PCI(pcd)->pcop) {
1547 if (PCI(pcd)->pcop->type == PO_WILD) {
1548 index = PCOW(PCI(pcd)->pcop)->id;
1550 //DFPRINTF((stderr,"destination is wild\n"));
1551 #ifdef DEBUG_PCODEPEEP
1552 if (index > peepBlock->nops) {
1553 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1558 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1559 if(!peepBlock->target.wildpCodeOps[index]) {
1560 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1562 //if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
1566 pcs->print(stderr,pcs);
1567 pcd->print(stderr,pcd);
1569 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1570 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1574 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1580 switch(PCI(pcs)->pcop->type) {
1584 n = PCOR(PCI(pcs)->pcop)->r->name;
1588 n = PCI(pcs)->pcop->name;
1591 if(peepBlock->target.vars[index])
1592 return (strcmp(peepBlock->target.vars[index],n) == 0);
1594 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1595 peepBlock->target.vars[index] = n;
1601 /* FIXME - need an else to check the case when the destination
1602 * isn't a wild card */
1604 /* The pcd has no operand. Lines match if pcs has no operand either*/
1605 return (PCI(pcs)->pcop == NULL);
1609 /* Compare a wild instruction to a regular one. */
1611 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1614 index = PCW(pcd)->id;
1616 DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1617 pcs->print(stderr,pcs);
1618 pcd->print(stderr,pcd);
1620 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1622 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
1623 DFPRINTF((stderr," Failing because labels don't match\n"));
1627 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1628 // doesn't match because the wild pcode must be a bit skip
1629 DFPRINTF((stderr," Failing match because bit skip is req\n"));
1630 //pcd->print(stderr,pcd);
1631 //pcs->print(stderr,pcs);
1635 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1636 // doesn't match because the wild pcode must *not* be a bit skip
1637 DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
1638 //pcd->print(stderr,pcd);
1639 //pcs->print(stderr,pcs);
1643 if(PCW(pcd)->operand) {
1644 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1645 if(peepBlock->target.vars[index]) {
1646 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1650 DFPRINTF((stderr," (matched)\n"));
1652 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1653 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n",
1654 peepBlock->target.vars[index],
1655 PCI(pcs)->pcop->name));
1660 DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
1661 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1666 pcs = findNextInstruction(pcs->next);
1668 //DFPRINTF((stderr," (next to match)\n"));
1669 //pcs->print(stderr,pcs);
1670 } else if(pcd->next) {
1671 /* oops, we ran out of code, but there's more to the rule */
1675 return 1; /* wild card matches */
1681 /*-----------------------------------------------------------------*/
1682 /*-----------------------------------------------------------------*/
1683 void pCodePeepClrVars(pCodePeep *pcp)
1690 DFPRINTF((stderr," Clearing peep rule vars\n"));
1691 DFPRINTF((stderr," %d %d %d %d %d %d\n",
1692 pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
1693 pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
1695 for(i=0;i<pcp->target.nvars; i++)
1696 pcp->target.vars[i] = NULL;
1697 for(i=0;i<pcp->target.nops; i++)
1698 pcp->target.wildpCodeOps[i] = NULL;
1699 for(i=0;i<pcp->target.nwildpCodes; i++)
1700 pcp->target.wildpCodes[i] = NULL;
1702 for(i=0;i<pcp->replace.nvars; i++)
1703 pcp->replace.vars[i] = NULL;
1704 for(i=0;i<pcp->replace.nops; i++)
1705 pcp->replace.wildpCodeOps[i] = NULL;
1706 for(i=0;i<pcp->replace.nwildpCodes; i++)
1707 pcp->replace.wildpCodes[i] = NULL;
1713 /*-----------------------------------------------------------------*/
1714 /* pCodeInsertAfter - splice in the pCode chain starting with pc2 */
1715 /* into the pCode chain containing pc1 */
1716 /*-----------------------------------------------------------------*/
1717 void pCodeInsertAfter(pCode *pc1, pCode *pc2)
1723 pc2->next = pc1->next;
1725 pc1->next->prev = pc2;
1733 /*-----------------------------------------------------------------*/
1734 /* pCodeOpCopy - copy a pcode operator */
1735 /*-----------------------------------------------------------------*/
1736 pCodeOp *pCodeOpCopy(pCodeOp *pcop)
1738 pCodeOp *pcopnew=NULL;
1743 switch(pcop->type) {
1746 //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
1747 pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1748 PCORB(pcopnew)->bit = PCORB(pcop)->bit;
1749 PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
1754 /* Here we expand the wild card into the appropriate type: */
1755 /* By recursively calling pCodeOpCopy */
1756 //DFPRINTF((stderr,"pCodeOpCopy wild\n"));
1757 if(PCOW(pcop)->matched)
1758 pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
1761 pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
1762 pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
1763 //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
1770 //DFPRINTF((stderr,"pCodeOpCopy label\n"));
1771 pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
1772 PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
1776 pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
1777 PCOI(pcopnew)->index = PCOI(pcop)->index;
1778 PCOI(pcopnew)->offset = PCOI(pcop)->offset;
1779 PCOI(pcopnew)->_const = PCOI(pcop)->_const;
1783 //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
1784 pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
1785 PCOL(pcopnew)->lit = PCOL(pcop)->lit;
1790 pcopnew = newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
1791 PCOR(pcopnew)->r = PCOR(pcop)->r;
1792 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1793 DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
1797 case PO_GPR_REGISTER:
1801 //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
1802 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1803 PCOR(pcopnew)->r = PCOR(pcop)->r;
1804 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1805 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1806 DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
1810 //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
1811 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1812 PCOR(pcopnew)->r = PCOR(pcop)->r;
1813 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1814 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1817 DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
1818 case PO_SFR_REGISTER:
1826 //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
1827 pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
1831 pcopnew->type = pcop->type;
1833 pcopnew->name = Safe_strdup(pcop->name);
1835 pcopnew->name = NULL;
1841 /*-----------------------------------------------------------------*/
1842 /* pCodeCopy - copy a pcode */
1843 /*-----------------------------------------------------------------*/
1844 static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert)
1846 pCodeInstruction *new_pci;
1849 new_pci = PCI(newpCode(pci->inverted_op,pci->pcop));
1851 new_pci = PCI(newpCode(pci->op,pci->pcop));
1853 new_pci->pc.pb = pci->pc.pb;
1854 new_pci->from = pci->from;
1855 new_pci->to = pci->to;
1856 new_pci->label = pci->label;
1857 new_pci->pcflow = pci->pcflow;
1859 return PCODE(new_pci);
1862 /*-----------------------------------------------------------------*/
1863 /*-----------------------------------------------------------------*/
1864 void pCodeDeleteChain(pCode *f,pCode *t)
1870 DFPRINTF((stderr,"delete pCode:\n"));
1872 //f->print(stderr,f);
1873 //f->delete(f); this dumps core...
1880 /*-----------------------------------------------------------------*/
1881 /*-----------------------------------------------------------------*/
1882 int pCodePeepMatchRule(pCode *pc)
1884 pCodePeep *peepBlock;
1886 pCodeCSource *pc_cline=NULL;
1890 peeprules = (_DLL *)peepSnippets;
1893 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1895 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
1896 fprintf(stderr, "skipping rule because target pb is NULL\n");
1900 pCodePeepClrVars(peepBlock);
1903 if(IS_PCCOMMENT(pcin))
1904 pc = pcin = findNextInstruction(pcin->next);
1906 pcin = pc = findNextInstruction(pc);
1908 pct = peepBlock->target.pb->pcHead;
1911 pCode *pcr = peepBlock->replace.pb->pcHead;
1912 if(pcr) pct->print(stderr,pcr);
1916 while(pct && pcin) {
1918 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1921 pcin = findNextInstruction(pcin->next);
1924 //DFPRINTF((stderr," matched\n"));
1927 DFPRINTF((stderr," partial match... no more code\n"));
1928 fprintf(stderr," partial match... no more code\n");
1932 DFPRINTF((stderr," end of rule\n"));
1938 //pCode *pcr = peepBlock->replace.pb->pcHead;
1939 //if(pcr) pcr->print(stderr,pcr);
1941 /* So far we matched the rule up to the point of the conditions .
1942 * In other words, all of the opcodes match. Now we need to see
1943 * if the post conditions are satisfied.
1944 * First we check the 'postFalseCond'. This means that we check
1945 * to see if any of the subsequent pCode's in the pCode chain
1946 * following the point just past where we have matched depend on
1947 * the `postFalseCond' as input then we abort the match
1949 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
1950 if (pcin && peepBlock->postFalseCond &&
1951 (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
1954 if(!matched) fprintf(stderr,"failed on conditions\n");
1963 /* We matched a rule! Now we have to go through and remove the
1964 inefficient code with the optimized version */
1966 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
1967 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
1968 DFPRINTF((stderr,"first thing matched\n"));
1969 pc->print(stderr,pc);
1971 DFPRINTF((stderr,"last thing matched\n"));
1972 pcin->print(stderr,pcin);
1977 /* Unlink the original code */
1979 pcprev->next = pcin;
1981 pcin->prev = pc->prev;
1987 /* Converted the deleted pCodes into comments */
1990 pCodeCSource *pc_cline2=NULL;
1995 while(pc && pc!=pcin) {
1997 if(pc->type == PC_OPCODE && PCI(pc)->cline) {
1999 pc_cline2->pc.next = PCODE(PCI(pc)->cline);
2000 pc_cline2 = PCCS(pc_cline2->pc.next);
2002 pc_cline = pc_cline2 = PCI(pc)->cline;
2003 pc_cline->pc.seq = pc->seq;
2007 pCode2str(&buf[2], 254, pc);
2008 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
2009 pcprev = pcprev->next;
2014 pc_cline2->pc.next = NULL;
2019 pCodeDeleteChain(pc,pcin);
2021 /* Generate the replacement code */
2023 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
2027 /* If the replace pcode is an instruction with an operand, */
2028 /* then duplicate the operand (and expand wild cards in the process). */
2029 if(pcr->type == PC_OPCODE) {
2030 if(PCI(pcr)->pcop) {
2031 /* The replacing instruction has an operand.
2033 if(PCI(pcr)->pcop->type == PO_WILD) {
2034 int index = PCOW(PCI(pcr)->pcop)->id;
2035 //DFPRINTF((stderr,"copying wildopcode\n"));
2036 if(peepBlock->target.wildpCodeOps[index])
2037 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
2039 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
2041 pcop = pCodeOpCopy(PCI(pcr)->pcop);
2043 //DFPRINTF((stderr,"inserting pCode\n"));
2044 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
2045 } else if (pcr->type == PC_WILD) {
2046 if(PCW(pcr)->invertBitSkipInst)
2047 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
2048 pCodeInsertAfter(pc,
2049 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
2050 PCW(pcr)->invertBitSkipInst));
2051 } else if (pcr->type == PC_COMMENT) {
2052 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
2058 DFPRINTF((stderr," NEW Code:"));
2059 if(pc) pc->print(stderr,pc);
2064 /* We have just replaced the inefficient code with the rule.
2065 * Now, we need to re-add the C-source symbols if there are any */
2069 pc = findNextInstruction(pc->next);
2070 PCI(pc)->cline = pc_cline;
2071 pc_cline = PCCS(pc_cline->pc.next);
2078 peeprules = peeprules->next;
2080 DFPRINTF((stderr," no rule matched\n"));