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
208 static char alt_comment[] = { PCP_COMMENT, 0};
209 static char alt_label[] = { PCP_LABEL, 0};
210 static char alt_mnem0[] = { PCP_STR, 0};
211 static char alt_mnem0a[] = { PCP_WILDVAR, 0};
212 static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
213 static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0};
214 static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
215 static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
216 static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
217 static char alt_mnem3[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
219 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
220 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
221 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
222 static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
223 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
224 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
225 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
226 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
227 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
228 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
230 pcPattern altArr[] = {
231 {ALT_LABEL, alt_label, cvt_altpat_label},
232 {ALT_COMMENT, alt_comment,cvt_altpat_comment},
233 {ALT_MNEM3, alt_mnem3, cvt_altpat_mnem3},
234 {ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
235 {ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
236 {ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
237 {ALT_MNEM1A, alt_mnem1a, cvt_altpat_mnem1a},
238 {ALT_MNEM1, alt_mnem1, cvt_altpat_mnem1},
239 {ALT_MNEM0A, alt_mnem0a, cvt_altpat_mnem0a},
240 {ALT_MNEM0, alt_mnem0, cvt_altpat_mnem0},
244 #define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
246 // forward declarations
247 static void * DLL_append(_DLL *list, _DLL *next);
249 /*-----------------------------------------------------------------*/
250 /* cvt_extract_destination - helper function extracts the register */
251 /* destination from a parsedPattern. */
253 /*-----------------------------------------------------------------*/
254 static int cvt_extract_destination(parsedPattern *pp)
257 if(pp->pct[0].tt == PCT_STRING) {
259 // just check first letter for now
261 if(toupper(*pp->pct[0].tok.s) == 'F')
264 } else if (pp->pct[0].tt == PCT_NUMBER) {
274 /*-----------------------------------------------------------------*/
275 /* pCodeOp *cvt_extract_status(char *reg, char *bit) */
276 /* if *reg is the "status" register and *bit is one of the */
277 /* status bits, then this function will create a new pCode op */
278 /* containing the status register. */
279 /*-----------------------------------------------------------------*/
281 static pCodeOp *cvt_extract_status(char *reg, char *bit)
285 if(STRCASECMP(reg, pc_status.pcop.name))
292 if(toupper(*bit) == 'C')
293 return PCOP(popCopyGPR2Bit(&pc_status,PIC_C_BIT));
294 if(toupper(*bit) == 'Z')
295 return PCOP(popCopyGPR2Bit(&pc_status,PIC_Z_BIT));
299 if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C')
300 return PCOP(popCopyGPR2Bit(&pc_status,PIC_DC_BIT));
306 /*-----------------------------------------------------------------*/
307 /* cvt_altpat_label - convert assembly line type to a pCode label */
308 /* INPUT: pointer to the parsedPattern */
312 /* label pattern => '%' number ':' */
313 /* at this point, we wish to extract only the 'number' */
315 /*-----------------------------------------------------------------*/
316 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
318 parsedPattern *p = pp;
320 DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
321 return newpCodeLabel(NULL,-p->pct[1].tok.n);
325 /*-----------------------------------------------------------------*/
326 /* cvt_altpat_comment - convert assembly line type to a comment */
327 /* INPUT: pointer to the parsedPattern */
329 /* pp[0] - comment */
332 /*-----------------------------------------------------------------*/
333 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
335 parsedPattern *p = pp;
337 DFPRINTF((stderr,"altpat_comment = %s\n",p->pct[0].tok.s));
338 return newpCodeCharP(p->pct[0].tok.s);
342 /*-----------------------------------------------------------------*/
343 /* cvt_altpat_mem0 - convert assembly line type to a wild pCode */
348 /*-----------------------------------------------------------------*/
349 static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
351 parsedPattern *p = pp;
354 pCodeInstruction *pci=NULL;
356 DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s));
358 opcode = getpCode(p->pct[0].tok.s,0);
361 /* look for special command strings like _NOTBITSKIP_ */
363 //fprintf(stderr, "Bad mnemonic\n");
365 opcode = getpCodePeepCommand(p->pct[0].tok.s);
367 // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
371 pci = PCI(newpCode(opcode, NULL));
374 fprintf(stderr,"couldn't find mnemonic\n");
380 /*-----------------------------------------------------------------*/
381 /* cvt_altpat_mem0a - convert assembly line type to a wild pCode */
384 /* pp[0] - wild var */
386 /*-----------------------------------------------------------------*/
387 static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
389 parsedPattern *p = pp;
391 DFPRINTF((stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n));
393 /* Save the index of the maximum wildcard mnemonic */
395 //if(p[0].pct[1].tok.n > sMaxWildVar)
396 // sMaxWildMnem = p[0].pct[1].tok.n;
398 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
399 pcwb->nwildpCodes = p[0].pct[1].tok.n;
401 return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
405 /*-----------------------------------------------------------------*/
406 /* cvt_altpat_mem1 - convert assembly line type to a pCode */
407 /* instruction with 1 operand. */
410 /* pp[1] - Operand */
412 /*-----------------------------------------------------------------*/
413 static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
416 parsedPattern *p = pp;
419 pCodeInstruction *pci=NULL;
422 DFPRINTF((stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s));
424 opcode = getpCode(p->pct[0].tok.s,0);
426 //fprintf(stderr, "Bad mnemonic\n");
427 opcode = getpCodePeepCommand(p->pct[0].tok.s);
429 //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
434 if(pic14Mnemonics[opcode]->isBitInst)
435 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
437 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
440 pci = PCI(newpCode(opcode, pcosubtype));
443 fprintf(stderr,"couldn't find mnemonic\n");
449 /*-----------------------------------------------------------------*/
450 /* cvt_altpat_mem1a - convert assembly line type to a pCode */
451 /* instruction with 1 wild operand. */
454 /* pp[1] - wild var */
456 /*-----------------------------------------------------------------*/
457 static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
459 parsedPattern *p = pp;
462 pCodeInstruction *pci=NULL;
465 DFPRINTF((stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n));
467 opcode = getpCode(p->pct[0].tok.s,0);
469 int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
473 fprintf(stderr, "Bad mnemonic\n");
477 if(p[0].pct[1].tok.n > pcwb->nwildpCodes)
478 pcwb->nwildpCodes = p[0].pct[1].tok.n;
480 pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
484 PCW(pc)->mustNotBeBitSkipInst = 1;
487 PCW(pc)->mustBeBitSkipInst = 1;
490 PCW(pc)->invertBitSkipInst = 1;
495 if(pic14Mnemonics[opcode]->isBitInst)
496 pcosubtype = newpCodeOpBit(NULL,-1,0);
498 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
501 pci = PCI(newpCode(opcode,
502 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
504 /* Save the index of the maximum wildcard variable */
505 //if(p[1].pct[1].tok.n > sMaxWildVar)
506 // sMaxWildVar = p[1].pct[1].tok.n;
508 if(p[1].pct[1].tok.n > pcwb->nvars)
509 pcwb->nvars = p[1].pct[1].tok.n;
512 fprintf(stderr,"couldn't find mnemonic\n");
518 /*-----------------------------------------------------------------*/
519 /*-----------------------------------------------------------------*/
520 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
522 parsedPattern *p = pp;
525 pCodeInstruction *pci=NULL;
527 DFPRINTF((stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n));
529 opcode = getpCode(p->pct[0].tok.s,0);
531 fprintf(stderr, "Bad mnemonic\n");
535 pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
538 fprintf(stderr,"couldn't find mnemonic\n");
544 /*-----------------------------------------------------------------*/
545 /*-----------------------------------------------------------------*/
546 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
548 parsedPattern *p = pp;
552 pCodeInstruction *pci=NULL;
555 dest = cvt_extract_destination(&p[3]);
557 DFPRINTF((stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
564 opcode = getpCode(p->pct[0].tok.s,dest);
566 fprintf(stderr, "Bad mnemonic\n");
570 if(pic14Mnemonics[opcode]->isBitInst) {
571 pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
572 if(pcosubtype == NULL) {
573 fprintf(stderr, "bad operand?\n");
578 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
581 pci = PCI(newpCode(opcode,pcosubtype));
584 fprintf(stderr,"couldn't find mnemonic\n");
590 /*-----------------------------------------------------------------*/
591 /* cvt_altpat_mem2a - convert assembly line type to a pCode */
592 /* instruction with 1 wild operand and a */
593 /* destination operand (e.g. w or f) */
596 /* pp[1] - wild var */
598 /* pp[3] - destination */
600 /*-----------------------------------------------------------------*/
601 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
603 parsedPattern *p = pp;
607 pCodeInstruction *pci=NULL;
611 fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
615 dest = cvt_extract_destination(&p[3]);
617 DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
624 opcode = getpCode(p->pct[0].tok.s,dest);
626 fprintf(stderr, "Bad mnemonic\n");
630 if(pic14Mnemonics[opcode]->isBitInst)
631 pcosubtype = newpCodeOp(NULL,PO_BIT);
633 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
636 pci = PCI(newpCode(opcode,
637 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
639 /* Save the index of the maximum wildcard variable */
640 //if(p[1].pct[1].tok.n > sMaxWildVar)
641 // sMaxWildVar = p[1].pct[1].tok.n;
643 if(p[1].pct[1].tok.n > pcwb->nvars)
644 pcwb->nvars = p[1].pct[1].tok.n;
647 fprintf(stderr,"couldn't find mnemonic\n");
654 /*-----------------------------------------------------------------*/
655 /* cvt_altpat_mem3 - convert assembly line type to a pCode */
656 /* This rule is for bsf/bcf type instructions */
660 /* pp[1] - register */
664 /*-----------------------------------------------------------------*/
665 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
667 parsedPattern *p = pp;
669 int dest; // or could be bit position in the register
671 pCodeInstruction *pci=NULL;
672 pCodeOp *pcosubtype=NULL;
674 dest = cvt_extract_destination(&p[3]);
676 DFPRINTF((stderr,"altpat_mnem3 %s var %s bit (%d)\n",
682 opcode = getpCode(p->pct[0].tok.s,0);
684 fprintf(stderr, "Bad mnemonic\n");
689 if(pic14Mnemonics[opcode]->isBitInst) {
690 //pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
692 //if(pcosubtype == NULL) {
693 pcosubtype = newpCodeOpBit(p[1].pct[0].tok.s,p[3].pct[0].tok.n,0);
696 pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
698 if(pcosubtype == NULL) {
699 fprintf(stderr, "Bad operand\n");
703 pci = PCI(newpCode(opcode, pcosubtype));
706 fprintf(stderr,"couldn't find mnemonic\n");
712 /*-----------------------------------------------------------------*/
713 /* tokenizeLineNode - Convert a string (of char's) that was parsed */
714 /* by SDCCpeeph.c into a string of tokens. */
717 /* The tokenizer is of the classic type. When an item is encounterd*/
718 /* it is converted into a token. The token is a structure that */
719 /* encodes the item's type and it's value (when appropriate). */
721 /* Accepted token types: */
722 /* SPACE NUMBER STRING % : , ; */
726 /*-----------------------------------------------------------------*/
729 static void tokenizeLineNode(char *ln)
732 tokIdx = 0; // Starting off at the beginning
733 tokArr[0].tt = PCT_NULL; // and assume invalid character for first token.
742 // add a SPACE token and eat the extra spaces.
743 tokArr[tokIdx++].tt = PCT_SPACE;
744 while (isspace (*ln))
751 tokArr[tokIdx].tt = PCT_NUMBER;
752 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
760 tokArr[tokIdx++].tt = PCT_PERCENT;
763 tokArr[tokIdx++].tt = PCT_LESSTHAN;
766 tokArr[tokIdx++].tt = PCT_GREATERTHAN;
769 tokArr[tokIdx++].tt = PCT_COLON;
772 tokArr[tokIdx].tok.s = Safe_strdup(ln);
773 tokArr[tokIdx++].tt = PCT_COMMENT;
774 tokArr[tokIdx].tt = PCT_NULL;
777 tokArr[tokIdx++].tt = PCT_COMMA;
782 if(isalpha(*ln) || (*ln == '_') ) {
786 while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
792 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
793 tokArr[tokIdx++].tt = PCT_STRING;
796 fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
797 fprintf(stderr, "Line: %s\n",lnstart);
798 fprintf(stderr, "Token: '%c'\n",*ln);
803 /* Advance to next character in input string .
804 * Note, if none of the tests passed above, then
805 * we effectively ignore the `bad' character.
806 * Since the line has already been parsed by SDCCpeeph,
807 * chance are that there are no invalid characters... */
813 tokArr[tokIdx].tt = 0;
817 /*-----------------------------------------------------------------*/
818 /*-----------------------------------------------------------------*/
822 void dump1Token(pCodeTokens tt)
827 fprintf(stderr, " space ");
830 fprintf(stderr, " pct %%");
833 fprintf(stderr, " pct <");
835 case PCT_GREATERTHAN:
836 fprintf(stderr, " pct >");
839 fprintf(stderr, " col :");
842 fprintf(stderr, " comma , ");
845 fprintf(stderr, " comment ");
846 //fprintf(stderr,"%s",tokArr[i].tok.s);
849 fprintf(stderr, " str ");
850 //fprintf(stderr,"%s",tokArr[i].tok.s);
853 fprintf(stderr, " num ");
854 //fprintf(stderr,"%d",tokArr[i].tok.n);
857 fprintf(stderr, " null ");
864 /*-----------------------------------------------------------------*/
865 /*-----------------------------------------------------------------*/
867 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
871 if(!pct || !pat || !*pat)
874 //DFPRINTF((stderr,"comparing against:\n"));
876 while(i < max_tokens) {
879 //DFPRINTF((stderr,"matched\n"));
883 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
897 /*-----------------------------------------------------------------*/
898 /*-----------------------------------------------------------------*/
900 int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
904 if(!pct || !pat || !*pct)
908 while(i < max_tokens) {
911 //DFPRINTF((stderr,"matched\n"));
915 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
917 if( !pat || !pat->pcp )
920 if (pat->pcp->pt != *pct)
923 //DFPRINTF((stderr," pct=%d\n",*pct));
932 /*-----------------------------------------------------------------*/
933 /*-----------------------------------------------------------------*/
935 int advTokIdx(int *v, int amt)
938 if((unsigned) (*v + amt) > tokIdx)
946 /*-----------------------------------------------------------------*/
947 /* parseTokens - convert the tokens corresponding to a single line */
948 /* of a peep hole assembly into a pCode object. */
953 /* This is a simple parser that looks for strings of the type */
954 /* allowed in the peep hole definition file. Essentially the format*/
955 /* is the same as a line of assembly: */
957 /* label: mnemonic op1, op2, op3 ; comment */
959 /* Some of these items aren't present. It's the job of the parser */
960 /* to determine which are and convert those into the appropriate */
962 /*-----------------------------------------------------------------*/
964 int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
975 for(i=0; i<=tokIdx; i++)
976 dump1Token(tokArr[i].tt);
989 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
990 char * cP1stop = NULL;
991 char * cP2ndop = NULL;
993 //pCodeOp *pcl = NULL; // Storage for a label
994 //pCodeOp *pco1 = NULL; // 1st operand
995 //pCodeOp *pco2 = NULL; // 2nd operand
996 //pCode *pc = NULL; // Mnemonic
1007 ParseStates state = PS_START;
1014 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
1015 && (advTokIdx(<okIdx, 1)) ) // eat space
1019 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
1022 switch(pcpArr[lpcpIdx].pt) {
1024 if(state == PS_START){
1025 DFPRINTF((stderr," label\n"));
1026 state = PS_HAVE_LABEL;
1028 DFPRINTF((stderr," bad state (%d) for label\n",state));
1032 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
1036 DFPRINTF((stderr," mnem\n"));
1037 cPmnem = tokArr[ltokIdx].tok.s;
1038 state = PS_HAVE_MNEM;
1041 DFPRINTF((stderr," 1st operand\n"));
1042 cP1stop = tokArr[ltokIdx].tok.s;
1043 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
1044 state = PS_HAVE_1OPERAND;
1046 case PS_HAVE_1OPERAND:
1047 DFPRINTF((stderr," error expecting comma\n"));
1050 DFPRINTF((stderr," 2 operands\n"));
1051 cP2ndop = tokArr[ltokIdx].tok.s;
1053 case PS_HAVE_2OPERANDS:
1062 DFPRINTF((stderr," wild mnem\n"));
1063 state = PS_HAVE_MNEM;
1066 DFPRINTF((stderr," 1st operand is wild\n"));
1067 state = PS_HAVE_1OPERAND;
1069 case PS_HAVE_1OPERAND:
1070 DFPRINTF((stderr," error expecting comma\n"));
1073 DFPRINTF((stderr," 2nd operand is wild\n"));
1075 case PS_HAVE_2OPERANDS:
1084 fprintf(stderr," ERROR number\n");
1087 DFPRINTF((stderr," 1st operand is a number\n"));
1088 state = PS_HAVE_1OPERAND;
1090 case PS_HAVE_1OPERAND:
1091 fprintf(stderr," error expecting comma\n");
1094 DFPRINTF((stderr," 2nd operand is a number\n"));
1096 case PS_HAVE_2OPERANDS:
1104 if(state == PS_HAVE_1OPERAND){
1105 DFPRINTF((stderr," got a comma\n"));
1106 state = PS_HAVE_COMMA;
1108 fprintf(stderr," unexpected comma\n");
1114 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1115 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1118 //dump1Token(tokArr[ltokIdx].tt);
1120 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1121 DFPRINTF((stderr," reached end \n"));
1128 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1132 parsedPatArr[lparsedPatIdx].pcp = NULL;
1133 parsedPatArr[lparsedPatIdx].pct = NULL;
1139 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1142 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1143 //if(pc && pc->print)
1144 // pc->print(stderr,pc);
1145 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1147 //if(curBlock && pc)
1148 //addpCode2pBlock(curBlock, pc);
1152 return 0; // Only accept one line for now.
1154 addpCode2pBlock(pcwb->pb, pc);
1162 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1165 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1169 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1170 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1171 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1174 while(j<lparsedPatIdx);
1176 DFPRINTF((stderr,"\n"));
1183 /*-----------------------------------------------------------------*/
1185 /*-----------------------------------------------------------------*/
1186 void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
1192 for( ; ln; ln = ln->next) {
1194 //DFPRINTF((stderr,"%s\n",ln->line));
1196 tokenizeLineNode(ln->line);
1198 if(parseTokens(pcwb,NULL)) {
1200 fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
1201 fprintf(stderr,"Tokens:\n");
1203 dump1Token(tokArr[i].tt);
1210 /*-----------------------------------------------------------------*/
1212 /*-----------------------------------------------------------------*/
1213 pCode *AssembleLine(char *line)
1217 if(!line || !*line) {
1218 fprintf(stderr,"WARNING returning NULL in AssembleLine\n");
1222 tokenizeLineNode(line);
1224 if(parseTokens(NULL,&pc))
1225 fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
1231 /*-----------------------------------------------------------------*/
1232 /* peepRuleCondition */
1233 /*-----------------------------------------------------------------*/
1234 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1239 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1240 /* brute force compares for now */
1242 if(STRCASECMP(cond, "NZ") == 0) {
1243 //DFPRINTF((stderr,"found NZ\n"));
1244 pcp->postFalseCond = PCC_Z;
1251 void initpCodeWildBlock(pCodeWildBlock *pcwb)
1254 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1260 pcwb->wildpCodes = NULL;
1261 pcwb->wildpCodeOps = NULL;
1264 pcwb->nwildpCodes = 0;
1269 void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1276 pcwb->nops = pcwb->nvars;
1278 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1279 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1281 pcwb->nwildpCodes+=2;
1282 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1286 void initpCodePeep(pCodePeep *pcp)
1289 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1294 initpCodeWildBlock(&pcp->target);
1295 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1297 initpCodeWildBlock(&pcp->replace);
1298 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1302 /*-----------------------------------------------------------------*/
1303 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1306 /* SDCCpeeph parses the peep rules file and extracts variables, */
1307 /* removes white space, and checks the syntax. This function */
1308 /* extends that processing to produce pCode objects. You can kind */
1309 /* think of this function as an "assembler", though instead of */
1310 /* taking raw text to produce machine code, it produces pCode. */
1312 /*-----------------------------------------------------------------*/
1313 extern void pic14initpCodePeepCommands(void);
1315 void peepRules2pCode(peepRule *rules)
1319 pCodePeep *currentRule;
1320 pCodePeepSnippets *pcps;
1322 pic14initpCodePeepCommands();
1324 /* The rules are in a linked-list. Each rule has two portions */
1325 /* There's the `target' and there's the `replace'. The target */
1326 /* is compared against the SDCC generated code and if it */
1327 /* matches, it gets replaced by the `replace' block of code. */
1329 /* Here we loop through each rule and convert the target's and*/
1330 /* replace's into pCode target and replace blocks */
1332 for (pr = rules; pr; pr = pr->next) {
1334 //DFPRINTF((stderr,"\nRule:\n\n"));
1336 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1337 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1339 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1340 initpCodePeep(currentRule);
1342 /* Convert the target block */
1343 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1345 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1346 //printpBlock(stderr, currentRule->target.pb);
1348 //DFPRINTF((stderr,"target with labels merged:\n"));
1349 //pBlockMergeLabels(curBlock);
1350 pBlockMergeLabels(currentRule->target.pb);
1351 //printpBlock(stderr, currentRule->replace.pb);
1353 //#ifdef PCODE_DEBUG
1354 // printpBlock(stderr, curBlock);
1356 //DFPRINTF((stderr,"\nReplaced by:\n"));
1359 /* Convert the replace block */
1360 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1362 //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
1363 //printpBlock(stderr, curBlock);
1365 //DFPRINTF((stderr,"replace with labels merged:\n"));
1367 pBlockMergeLabels(currentRule->replace.pb);
1368 //printpBlock(stderr, currentRule->replace.pb);
1370 peepRuleCondition(pr->cond,currentRule);
1372 /* The rule has been converted to pCode. Now allocate
1373 * space for the wildcards */
1375 postinit_pCodeWildBlock(¤tRule->target);
1376 postinit_pCodeWildBlock(¤tRule->replace);
1378 //return; // debug ... don't want to go through all the rules yet
1382 pCodePeep *peepBlock;
1385 peeprules = (_DLL *)peepSnippets;
1386 //fprintf(stderr,"target rules\n");
1388 //fprintf(stderr," rule:\n");
1389 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1390 //printpBlock(stderr, peepBlock->target.pb);
1391 peeprules = peeprules->next;
1393 //fprintf(stderr," ... done\n");
1398 void printpCodeString(FILE *of, pCode *pc, int max)
1402 while(pc && (i++<max)) {
1408 /*-----------------------------------------------------------------*/
1409 /* _DLL * DLL_append */
1411 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1412 /* If The list to which we want to append is non-existant then one */
1413 /* is created. Other wise, the end of the list is sought out and */
1414 /* a new DLL object is appended to it. In either case, the void */
1415 /* *data is added to the newly created DLL object. */
1416 /*-----------------------------------------------------------------*/
1418 static void * DLL_append(_DLL *list, _DLL *next)
1423 /* If there's no list, then create one: */
1425 next->next = next->prev = NULL;
1430 /* Search for the end of the list. */
1435 /* Now append the new DLL object */
1446 /*-----------------------------------------------------------------
1448 pCode peephole optimization
1451 The pCode "peep hole" optimization is not too unlike the peep hole
1452 optimization in SDCCpeeph.c. The major difference is that here we
1453 use pCode's whereas there we use ASCII strings. The advantage with
1454 pCode's is that we can ascertain flow information in the instructions
1458 <FIX ME> - elaborate...
1460 -----------------------------------------------------------------*/
1464 /*-----------------------------------------------------------------*/
1465 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1467 /* return conditions */
1468 /* 1 - The Condition was found for a pCode's input */
1469 /* 0 - No matching condition was found for the whole chain */
1470 /* -1 - The Condition was found for a pCode's output */
1472 /*-----------------------------------------------------------------*/
1473 int pCodeSearchCondition(pCode *pc, unsigned int cond)
1475 //fprintf(stderr,"Checking conditions %d\n",cond);
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 //fprintf(stderr," checking conditions of: ");
1486 //pc->print(stderr,pc);
1487 //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond);
1488 if(PCI(pc)->inCond & cond)
1490 if(PCI(pc)->outCond & cond)
1500 /*-----------------------------------------------------------------
1501 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1503 * Compare two pCodeOp's and return 1 if they're the same
1504 *-----------------------------------------------------------------*/
1505 int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1509 if(!pcops || !pcopd)
1512 fprintf(stderr," Comparing operands %s",
1513 get_op( pcops,NULL,0));
1515 fprintf(stderr," to %s\n",
1516 get_op( pcopd,NULL,0));
1519 if(pcops->type != pcopd->type) {
1520 //fprintf(stderr," - fail - diff types\n");
1521 return 0; // different types
1524 if(pcops->type == PO_LITERAL) {
1526 if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit))
1535 n2 = get_op(pcopd,NULL,0);
1537 if( !n2 || strcmp(b,n2)) {
1538 //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
1539 return 0; // different names
1542 switch(pcops->type) {
1544 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1545 //fprintf(stderr, " - fail different instances\n");
1553 //fprintf(stderr," - pass\n");
1558 int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1562 /* Check for a label associated with this wild pCode */
1563 // If the wild card has a label, make sure the source code does too.
1564 if(PCI(pcd)->label) {
1565 pCode *pcl = PCI(pcd)->label->pc;
1568 int li = -PCL(pcl)->key;
1570 if(peepBlock->target.vars[li] == NULL) {
1571 if(PCI(pcs)->label) {
1572 DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
1575 // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
1576 DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
1577 if(PCI(pcs)->label) {
1578 DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
1584 if(!PCI(pcs)->label)
1587 labindex = -PCL(pcl)->key;
1588 if(peepBlock->target.vars[labindex] == NULL) {
1589 // First time to encounter this label
1590 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1591 DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
1594 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1595 DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
1598 DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
1601 //DFPRINTF((stderr,"destination doesn't have a label\n"));
1606 //DFPRINTF((stderr,"neither src nor dest have labels\n"));
1614 /*-----------------------------------------------------------------*/
1615 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1616 /* see they're the same. */
1618 /* In this context, "source" refers to the coded generated by gen.c*/
1619 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1620 /* ination has no wild cards, then MatchLine will compare the two */
1621 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1622 /* has wildcards, then those get expanded. When a wild card is */
1623 /* encountered for the first time it autmatically is considered a */
1624 /* match and the object that matches it is referenced in the */
1625 /* variables or opcodes array (depending on the type of match). */
1629 /* *peepBlock - A pointer to the peepBlock that contains the */
1630 /* entire rule to which the destination pcode belongs*/
1631 /* *pcs - a pointer to the source pcode */
1632 /* *pcd - a pointer to the destination pcode */
1635 /* 1 - pcodes match */
1636 /* 0 - pcodes don't match */
1639 /*-----------------------------------------------------------------*/
1641 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1643 int index; // index into wild card arrays
1645 /* one-for-one match. Here the source and destination opcodes
1646 * are not wild. However, there may be a label or a wild operand */
1649 if(PCI(pcs)->label) {
1650 DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
1654 if(pcs->type == pcd->type) {
1656 if(pcs->type == PC_OPCODE) {
1658 /* If the opcodes don't match then the line doesn't match */
1659 if(PCI(pcs)->op != PCI(pcd)->op)
1663 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1664 pcs->print(stderr,pcs);
1665 pcd->print(stderr,pcd);
1668 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1671 /* Compare the operands */
1672 if(PCI(pcd)->pcop) {
1673 if (PCI(pcd)->pcop->type == PO_WILD) {
1674 index = PCOW(PCI(pcd)->pcop)->id;
1675 //DFPRINTF((stderr,"destination is wild\n"));
1676 #ifdef DEBUG_PCODEPEEP
1677 if (index > peepBlock->nops) {
1678 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1683 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1684 if(!peepBlock->target.wildpCodeOps[index]) {
1685 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1687 //if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
1691 pcs->print(stderr,pcs);
1692 pcd->print(stderr,pcd);
1694 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1695 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1699 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1705 switch(PCI(pcs)->pcop->type) {
1709 n = PCOR(PCI(pcs)->pcop)->r->name;
1713 n = PCI(pcs)->pcop->name;
1716 if(peepBlock->target.vars[index])
1717 return (strcmp(peepBlock->target.vars[index],n) == 0);
1719 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1720 peepBlock->target.vars[index] = n;
1725 } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
1726 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1729 /* FIXME - need an else to check the case when the destination
1730 * isn't a wild card */
1732 /* The pcd has no operand. Lines match if pcs has no operand either*/
1733 return (PCI(pcs)->pcop == NULL);
1737 /* Compare a wild instruction to a regular one. */
1739 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1741 index = PCW(pcd)->id;
1743 DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1744 pcs->print(stderr,pcs);
1745 pcd->print(stderr,pcd);
1747 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1749 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
1750 DFPRINTF((stderr," Failing because labels don't match\n"));
1754 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1755 // doesn't match because the wild pcode must be a bit skip
1756 DFPRINTF((stderr," Failing match because bit skip is req\n"));
1757 //pcd->print(stderr,pcd);
1758 //pcs->print(stderr,pcs);
1762 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1763 // doesn't match because the wild pcode must *not* be a bit skip
1764 DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
1765 //pcd->print(stderr,pcd);
1766 //pcs->print(stderr,pcs);
1770 if(PCW(pcd)->operand) {
1771 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1772 if(peepBlock->target.vars[index]) {
1773 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1777 DFPRINTF((stderr," (matched)\n"));
1779 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1780 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n",
1781 peepBlock->target.vars[index],
1782 PCI(pcs)->pcop->name));
1787 DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
1788 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1793 pcs = findNextInstruction(pcs->next);
1795 //DFPRINTF((stderr," (next to match)\n"));
1796 //pcs->print(stderr,pcs);
1797 } else if(pcd->next) {
1798 /* oops, we ran out of code, but there's more to the rule */
1802 return 1; /* wild card matches */
1808 /*-----------------------------------------------------------------*/
1809 /*-----------------------------------------------------------------*/
1810 void pCodePeepClrVars(pCodePeep *pcp)
1817 DFPRINTF((stderr," Clearing peep rule vars\n"));
1818 DFPRINTF((stderr," %d %d %d %d %d %d\n",
1819 pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
1820 pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
1822 for(i=0;i<pcp->target.nvars; i++)
1823 pcp->target.vars[i] = NULL;
1824 for(i=0;i<pcp->target.nops; i++)
1825 pcp->target.wildpCodeOps[i] = NULL;
1826 for(i=0;i<pcp->target.nwildpCodes; i++)
1827 pcp->target.wildpCodes[i] = NULL;
1829 for(i=0;i<pcp->replace.nvars; i++)
1830 pcp->replace.vars[i] = NULL;
1831 for(i=0;i<pcp->replace.nops; i++)
1832 pcp->replace.wildpCodeOps[i] = NULL;
1833 for(i=0;i<pcp->replace.nwildpCodes; i++)
1834 pcp->replace.wildpCodes[i] = NULL;
1840 /*-----------------------------------------------------------------*/
1841 /* pCodeInsertAfter - splice in the pCode chain starting with pc2 */
1842 /* into the pCode chain containing pc1 */
1843 /*-----------------------------------------------------------------*/
1844 void pCodeInsertAfter(pCode *pc1, pCode *pc2)
1850 pc2->next = pc1->next;
1852 pc1->next->prev = pc2;
1860 /*-----------------------------------------------------------------*/
1861 /* pCodeOpCopy - copy a pcode operator */
1862 /*-----------------------------------------------------------------*/
1863 pCodeOp *pCodeOpCopy(pCodeOp *pcop)
1865 pCodeOp *pcopnew=NULL;
1870 switch(pcop->type) {
1873 //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
1874 pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1875 PCORB(pcopnew)->bit = PCORB(pcop)->bit;
1876 PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
1881 /* Here we expand the wild card into the appropriate type: */
1882 /* By recursively calling pCodeOpCopy */
1883 //DFPRINTF((stderr,"pCodeOpCopy wild\n"));
1884 if(PCOW(pcop)->matched)
1885 pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
1888 pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
1889 pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
1890 //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
1897 //DFPRINTF((stderr,"pCodeOpCopy label\n"));
1898 pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
1899 PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
1903 pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
1904 PCOI(pcopnew)->index = PCOI(pcop)->index;
1905 PCOI(pcopnew)->offset = PCOI(pcop)->offset;
1906 PCOI(pcopnew)->_const = PCOI(pcop)->_const;
1910 //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
1911 pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
1912 PCOL(pcopnew)->lit = PCOL(pcop)->lit;
1917 pcopnew = newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
1918 PCOR(pcopnew)->r = PCOR(pcop)->r;
1919 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1920 DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
1924 case PO_GPR_REGISTER:
1928 //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
1929 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1930 PCOR(pcopnew)->r = PCOR(pcop)->r;
1931 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1932 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1933 DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
1937 //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
1938 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1939 PCOR(pcopnew)->r = PCOR(pcop)->r;
1940 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1941 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1944 DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
1945 case PO_SFR_REGISTER:
1953 //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
1954 pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
1958 pcopnew->type = pcop->type;
1960 pcopnew->name = Safe_strdup(pcop->name);
1962 pcopnew->name = NULL;
1968 /*-----------------------------------------------------------------*/
1969 /* pCodeCopy - copy a pcode */
1970 /*-----------------------------------------------------------------*/
1971 static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert)
1973 pCodeInstruction *new_pci;
1976 new_pci = PCI(newpCode(pci->inverted_op,pci->pcop));
1978 new_pci = PCI(newpCode(pci->op,pci->pcop));
1980 new_pci->pc.pb = pci->pc.pb;
1981 new_pci->from = pci->from;
1982 new_pci->to = pci->to;
1983 new_pci->label = pci->label;
1984 new_pci->pcflow = pci->pcflow;
1986 return PCODE(new_pci);
1989 /*-----------------------------------------------------------------*/
1990 /*-----------------------------------------------------------------*/
1991 void pCodeDeleteChain(pCode *f,pCode *t)
1997 DFPRINTF((stderr,"delete pCode:\n"));
1999 //f->print(stderr,f);
2000 //f->delete(f); this dumps core...
2007 /*-----------------------------------------------------------------*/
2008 /*-----------------------------------------------------------------*/
2009 int pCodePeepMatchRule(pCode *pc)
2011 pCodePeep *peepBlock;
2013 pCodeCSource *pc_cline=NULL;
2017 peeprules = (_DLL *)peepSnippets;
2020 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
2022 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
2023 fprintf(stderr, "skipping rule because target pb is NULL\n");
2027 pCodePeepClrVars(peepBlock);
2030 if(IS_PCCOMMENT(pcin))
2031 pc = pcin = findNextInstruction(pcin->next);
2033 pcin = pc = findNextInstruction(pc);
2035 pct = peepBlock->target.pb->pcHead;
2038 pCode *pcr = peepBlock->replace.pb->pcHead;
2039 if(pcr) pct->print(stderr,pcr);
2043 while(pct && pcin) {
2045 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
2048 pcin = findNextInstruction(pcin->next);
2051 //DFPRINTF((stderr," matched\n"));
2054 DFPRINTF((stderr," partial match... no more code\n"));
2055 fprintf(stderr," partial match... no more code\n");
2059 DFPRINTF((stderr," end of rule\n"));
2063 if(matched && pcin) {
2065 /* So far we matched the rule up to the point of the conditions .
2066 * In other words, all of the opcodes match. Now we need to see
2067 * if the post conditions are satisfied.
2068 * First we check the 'postFalseCond'. This means that we check
2069 * to see if any of the subsequent pCode's in the pCode chain
2070 * following the point just past where we have matched depend on
2071 * the `postFalseCond' as input then we abort the match
2073 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
2074 //pcin->print(stderr,pcin);
2076 if (pcin && peepBlock->postFalseCond &&
2077 (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
2080 //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
2083 //if(!matched) fprintf(stderr,"failed on conditions\n");
2092 /* We matched a rule! Now we have to go through and remove the
2093 inefficient code with the optimized version */
2095 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
2096 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
2097 DFPRINTF((stderr,"first thing matched\n"));
2098 pc->print(stderr,pc);
2100 DFPRINTF((stderr,"last thing matched\n"));
2101 pcin->print(stderr,pcin);
2106 /* Unlink the original code */
2108 pcprev->next = pcin;
2110 pcin->prev = pc->prev;
2116 /* Converted the deleted pCodes into comments */
2119 pCodeCSource *pc_cline2=NULL;
2124 while(pc && pc!=pcin) {
2126 if(pc->type == PC_OPCODE && PCI(pc)->cline) {
2128 pc_cline2->pc.next = PCODE(PCI(pc)->cline);
2129 pc_cline2 = PCCS(pc_cline2->pc.next);
2131 pc_cline = pc_cline2 = PCI(pc)->cline;
2132 pc_cline->pc.seq = pc->seq;
2136 pCode2str(&buf[2], 254, pc);
2137 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
2138 pcprev = pcprev->next;
2143 pc_cline2->pc.next = NULL;
2148 pCodeDeleteChain(pc,pcin);
2150 /* Generate the replacement code */
2152 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
2156 /* If the replace pcode is an instruction with an operand, */
2157 /* then duplicate the operand (and expand wild cards in the process). */
2158 if(pcr->type == PC_OPCODE) {
2159 if(PCI(pcr)->pcop) {
2160 /* The replacing instruction has an operand.
2162 if(PCI(pcr)->pcop->type == PO_WILD) {
2163 int index = PCOW(PCI(pcr)->pcop)->id;
2164 //DFPRINTF((stderr,"copying wildopcode\n"));
2165 if(peepBlock->target.wildpCodeOps[index])
2166 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
2168 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
2170 pcop = pCodeOpCopy(PCI(pcr)->pcop);
2172 //DFPRINTF((stderr,"inserting pCode\n"));
2173 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
2174 } else if (pcr->type == PC_WILD) {
2175 if(PCW(pcr)->invertBitSkipInst)
2176 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
2177 pCodeInsertAfter(pc,
2178 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
2179 PCW(pcr)->invertBitSkipInst));
2180 } else if (pcr->type == PC_COMMENT) {
2181 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
2187 DFPRINTF((stderr," NEW Code:"));
2188 if(pc) pc->print(stderr,pc);
2193 /* We have just replaced the inefficient code with the rule.
2194 * Now, we need to re-add the C-source symbols if there are any */
2198 pc = findNextInstruction(pc->next);
2199 PCI(pc)->cline = pc_cline;
2200 pc_cline = PCCS(pc_cline->pc.next);
2207 peeprules = peeprules->next;
2209 DFPRINTF((stderr," no rule matched\n"));