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.
674 // add a SPACE token and eat the extra spaces.
675 tokArr[tokIdx++].tt = PCT_SPACE;
676 while (isspace (*ln))
683 tokArr[tokIdx].tt = PCT_NUMBER;
684 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
692 tokArr[tokIdx++].tt = PCT_PERCENT;
695 tokArr[tokIdx++].tt = PCT_LESSTHAN;
698 tokArr[tokIdx++].tt = PCT_GREATERTHAN;
701 tokArr[tokIdx++].tt = PCT_COLON;
704 tokArr[tokIdx].tok.s = Safe_strdup(ln);
705 tokArr[tokIdx++].tt = PCT_COMMENT;
706 tokArr[tokIdx].tt = PCT_NULL;
709 tokArr[tokIdx++].tt = PCT_COMMA;
714 if(isalpha(*ln) || (*ln == '_') ) {
718 while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
724 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
725 tokArr[tokIdx++].tt = PCT_STRING;
728 fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
729 fprintf(stderr, "Line: %s\n",lnstart);
730 fprintf(stderr, "Token: '%c'\n",*ln);
735 /* Advance to next character in input string .
736 * Note, if none of the tests passed above, then
737 * we effectively ignore the `bad' character.
738 * Since the line has already been parsed by SDCCpeeph,
739 * chance are that there are no invalid characters... */
745 tokArr[tokIdx].tt = 0;
749 /*-----------------------------------------------------------------*/
750 /*-----------------------------------------------------------------*/
754 void dump1Token(pCodeTokens tt)
759 fprintf(stderr, " space ");
762 fprintf(stderr, " pct %%");
765 fprintf(stderr, " pct <");
767 case PCT_GREATERTHAN:
768 fprintf(stderr, " pct >");
771 fprintf(stderr, " col :");
774 fprintf(stderr, " comma , ");
777 fprintf(stderr, " comment ");
778 //fprintf(stderr,"%s",tokArr[i].tok.s);
781 fprintf(stderr, " str ");
782 //fprintf(stderr,"%s",tokArr[i].tok.s);
785 fprintf(stderr, " num ");
786 //fprintf(stderr,"%d",tokArr[i].tok.n);
789 fprintf(stderr, " null ");
796 /*-----------------------------------------------------------------*/
797 /*-----------------------------------------------------------------*/
799 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
803 if(!pct || !pat || !*pat)
806 //DFPRINTF((stderr,"comparing against:\n"));
808 while(i < max_tokens) {
811 //DFPRINTF((stderr,"matched\n"));
815 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
829 /*-----------------------------------------------------------------*/
830 /*-----------------------------------------------------------------*/
832 int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
836 if(!pct || !pat || !*pct)
840 while(i < max_tokens) {
843 //DFPRINTF((stderr,"matched\n"));
847 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
849 if( !pat || !pat->pcp )
852 if (pat->pcp->pt != *pct)
855 //DFPRINTF((stderr," pct=%d\n",*pct));
864 /*-----------------------------------------------------------------*/
865 /*-----------------------------------------------------------------*/
867 int advTokIdx(int *v, int amt)
870 if((unsigned) (*v + amt) > tokIdx)
878 /*-----------------------------------------------------------------*/
879 /* parseTokens - convert the tokens corresponding to a single line */
880 /* of a peep hole assembly into a pCode object. */
885 /* This is a simple parser that looks for strings of the type */
886 /* allowed in the peep hole definition file. Essentially the format*/
887 /* is the same as a line of assembly: */
889 /* label: mnemonic op1, op2, op3 ; comment */
891 /* Some of these items aren't present. It's the job of the parser */
892 /* to determine which are and convert those into the appropriate */
894 /*-----------------------------------------------------------------*/
896 void parseTokens(pCodeWildBlock *pcwb)
904 for(i=0; i<=tokIdx; i++)
905 dump1Token(tokArr[i].tt);
917 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
918 char * cP1stop = NULL;
919 char * cP2ndop = NULL;
921 //pCodeOp *pcl = NULL; // Storage for a label
922 //pCodeOp *pco1 = NULL; // 1st operand
923 //pCodeOp *pco2 = NULL; // 2nd operand
924 //pCode *pc = NULL; // Mnemonic
935 ParseStates state = PS_START;
942 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
943 && (advTokIdx(<okIdx, 1)) ) // eat space
947 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
950 switch(pcpArr[lpcpIdx].pt) {
952 if(state == PS_START){
953 DFPRINTF((stderr," label\n"));
954 state = PS_HAVE_LABEL;
956 DFPRINTF((stderr," bad state (%d) for label\n",state));
960 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
964 DFPRINTF((stderr," mnem\n"));
965 cPmnem = tokArr[ltokIdx].tok.s;
966 state = PS_HAVE_MNEM;
969 DFPRINTF((stderr," 1st operand\n"));
970 cP1stop = tokArr[ltokIdx].tok.s;
971 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
972 state = PS_HAVE_1OPERAND;
974 case PS_HAVE_1OPERAND:
975 DFPRINTF((stderr," error expecting comma\n"));
978 DFPRINTF((stderr," 2 operands\n"));
979 cP2ndop = tokArr[ltokIdx].tok.s;
981 case PS_HAVE_2OPERANDS:
990 DFPRINTF((stderr," wild mnem\n"));
991 state = PS_HAVE_MNEM;
994 DFPRINTF((stderr," 1st operand is wild\n"));
995 state = PS_HAVE_1OPERAND;
997 case PS_HAVE_1OPERAND:
998 DFPRINTF((stderr," error expecting comma\n"));
1001 DFPRINTF((stderr," 2nd operand is wild\n"));
1003 case PS_HAVE_2OPERANDS:
1012 fprintf(stderr," ERROR number\n");
1015 DFPRINTF((stderr," 1st operand is a number\n"));
1016 state = PS_HAVE_1OPERAND;
1018 case PS_HAVE_1OPERAND:
1019 fprintf(stderr," error expecting comma\n");
1022 DFPRINTF((stderr," 2nd operand is a number\n"));
1024 case PS_HAVE_2OPERANDS:
1032 if(state == PS_HAVE_1OPERAND){
1033 DFPRINTF((stderr," got a comma\n"));
1034 state = PS_HAVE_COMMA;
1036 fprintf(stderr," unexpected comma\n");
1042 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1043 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1046 //dump1Token(tokArr[ltokIdx].tt);
1048 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1049 DFPRINTF((stderr," reached end \n"));
1056 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1060 parsedPatArr[lparsedPatIdx].pcp = NULL;
1061 parsedPatArr[lparsedPatIdx].pct = NULL;
1067 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1070 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1071 //if(pc && pc->print)
1072 // pc->print(stderr,pc);
1073 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1075 //if(curBlock && pc)
1076 //addpCode2pBlock(curBlock, pc);
1077 addpCode2pBlock(pcwb->pb, pc);
1083 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1086 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1090 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1091 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1092 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1095 while(j<lparsedPatIdx);
1097 DFPRINTF((stderr,"\n"));
1104 /*-----------------------------------------------------------------*/
1106 /*-----------------------------------------------------------------*/
1107 void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
1113 for( ; ln; ln = ln->next) {
1115 //DFPRINTF((stderr,"%s\n",ln->line));
1117 tokenizeLineNode(ln->line);
1123 /*-----------------------------------------------------------------*/
1124 /* peepRuleCondition */
1125 /*-----------------------------------------------------------------*/
1126 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1131 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1132 /* brute force compares for now */
1134 if(STRCASECMP(cond, "NZ") == 0) {
1135 //DFPRINTF((stderr,"found NZ\n"));
1136 pcp->postFalseCond = PCC_Z;
1143 void initpCodeWildBlock(pCodeWildBlock *pcwb)
1146 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1152 pcwb->wildpCodes = NULL;
1153 pcwb->wildpCodeOps = NULL;
1156 pcwb->nwildpCodes = 0;
1161 void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1168 pcwb->nops = pcwb->nvars;
1170 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1171 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1173 pcwb->nwildpCodes+=2;
1174 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1178 void initpCodePeep(pCodePeep *pcp)
1181 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1186 initpCodeWildBlock(&pcp->target);
1187 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1189 initpCodeWildBlock(&pcp->replace);
1190 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1194 /*-----------------------------------------------------------------*/
1195 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1198 /* SDCCpeeph parses the peep rules file and extracts variables, */
1199 /* removes white space, and checks the syntax. This function */
1200 /* extends that processing to produce pCode objects. You can kind */
1201 /* think of this function as an "assembler", though instead of */
1202 /* taking raw text to produce machine code, it produces pCode. */
1204 /*-----------------------------------------------------------------*/
1205 extern void pic14initpCodePeepCommands(void);
1207 void peepRules2pCode(peepRule *rules)
1211 pCodePeep *currentRule;
1212 pCodePeepSnippets *pcps;
1214 pic14initpCodePeepCommands();
1216 /* The rules are in a linked-list. Each rule has two portions */
1217 /* There's the `target' and there's the `replace'. The target */
1218 /* is compared against the SDCC generated code and if it */
1219 /* matches, it gets replaced by the `replace' block of code. */
1221 /* Here we loop through each rule and convert the target's and*/
1222 /* replace's into pCode target and replace blocks */
1224 for (pr = rules; pr; pr = pr->next) {
1226 //DFPRINTF((stderr,"\nRule:\n\n"));
1228 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1229 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1231 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1232 initpCodePeep(currentRule);
1234 /* Convert the target block */
1235 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1237 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1238 //printpBlock(stderr, currentRule->target.pb);
1240 //DFPRINTF((stderr,"target with labels merged:\n"));
1241 //pBlockMergeLabels(curBlock);
1242 pBlockMergeLabels(currentRule->target.pb);
1243 //printpBlock(stderr, currentRule->replace.pb);
1245 //#ifdef PCODE_DEBUG
1246 // printpBlock(stderr, curBlock);
1248 //DFPRINTF((stderr,"\nReplaced by:\n"));
1251 /* Convert the replace block */
1252 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1254 //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
1255 //printpBlock(stderr, curBlock);
1257 //DFPRINTF((stderr,"replace with labels merged:\n"));
1259 pBlockMergeLabels(currentRule->replace.pb);
1260 //printpBlock(stderr, currentRule->replace.pb);
1262 peepRuleCondition(pr->cond,currentRule);
1264 /* The rule has been converted to pCode. Now allocate
1265 * space for the wildcards */
1267 postinit_pCodeWildBlock(¤tRule->target);
1268 postinit_pCodeWildBlock(¤tRule->replace);
1270 //return; // debug ... don't want to go through all the rules yet
1274 pCodePeep *peepBlock;
1277 peeprules = (_DLL *)peepSnippets;
1278 //fprintf(stderr,"target rules\n");
1280 //fprintf(stderr," rule:\n");
1281 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1282 //printpBlock(stderr, peepBlock->target.pb);
1283 peeprules = peeprules->next;
1285 //fprintf(stderr," ... done\n");
1290 void printpCodeString(FILE *of, pCode *pc, int max)
1294 while(pc && (i++<max)) {
1300 /*-----------------------------------------------------------------*/
1301 /* _DLL * DLL_append */
1303 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1304 /* If The list to which we want to append is non-existant then one */
1305 /* is created. Other wise, the end of the list is sought out and */
1306 /* a new DLL object is appended to it. In either case, the void */
1307 /* *data is added to the newly created DLL object. */
1308 /*-----------------------------------------------------------------*/
1310 static void * DLL_append(_DLL *list, _DLL *next)
1315 /* If there's no list, then create one: */
1317 next->next = next->prev = NULL;
1322 /* Search for the end of the list. */
1327 /* Now append the new DLL object */
1338 /*-----------------------------------------------------------------
1340 pCode peephole optimization
1343 The pCode "peep hole" optimization is not too unlike the peep hole
1344 optimization in SDCCpeeph.c. The major difference is that here we
1345 use pCode's whereas there we use ASCII strings. The advantage with
1346 pCode's is that we can ascertain flow information in the instructions
1350 <FIX ME> - elaborate...
1352 -----------------------------------------------------------------*/
1356 /*-----------------------------------------------------------------*/
1357 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1359 /* return conditions */
1360 /* 1 - The Condition was found for a pCode's input */
1361 /* 0 - No matching condition was found for the whole chain */
1362 /* -1 - The Condition was found for a pCode's output */
1364 /*-----------------------------------------------------------------*/
1365 int pCodeSearchCondition(pCode *pc, unsigned int cond)
1367 //fprintf(stderr,"Checking conditions %d\n",cond);
1370 /* If we reach a function end (presumably an end since we most
1371 probably began the search in the middle of a function), then
1372 the condition was not found. */
1373 if(pc->type == PC_FUNCTION)
1376 if(pc->type == PC_OPCODE) {
1377 //fprintf(stderr," checking conditions of: ");
1378 //pc->print(stderr,pc);
1379 //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond);
1380 if(PCI(pc)->inCond & cond)
1382 if(PCI(pc)->outCond & cond)
1392 /*-----------------------------------------------------------------
1393 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1395 * Compare two pCodeOp's and return 1 if they're the same
1396 *-----------------------------------------------------------------*/
1397 int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1401 if(!pcops || !pcopd)
1404 fprintf(stderr," Comparing operands %s",
1405 get_op( pcops,NULL,0));
1407 fprintf(stderr," to %s\n",
1408 get_op( pcopd,NULL,0));
1411 if(pcops->type != pcopd->type) {
1412 //fprintf(stderr," - fail - diff types\n");
1413 return 0; // different types
1416 if(pcops->type == PO_LITERAL) {
1418 if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit))
1427 n2 = get_op(pcopd,NULL,0);
1429 if( !n2 || strcmp(b,n2)) {
1430 //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
1431 return 0; // different names
1434 switch(pcops->type) {
1436 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1437 //fprintf(stderr, " - fail different instances\n");
1445 //fprintf(stderr," - pass\n");
1450 int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1454 /* Check for a label associated with this wild pCode */
1455 // If the wild card has a label, make sure the source code does too.
1456 if(PCI(pcd)->label) {
1457 pCode *pcl = PCI(pcd)->label->pc;
1460 int li = -PCL(pcl)->key;
1462 if(peepBlock->target.vars[li] == NULL) {
1463 if(PCI(pcs)->label) {
1464 DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
1467 // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
1468 DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
1469 if(PCI(pcs)->label) {
1470 DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
1476 if(!PCI(pcs)->label)
1479 labindex = -PCL(pcl)->key;
1480 if(peepBlock->target.vars[labindex] == NULL) {
1481 // First time to encounter this label
1482 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1483 DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
1486 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1487 DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
1490 DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
1493 //DFPRINTF((stderr,"destination doesn't have a label\n"));
1498 //DFPRINTF((stderr,"neither src nor dest have labels\n"));
1506 /*-----------------------------------------------------------------*/
1507 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1508 /* see they're the same. */
1510 /* In this context, "source" refers to the coded generated by gen.c*/
1511 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1512 /* ination has no wild cards, then MatchLine will compare the two */
1513 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1514 /* has wildcards, then those get expanded. When a wild card is */
1515 /* encountered for the first time it autmatically is considered a */
1516 /* match and the object that matches it is referenced in the */
1517 /* variables or opcodes array (depending on the type of match). */
1521 /* *peepBlock - A pointer to the peepBlock that contains the */
1522 /* entire rule to which the destination pcode belongs*/
1523 /* *pcs - a pointer to the source pcode */
1524 /* *pcd - a pointer to the destination pcode */
1527 /* 1 - pcodes match */
1528 /* 0 - pcodes don't match */
1531 /*-----------------------------------------------------------------*/
1533 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1535 int index; // index into wild card arrays
1537 /* one-for-one match. Here the source and destination opcodes
1538 * are not wild. However, there may be a label or a wild operand */
1541 if(PCI(pcs)->label) {
1542 DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
1546 if(pcs->type == pcd->type) {
1548 if(pcs->type == PC_OPCODE) {
1550 /* If the opcodes don't match then the line doesn't match */
1551 if(PCI(pcs)->op != PCI(pcd)->op)
1555 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1556 pcs->print(stderr,pcs);
1557 pcd->print(stderr,pcd);
1560 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1563 /* Compare the operands */
1564 if(PCI(pcd)->pcop) {
1565 if (PCI(pcd)->pcop->type == PO_WILD) {
1566 index = PCOW(PCI(pcd)->pcop)->id;
1567 //DFPRINTF((stderr,"destination is wild\n"));
1568 #ifdef DEBUG_PCODEPEEP
1569 if (index > peepBlock->nops) {
1570 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1575 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1576 if(!peepBlock->target.wildpCodeOps[index]) {
1577 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1579 //if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
1583 pcs->print(stderr,pcs);
1584 pcd->print(stderr,pcd);
1586 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1587 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1591 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1597 switch(PCI(pcs)->pcop->type) {
1601 n = PCOR(PCI(pcs)->pcop)->r->name;
1605 n = PCI(pcs)->pcop->name;
1608 if(peepBlock->target.vars[index])
1609 return (strcmp(peepBlock->target.vars[index],n) == 0);
1611 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1612 peepBlock->target.vars[index] = n;
1617 } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
1618 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1621 /* FIXME - need an else to check the case when the destination
1622 * isn't a wild card */
1624 /* The pcd has no operand. Lines match if pcs has no operand either*/
1625 return (PCI(pcs)->pcop == NULL);
1629 /* Compare a wild instruction to a regular one. */
1631 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1633 index = PCW(pcd)->id;
1635 DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1636 pcs->print(stderr,pcs);
1637 pcd->print(stderr,pcd);
1639 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1641 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
1642 DFPRINTF((stderr," Failing because labels don't match\n"));
1646 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1647 // doesn't match because the wild pcode must be a bit skip
1648 DFPRINTF((stderr," Failing match because bit skip is req\n"));
1649 //pcd->print(stderr,pcd);
1650 //pcs->print(stderr,pcs);
1654 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1655 // doesn't match because the wild pcode must *not* be a bit skip
1656 DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
1657 //pcd->print(stderr,pcd);
1658 //pcs->print(stderr,pcs);
1662 if(PCW(pcd)->operand) {
1663 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1664 if(peepBlock->target.vars[index]) {
1665 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1669 DFPRINTF((stderr," (matched)\n"));
1671 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1672 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n",
1673 peepBlock->target.vars[index],
1674 PCI(pcs)->pcop->name));
1679 DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
1680 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1685 pcs = findNextInstruction(pcs->next);
1687 //DFPRINTF((stderr," (next to match)\n"));
1688 //pcs->print(stderr,pcs);
1689 } else if(pcd->next) {
1690 /* oops, we ran out of code, but there's more to the rule */
1694 return 1; /* wild card matches */
1700 /*-----------------------------------------------------------------*/
1701 /*-----------------------------------------------------------------*/
1702 void pCodePeepClrVars(pCodePeep *pcp)
1709 DFPRINTF((stderr," Clearing peep rule vars\n"));
1710 DFPRINTF((stderr," %d %d %d %d %d %d\n",
1711 pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
1712 pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
1714 for(i=0;i<pcp->target.nvars; i++)
1715 pcp->target.vars[i] = NULL;
1716 for(i=0;i<pcp->target.nops; i++)
1717 pcp->target.wildpCodeOps[i] = NULL;
1718 for(i=0;i<pcp->target.nwildpCodes; i++)
1719 pcp->target.wildpCodes[i] = NULL;
1721 for(i=0;i<pcp->replace.nvars; i++)
1722 pcp->replace.vars[i] = NULL;
1723 for(i=0;i<pcp->replace.nops; i++)
1724 pcp->replace.wildpCodeOps[i] = NULL;
1725 for(i=0;i<pcp->replace.nwildpCodes; i++)
1726 pcp->replace.wildpCodes[i] = NULL;
1732 /*-----------------------------------------------------------------*/
1733 /* pCodeInsertAfter - splice in the pCode chain starting with pc2 */
1734 /* into the pCode chain containing pc1 */
1735 /*-----------------------------------------------------------------*/
1736 void pCodeInsertAfter(pCode *pc1, pCode *pc2)
1742 pc2->next = pc1->next;
1744 pc1->next->prev = pc2;
1752 /*-----------------------------------------------------------------*/
1753 /* pCodeOpCopy - copy a pcode operator */
1754 /*-----------------------------------------------------------------*/
1755 pCodeOp *pCodeOpCopy(pCodeOp *pcop)
1757 pCodeOp *pcopnew=NULL;
1762 switch(pcop->type) {
1765 //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
1766 pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1767 PCORB(pcopnew)->bit = PCORB(pcop)->bit;
1768 PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
1773 /* Here we expand the wild card into the appropriate type: */
1774 /* By recursively calling pCodeOpCopy */
1775 //DFPRINTF((stderr,"pCodeOpCopy wild\n"));
1776 if(PCOW(pcop)->matched)
1777 pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
1780 pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
1781 pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
1782 //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
1789 //DFPRINTF((stderr,"pCodeOpCopy label\n"));
1790 pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
1791 PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
1795 pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
1796 PCOI(pcopnew)->index = PCOI(pcop)->index;
1797 PCOI(pcopnew)->offset = PCOI(pcop)->offset;
1798 PCOI(pcopnew)->_const = PCOI(pcop)->_const;
1802 //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
1803 pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
1804 PCOL(pcopnew)->lit = PCOL(pcop)->lit;
1809 pcopnew = newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
1810 PCOR(pcopnew)->r = PCOR(pcop)->r;
1811 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1812 DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
1816 case PO_GPR_REGISTER:
1820 //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
1821 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1822 PCOR(pcopnew)->r = PCOR(pcop)->r;
1823 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1824 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1825 DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
1829 //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
1830 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1831 PCOR(pcopnew)->r = PCOR(pcop)->r;
1832 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1833 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1836 DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
1837 case PO_SFR_REGISTER:
1845 //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
1846 pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
1850 pcopnew->type = pcop->type;
1852 pcopnew->name = Safe_strdup(pcop->name);
1854 pcopnew->name = NULL;
1860 /*-----------------------------------------------------------------*/
1861 /* pCodeCopy - copy a pcode */
1862 /*-----------------------------------------------------------------*/
1863 static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert)
1865 pCodeInstruction *new_pci;
1868 new_pci = PCI(newpCode(pci->inverted_op,pci->pcop));
1870 new_pci = PCI(newpCode(pci->op,pci->pcop));
1872 new_pci->pc.pb = pci->pc.pb;
1873 new_pci->from = pci->from;
1874 new_pci->to = pci->to;
1875 new_pci->label = pci->label;
1876 new_pci->pcflow = pci->pcflow;
1878 return PCODE(new_pci);
1881 /*-----------------------------------------------------------------*/
1882 /*-----------------------------------------------------------------*/
1883 void pCodeDeleteChain(pCode *f,pCode *t)
1889 DFPRINTF((stderr,"delete pCode:\n"));
1891 //f->print(stderr,f);
1892 //f->delete(f); this dumps core...
1899 /*-----------------------------------------------------------------*/
1900 /*-----------------------------------------------------------------*/
1901 int pCodePeepMatchRule(pCode *pc)
1903 pCodePeep *peepBlock;
1905 pCodeCSource *pc_cline=NULL;
1909 peeprules = (_DLL *)peepSnippets;
1912 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1914 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
1915 fprintf(stderr, "skipping rule because target pb is NULL\n");
1919 pCodePeepClrVars(peepBlock);
1922 if(IS_PCCOMMENT(pcin))
1923 pc = pcin = findNextInstruction(pcin->next);
1925 pcin = pc = findNextInstruction(pc);
1927 pct = peepBlock->target.pb->pcHead;
1930 pCode *pcr = peepBlock->replace.pb->pcHead;
1931 if(pcr) pct->print(stderr,pcr);
1935 while(pct && pcin) {
1937 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1940 pcin = findNextInstruction(pcin->next);
1943 //DFPRINTF((stderr," matched\n"));
1946 DFPRINTF((stderr," partial match... no more code\n"));
1947 fprintf(stderr," partial match... no more code\n");
1951 DFPRINTF((stderr," end of rule\n"));
1955 if(matched && pcin) {
1957 /* So far we matched the rule up to the point of the conditions .
1958 * In other words, all of the opcodes match. Now we need to see
1959 * if the post conditions are satisfied.
1960 * First we check the 'postFalseCond'. This means that we check
1961 * to see if any of the subsequent pCode's in the pCode chain
1962 * following the point just past where we have matched depend on
1963 * the `postFalseCond' as input then we abort the match
1965 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
1966 //pcin->print(stderr,pcin);
1968 if (pcin && peepBlock->postFalseCond &&
1969 (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
1972 //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
1975 //if(!matched) fprintf(stderr,"failed on conditions\n");
1984 /* We matched a rule! Now we have to go through and remove the
1985 inefficient code with the optimized version */
1987 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
1988 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
1989 DFPRINTF((stderr,"first thing matched\n"));
1990 pc->print(stderr,pc);
1992 DFPRINTF((stderr,"last thing matched\n"));
1993 pcin->print(stderr,pcin);
1998 /* Unlink the original code */
2000 pcprev->next = pcin;
2002 pcin->prev = pc->prev;
2008 /* Converted the deleted pCodes into comments */
2011 pCodeCSource *pc_cline2=NULL;
2016 while(pc && pc!=pcin) {
2018 if(pc->type == PC_OPCODE && PCI(pc)->cline) {
2020 pc_cline2->pc.next = PCODE(PCI(pc)->cline);
2021 pc_cline2 = PCCS(pc_cline2->pc.next);
2023 pc_cline = pc_cline2 = PCI(pc)->cline;
2024 pc_cline->pc.seq = pc->seq;
2028 pCode2str(&buf[2], 254, pc);
2029 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
2030 pcprev = pcprev->next;
2035 pc_cline2->pc.next = NULL;
2040 pCodeDeleteChain(pc,pcin);
2042 /* Generate the replacement code */
2044 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
2048 /* If the replace pcode is an instruction with an operand, */
2049 /* then duplicate the operand (and expand wild cards in the process). */
2050 if(pcr->type == PC_OPCODE) {
2051 if(PCI(pcr)->pcop) {
2052 /* The replacing instruction has an operand.
2054 if(PCI(pcr)->pcop->type == PO_WILD) {
2055 int index = PCOW(PCI(pcr)->pcop)->id;
2056 //DFPRINTF((stderr,"copying wildopcode\n"));
2057 if(peepBlock->target.wildpCodeOps[index])
2058 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
2060 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
2062 pcop = pCodeOpCopy(PCI(pcr)->pcop);
2064 //DFPRINTF((stderr,"inserting pCode\n"));
2065 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
2066 } else if (pcr->type == PC_WILD) {
2067 if(PCW(pcr)->invertBitSkipInst)
2068 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
2069 pCodeInsertAfter(pc,
2070 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
2071 PCW(pcr)->invertBitSkipInst));
2072 } else if (pcr->type == PC_COMMENT) {
2073 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
2079 DFPRINTF((stderr," NEW Code:"));
2080 if(pc) pc->print(stderr,pc);
2085 /* We have just replaced the inefficient code with the rule.
2086 * Now, we need to re-add the C-source symbols if there are any */
2090 pc = findNextInstruction(pc->next);
2091 PCI(pc)->cline = pc_cline;
2092 pc_cline = PCCS(pc_cline->pc.next);
2099 peeprules = peeprules->next;
2101 DFPRINTF((stderr," no rule matched\n"));