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;
607 fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
611 dest = cvt_extract_destination(&p[3]);
613 DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
620 opcode = getpCode(p->pct[0].tok.s,dest);
622 fprintf(stderr, "Bad mnemonic\n");
626 if(pic14Mnemonics[opcode]->isBitInst)
627 pcosubtype = newpCodeOp(NULL,PO_BIT);
629 pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
632 pci = PCI(newpCode(opcode,
633 newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
635 /* Save the index of the maximum wildcard variable */
636 //if(p[1].pct[1].tok.n > sMaxWildVar)
637 // sMaxWildVar = p[1].pct[1].tok.n;
639 if(p[1].pct[1].tok.n > pcwb->nvars)
640 pcwb->nvars = p[1].pct[1].tok.n;
643 fprintf(stderr,"couldn't find mnemonic\n");
649 /*-----------------------------------------------------------------*/
650 /* tokenizeLineNode - Convert a string (of char's) that was parsed */
651 /* by SDCCpeeph.c into a string of tokens. */
654 /* The tokenizer is of the classic type. When an item is encounterd*/
655 /* it is converted into a token. The token is a structure that */
656 /* encodes the item's type and it's value (when appropriate). */
658 /* Accepted token types: */
659 /* SPACE NUMBER STRING % : , ; */
663 /*-----------------------------------------------------------------*/
666 static void tokenizeLineNode(char *ln)
669 tokIdx = 0; // Starting off at the beginning
670 tokArr[0].tt = PCT_NULL; // and assume invalid character for first token.
679 // add a SPACE token and eat the extra spaces.
680 tokArr[tokIdx++].tt = PCT_SPACE;
681 while (isspace (*ln))
688 tokArr[tokIdx].tt = PCT_NUMBER;
689 tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
697 tokArr[tokIdx++].tt = PCT_PERCENT;
700 tokArr[tokIdx++].tt = PCT_LESSTHAN;
703 tokArr[tokIdx++].tt = PCT_GREATERTHAN;
706 tokArr[tokIdx++].tt = PCT_COLON;
709 tokArr[tokIdx].tok.s = Safe_strdup(ln);
710 tokArr[tokIdx++].tt = PCT_COMMENT;
711 tokArr[tokIdx].tt = PCT_NULL;
714 tokArr[tokIdx++].tt = PCT_COMMA;
719 if(isalpha(*ln) || (*ln == '_') ) {
723 while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
729 tokArr[tokIdx].tok.s = Safe_strdup(buffer);
730 tokArr[tokIdx++].tt = PCT_STRING;
733 fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
734 fprintf(stderr, "Line: %s\n",lnstart);
735 fprintf(stderr, "Token: '%c'\n",*ln);
740 /* Advance to next character in input string .
741 * Note, if none of the tests passed above, then
742 * we effectively ignore the `bad' character.
743 * Since the line has already been parsed by SDCCpeeph,
744 * chance are that there are no invalid characters... */
750 tokArr[tokIdx].tt = 0;
754 /*-----------------------------------------------------------------*/
755 /*-----------------------------------------------------------------*/
759 void dump1Token(pCodeTokens tt)
764 fprintf(stderr, " space ");
767 fprintf(stderr, " pct %%");
770 fprintf(stderr, " pct <");
772 case PCT_GREATERTHAN:
773 fprintf(stderr, " pct >");
776 fprintf(stderr, " col :");
779 fprintf(stderr, " comma , ");
782 fprintf(stderr, " comment ");
783 //fprintf(stderr,"%s",tokArr[i].tok.s);
786 fprintf(stderr, " str ");
787 //fprintf(stderr,"%s",tokArr[i].tok.s);
790 fprintf(stderr, " num ");
791 //fprintf(stderr,"%d",tokArr[i].tok.n);
794 fprintf(stderr, " null ");
801 /*-----------------------------------------------------------------*/
802 /*-----------------------------------------------------------------*/
804 int pcComparePattern(pCodeToken *pct, char *pat, int max_tokens)
808 if(!pct || !pat || !*pat)
811 //DFPRINTF((stderr,"comparing against:\n"));
813 while(i < max_tokens) {
816 //DFPRINTF((stderr,"matched\n"));
820 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
834 /*-----------------------------------------------------------------*/
835 /*-----------------------------------------------------------------*/
837 int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
841 if(!pct || !pat || !*pct)
845 while(i < max_tokens) {
848 //DFPRINTF((stderr,"matched\n"));
852 //dump1Token(*pat); DFPRINTF((stderr,"\n"));
854 if( !pat || !pat->pcp )
857 if (pat->pcp->pt != *pct)
860 //DFPRINTF((stderr," pct=%d\n",*pct));
869 /*-----------------------------------------------------------------*/
870 /*-----------------------------------------------------------------*/
872 int advTokIdx(int *v, int amt)
875 if((unsigned) (*v + amt) > tokIdx)
883 /*-----------------------------------------------------------------*/
884 /* parseTokens - convert the tokens corresponding to a single line */
885 /* of a peep hole assembly into a pCode object. */
890 /* This is a simple parser that looks for strings of the type */
891 /* allowed in the peep hole definition file. Essentially the format*/
892 /* is the same as a line of assembly: */
894 /* label: mnemonic op1, op2, op3 ; comment */
896 /* Some of these items aren't present. It's the job of the parser */
897 /* to determine which are and convert those into the appropriate */
899 /*-----------------------------------------------------------------*/
901 int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
910 for(i=0; i<=tokIdx; i++)
911 dump1Token(tokArr[i].tt);
923 char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
924 char * cP1stop = NULL;
925 char * cP2ndop = NULL;
927 //pCodeOp *pcl = NULL; // Storage for a label
928 //pCodeOp *pco1 = NULL; // 1st operand
929 //pCodeOp *pco2 = NULL; // 2nd operand
930 //pCode *pc = NULL; // Mnemonic
941 ParseStates state = PS_START;
948 if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
949 && (advTokIdx(<okIdx, 1)) ) // eat space
953 j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
956 switch(pcpArr[lpcpIdx].pt) {
958 if(state == PS_START){
959 DFPRINTF((stderr," label\n"));
960 state = PS_HAVE_LABEL;
962 DFPRINTF((stderr," bad state (%d) for label\n",state));
966 DFPRINTF((stderr," %s is",tokArr[ltokIdx].tok.s));
970 DFPRINTF((stderr," mnem\n"));
971 cPmnem = tokArr[ltokIdx].tok.s;
972 state = PS_HAVE_MNEM;
975 DFPRINTF((stderr," 1st operand\n"));
976 cP1stop = tokArr[ltokIdx].tok.s;
977 //pco1 = newpCodeOp(NULL,PO_GPR_REGISTER);
978 state = PS_HAVE_1OPERAND;
980 case PS_HAVE_1OPERAND:
981 DFPRINTF((stderr," error expecting comma\n"));
984 DFPRINTF((stderr," 2 operands\n"));
985 cP2ndop = tokArr[ltokIdx].tok.s;
987 case PS_HAVE_2OPERANDS:
996 DFPRINTF((stderr," wild mnem\n"));
997 state = PS_HAVE_MNEM;
1000 DFPRINTF((stderr," 1st operand is wild\n"));
1001 state = PS_HAVE_1OPERAND;
1003 case PS_HAVE_1OPERAND:
1004 DFPRINTF((stderr," error expecting comma\n"));
1007 DFPRINTF((stderr," 2nd operand is wild\n"));
1009 case PS_HAVE_2OPERANDS:
1018 fprintf(stderr," ERROR number\n");
1021 DFPRINTF((stderr," 1st operand is a number\n"));
1022 state = PS_HAVE_1OPERAND;
1024 case PS_HAVE_1OPERAND:
1025 fprintf(stderr," error expecting comma\n");
1028 DFPRINTF((stderr," 2nd operand is a number\n"));
1030 case PS_HAVE_2OPERANDS:
1038 if(state == PS_HAVE_1OPERAND){
1039 DFPRINTF((stderr," got a comma\n"));
1040 state = PS_HAVE_COMMA;
1042 fprintf(stderr," unexpected comma\n");
1048 parsedPatArr[lparsedPatIdx].pcp = &pcpArr[lpcpIdx];
1049 parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
1052 //dump1Token(tokArr[ltokIdx].tt);
1054 if(advTokIdx(<okIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
1055 DFPRINTF((stderr," reached end \n"));
1062 } while ((++lpcpIdx < PCPATTERNS) && !matching);
1066 parsedPatArr[lparsedPatIdx].pcp = NULL;
1067 parsedPatArr[lparsedPatIdx].pct = NULL;
1073 if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
1076 pc = altArr[k].f(&parsedPatArr[j],pcwb);
1077 //if(pc && pc->print)
1078 // pc->print(stderr,pc);
1079 //if(pc && pc->destruct) pc->destruct(pc); dumps core?
1081 //if(curBlock && pc)
1082 //addpCode2pBlock(curBlock, pc);
1086 return 0; // Only accept one line for now.
1088 addpCode2pBlock(pcwb->pb, pc);
1096 while(j<=lparsedPatIdx && k<ALTPATTERNS);
1099 DFPRINTF((stderr,"\nConverting parsed line to pCode:\n\n"));
1103 if(parsedPatArr[j].pcp && parsedPatArr[j].pcp->f )
1104 parsedPatArr[j].pcp->f(&parsedPatArr[j]);
1105 DFPRINTF((stderr," %d",parsedPatArr[j].pcp->pt));
1108 while(j<lparsedPatIdx);
1110 DFPRINTF((stderr,"\n"));
1117 /*-----------------------------------------------------------------*/
1119 /*-----------------------------------------------------------------*/
1120 void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
1126 for( ; ln; ln = ln->next) {
1128 //DFPRINTF((stderr,"%s\n",ln->line));
1130 tokenizeLineNode(ln->line);
1132 if(parseTokens(pcwb,NULL)) {
1133 fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line);
1139 /*-----------------------------------------------------------------*/
1141 /*-----------------------------------------------------------------*/
1142 pCode *AssembleLine(char *line)
1146 if(!line || !*line) {
1147 fprintf(stderr,"WARNING returning NULL in AssembleLine\n");
1151 tokenizeLineNode(line);
1153 if(parseTokens(NULL,&pc))
1154 fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
1160 /*-----------------------------------------------------------------*/
1161 /* peepRuleCondition */
1162 /*-----------------------------------------------------------------*/
1163 static void peepRuleCondition(char *cond, pCodePeep *pcp)
1168 //DFPRINTF((stderr,"\nCondition: %s\n",cond));
1169 /* brute force compares for now */
1171 if(STRCASECMP(cond, "NZ") == 0) {
1172 //DFPRINTF((stderr,"found NZ\n"));
1173 pcp->postFalseCond = PCC_Z;
1180 void initpCodeWildBlock(pCodeWildBlock *pcwb)
1183 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1189 pcwb->wildpCodes = NULL;
1190 pcwb->wildpCodeOps = NULL;
1193 pcwb->nwildpCodes = 0;
1198 void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
1205 pcwb->nops = pcwb->nvars;
1207 pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
1208 pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
1210 pcwb->nwildpCodes+=2;
1211 pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
1215 void initpCodePeep(pCodePeep *pcp)
1218 // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
1223 initpCodeWildBlock(&pcp->target);
1224 pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
1226 initpCodeWildBlock(&pcp->replace);
1227 pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
1231 /*-----------------------------------------------------------------*/
1232 /* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
1235 /* SDCCpeeph parses the peep rules file and extracts variables, */
1236 /* removes white space, and checks the syntax. This function */
1237 /* extends that processing to produce pCode objects. You can kind */
1238 /* think of this function as an "assembler", though instead of */
1239 /* taking raw text to produce machine code, it produces pCode. */
1241 /*-----------------------------------------------------------------*/
1242 extern void pic14initpCodePeepCommands(void);
1244 void peepRules2pCode(peepRule *rules)
1248 pCodePeep *currentRule;
1249 pCodePeepSnippets *pcps;
1251 pic14initpCodePeepCommands();
1253 /* The rules are in a linked-list. Each rule has two portions */
1254 /* There's the `target' and there's the `replace'. The target */
1255 /* is compared against the SDCC generated code and if it */
1256 /* matches, it gets replaced by the `replace' block of code. */
1258 /* Here we loop through each rule and convert the target's and*/
1259 /* replace's into pCode target and replace blocks */
1261 for (pr = rules; pr; pr = pr->next) {
1263 //DFPRINTF((stderr,"\nRule:\n\n"));
1265 pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
1266 peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
1268 currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
1269 initpCodePeep(currentRule);
1271 /* Convert the target block */
1272 peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
1274 //DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
1275 //printpBlock(stderr, currentRule->target.pb);
1277 //DFPRINTF((stderr,"target with labels merged:\n"));
1278 //pBlockMergeLabels(curBlock);
1279 pBlockMergeLabels(currentRule->target.pb);
1280 //printpBlock(stderr, currentRule->replace.pb);
1282 //#ifdef PCODE_DEBUG
1283 // printpBlock(stderr, curBlock);
1285 //DFPRINTF((stderr,"\nReplaced by:\n"));
1288 /* Convert the replace block */
1289 peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
1291 //DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
1292 //printpBlock(stderr, curBlock);
1294 //DFPRINTF((stderr,"replace with labels merged:\n"));
1296 pBlockMergeLabels(currentRule->replace.pb);
1297 //printpBlock(stderr, currentRule->replace.pb);
1299 peepRuleCondition(pr->cond,currentRule);
1301 /* The rule has been converted to pCode. Now allocate
1302 * space for the wildcards */
1304 postinit_pCodeWildBlock(¤tRule->target);
1305 postinit_pCodeWildBlock(¤tRule->replace);
1307 //return; // debug ... don't want to go through all the rules yet
1311 pCodePeep *peepBlock;
1314 peeprules = (_DLL *)peepSnippets;
1315 //fprintf(stderr,"target rules\n");
1317 //fprintf(stderr," rule:\n");
1318 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1319 //printpBlock(stderr, peepBlock->target.pb);
1320 peeprules = peeprules->next;
1322 //fprintf(stderr," ... done\n");
1327 void printpCodeString(FILE *of, pCode *pc, int max)
1331 while(pc && (i++<max)) {
1337 /*-----------------------------------------------------------------*/
1338 /* _DLL * DLL_append */
1340 /* Append a _DLL object to the end of a _DLL (doubly linked list) */
1341 /* If The list to which we want to append is non-existant then one */
1342 /* is created. Other wise, the end of the list is sought out and */
1343 /* a new DLL object is appended to it. In either case, the void */
1344 /* *data is added to the newly created DLL object. */
1345 /*-----------------------------------------------------------------*/
1347 static void * DLL_append(_DLL *list, _DLL *next)
1352 /* If there's no list, then create one: */
1354 next->next = next->prev = NULL;
1359 /* Search for the end of the list. */
1364 /* Now append the new DLL object */
1375 /*-----------------------------------------------------------------
1377 pCode peephole optimization
1380 The pCode "peep hole" optimization is not too unlike the peep hole
1381 optimization in SDCCpeeph.c. The major difference is that here we
1382 use pCode's whereas there we use ASCII strings. The advantage with
1383 pCode's is that we can ascertain flow information in the instructions
1387 <FIX ME> - elaborate...
1389 -----------------------------------------------------------------*/
1393 /*-----------------------------------------------------------------*/
1394 /* pCodeSearchCondition - Search a pCode chain for a 'condition' */
1396 /* return conditions */
1397 /* 1 - The Condition was found for a pCode's input */
1398 /* 0 - No matching condition was found for the whole chain */
1399 /* -1 - The Condition was found for a pCode's output */
1401 /*-----------------------------------------------------------------*/
1402 int pCodeSearchCondition(pCode *pc, unsigned int cond)
1404 //fprintf(stderr,"Checking conditions %d\n",cond);
1407 /* If we reach a function end (presumably an end since we most
1408 probably began the search in the middle of a function), then
1409 the condition was not found. */
1410 if(pc->type == PC_FUNCTION)
1413 if(pc->type == PC_OPCODE) {
1414 //fprintf(stderr," checking conditions of: ");
1415 //pc->print(stderr,pc);
1416 //fprintf(stderr,"\t\tinCond=%d\toutCond=%d\n",PCI(pc)->inCond,PCI(pc)->outCond);
1417 if(PCI(pc)->inCond & cond)
1419 if(PCI(pc)->outCond & cond)
1429 /*-----------------------------------------------------------------
1430 * int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1432 * Compare two pCodeOp's and return 1 if they're the same
1433 *-----------------------------------------------------------------*/
1434 int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
1438 if(!pcops || !pcopd)
1441 fprintf(stderr," Comparing operands %s",
1442 get_op( pcops,NULL,0));
1444 fprintf(stderr," to %s\n",
1445 get_op( pcopd,NULL,0));
1448 if(pcops->type != pcopd->type) {
1449 //fprintf(stderr," - fail - diff types\n");
1450 return 0; // different types
1453 if(pcops->type == PO_LITERAL) {
1455 if((PCOL(pcops)->lit >= 0) && (PCOL(pcops)->lit == PCOL(pcopd)->lit))
1464 n2 = get_op(pcopd,NULL,0);
1466 if( !n2 || strcmp(b,n2)) {
1467 //fprintf(stderr," - fail - diff names: %s, len=%d, %s, len=%d\n",b,strlen(b), n2, strlen(n2) );
1468 return 0; // different names
1471 switch(pcops->type) {
1473 if( PCOR(pcops)->instance != PCOR(pcopd)->instance) {
1474 //fprintf(stderr, " - fail different instances\n");
1482 //fprintf(stderr," - pass\n");
1487 int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1491 /* Check for a label associated with this wild pCode */
1492 // If the wild card has a label, make sure the source code does too.
1493 if(PCI(pcd)->label) {
1494 pCode *pcl = PCI(pcd)->label->pc;
1497 int li = -PCL(pcl)->key;
1499 if(peepBlock->target.vars[li] == NULL) {
1500 if(PCI(pcs)->label) {
1501 DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label));
1504 // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key));
1505 DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li]));
1506 if(PCI(pcs)->label) {
1507 DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label));
1513 if(!PCI(pcs)->label)
1516 labindex = -PCL(pcl)->key;
1517 if(peepBlock->target.vars[labindex] == NULL) {
1518 // First time to encounter this label
1519 peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
1520 DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label));
1523 if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
1524 DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label));
1527 DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex]));
1530 //DFPRINTF((stderr,"destination doesn't have a label\n"));
1535 //DFPRINTF((stderr,"neither src nor dest have labels\n"));
1543 /*-----------------------------------------------------------------*/
1544 /* pCodePeepMatchLine - Compare source and destination pCodes to */
1545 /* see they're the same. */
1547 /* In this context, "source" refers to the coded generated by gen.c*/
1548 /* and "destination" refers to a pcode in a peep rule. If the dest-*/
1549 /* ination has no wild cards, then MatchLine will compare the two */
1550 /* pcodes (src and dest) for a one-to-one match. If the destination*/
1551 /* has wildcards, then those get expanded. When a wild card is */
1552 /* encountered for the first time it autmatically is considered a */
1553 /* match and the object that matches it is referenced in the */
1554 /* variables or opcodes array (depending on the type of match). */
1558 /* *peepBlock - A pointer to the peepBlock that contains the */
1559 /* entire rule to which the destination pcode belongs*/
1560 /* *pcs - a pointer to the source pcode */
1561 /* *pcd - a pointer to the destination pcode */
1564 /* 1 - pcodes match */
1565 /* 0 - pcodes don't match */
1568 /*-----------------------------------------------------------------*/
1570 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
1572 int index; // index into wild card arrays
1574 /* one-for-one match. Here the source and destination opcodes
1575 * are not wild. However, there may be a label or a wild operand */
1578 if(PCI(pcs)->label) {
1579 DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label));
1583 if(pcs->type == pcd->type) {
1585 if(pcs->type == PC_OPCODE) {
1587 /* If the opcodes don't match then the line doesn't match */
1588 if(PCI(pcs)->op != PCI(pcd)->op)
1592 DFPRINTF((stderr,"%s comparing\n",__FUNCTION__));
1593 pcs->print(stderr,pcs);
1594 pcd->print(stderr,pcd);
1597 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
1600 /* Compare the operands */
1601 if(PCI(pcd)->pcop) {
1602 if (PCI(pcd)->pcop->type == PO_WILD) {
1603 index = PCOW(PCI(pcd)->pcop)->id;
1604 //DFPRINTF((stderr,"destination is wild\n"));
1605 #ifdef DEBUG_PCODEPEEP
1606 if (index > peepBlock->nops) {
1607 DFPRINTF((stderr,"%s - variables exceeded\n",__FUNCTION__));
1612 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1613 if(!peepBlock->target.wildpCodeOps[index]) {
1614 peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
1616 //if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
1620 pcs->print(stderr,pcs);
1621 pcd->print(stderr,pcd);
1623 fprintf(stderr, "comparing operands of these instructions, result %d\n",
1624 pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index])
1628 return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
1634 switch(PCI(pcs)->pcop->type) {
1638 n = PCOR(PCI(pcs)->pcop)->r->name;
1642 n = PCI(pcs)->pcop->name;
1645 if(peepBlock->target.vars[index])
1646 return (strcmp(peepBlock->target.vars[index],n) == 0);
1648 DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
1649 peepBlock->target.vars[index] = n;
1654 } else if (PCI(pcd)->pcop->type == PO_LITERAL) {
1655 return pCodeOpCompare(PCI(pcs)->pcop, PCI(pcd)->pcop);
1658 /* FIXME - need an else to check the case when the destination
1659 * isn't a wild card */
1661 /* The pcd has no operand. Lines match if pcs has no operand either*/
1662 return (PCI(pcs)->pcop == NULL);
1666 /* Compare a wild instruction to a regular one. */
1668 if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
1670 index = PCW(pcd)->id;
1672 DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__));
1673 pcs->print(stderr,pcs);
1674 pcd->print(stderr,pcd);
1676 peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
1678 if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) {
1679 DFPRINTF((stderr," Failing because labels don't match\n"));
1683 if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1684 // doesn't match because the wild pcode must be a bit skip
1685 DFPRINTF((stderr," Failing match because bit skip is req\n"));
1686 //pcd->print(stderr,pcd);
1687 //pcs->print(stderr,pcs);
1691 if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
1692 // doesn't match because the wild pcode must *not* be a bit skip
1693 DFPRINTF((stderr," Failing match because shouldn't be bit skip\n"));
1694 //pcd->print(stderr,pcd);
1695 //pcs->print(stderr,pcs);
1699 if(PCW(pcd)->operand) {
1700 PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
1701 if(peepBlock->target.vars[index]) {
1702 int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
1706 DFPRINTF((stderr," (matched)\n"));
1708 DFPRINTF((stderr," (no match: wild card operand mismatch\n"));
1709 DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n",
1710 peepBlock->target.vars[index],
1711 PCI(pcs)->pcop->name));
1716 DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name));
1717 peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
1722 pcs = findNextInstruction(pcs->next);
1724 //DFPRINTF((stderr," (next to match)\n"));
1725 //pcs->print(stderr,pcs);
1726 } else if(pcd->next) {
1727 /* oops, we ran out of code, but there's more to the rule */
1731 return 1; /* wild card matches */
1737 /*-----------------------------------------------------------------*/
1738 /*-----------------------------------------------------------------*/
1739 void pCodePeepClrVars(pCodePeep *pcp)
1746 DFPRINTF((stderr," Clearing peep rule vars\n"));
1747 DFPRINTF((stderr," %d %d %d %d %d %d\n",
1748 pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes,
1749 pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes));
1751 for(i=0;i<pcp->target.nvars; i++)
1752 pcp->target.vars[i] = NULL;
1753 for(i=0;i<pcp->target.nops; i++)
1754 pcp->target.wildpCodeOps[i] = NULL;
1755 for(i=0;i<pcp->target.nwildpCodes; i++)
1756 pcp->target.wildpCodes[i] = NULL;
1758 for(i=0;i<pcp->replace.nvars; i++)
1759 pcp->replace.vars[i] = NULL;
1760 for(i=0;i<pcp->replace.nops; i++)
1761 pcp->replace.wildpCodeOps[i] = NULL;
1762 for(i=0;i<pcp->replace.nwildpCodes; i++)
1763 pcp->replace.wildpCodes[i] = NULL;
1769 /*-----------------------------------------------------------------*/
1770 /* pCodeInsertAfter - splice in the pCode chain starting with pc2 */
1771 /* into the pCode chain containing pc1 */
1772 /*-----------------------------------------------------------------*/
1773 void pCodeInsertAfter(pCode *pc1, pCode *pc2)
1779 pc2->next = pc1->next;
1781 pc1->next->prev = pc2;
1789 /*-----------------------------------------------------------------*/
1790 /* pCodeOpCopy - copy a pcode operator */
1791 /*-----------------------------------------------------------------*/
1792 pCodeOp *pCodeOpCopy(pCodeOp *pcop)
1794 pCodeOp *pcopnew=NULL;
1799 switch(pcop->type) {
1802 //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
1803 pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1804 PCORB(pcopnew)->bit = PCORB(pcop)->bit;
1805 PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
1810 /* Here we expand the wild card into the appropriate type: */
1811 /* By recursively calling pCodeOpCopy */
1812 //DFPRINTF((stderr,"pCodeOpCopy wild\n"));
1813 if(PCOW(pcop)->matched)
1814 pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
1817 pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
1818 pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
1819 //DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
1826 //DFPRINTF((stderr,"pCodeOpCopy label\n"));
1827 pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
1828 PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
1832 pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
1833 PCOI(pcopnew)->index = PCOI(pcop)->index;
1834 PCOI(pcopnew)->offset = PCOI(pcop)->offset;
1835 PCOI(pcopnew)->_const = PCOI(pcop)->_const;
1839 //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
1840 pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
1841 PCOL(pcopnew)->lit = PCOL(pcop)->lit;
1846 pcopnew = newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
1847 PCOR(pcopnew)->r = PCOR(pcop)->r;
1848 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1849 DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
1853 case PO_GPR_REGISTER:
1857 //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
1858 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1859 PCOR(pcopnew)->r = PCOR(pcop)->r;
1860 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1861 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1862 DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
1866 //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
1867 pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
1868 PCOR(pcopnew)->r = PCOR(pcop)->r;
1869 PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
1870 PCOR(pcopnew)->instance = PCOR(pcop)->instance;
1873 DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
1874 case PO_SFR_REGISTER:
1882 //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
1883 pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
1887 pcopnew->type = pcop->type;
1889 pcopnew->name = Safe_strdup(pcop->name);
1891 pcopnew->name = NULL;
1897 /*-----------------------------------------------------------------*/
1898 /* pCodeCopy - copy a pcode */
1899 /*-----------------------------------------------------------------*/
1900 static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert)
1902 pCodeInstruction *new_pci;
1905 new_pci = PCI(newpCode(pci->inverted_op,pci->pcop));
1907 new_pci = PCI(newpCode(pci->op,pci->pcop));
1909 new_pci->pc.pb = pci->pc.pb;
1910 new_pci->from = pci->from;
1911 new_pci->to = pci->to;
1912 new_pci->label = pci->label;
1913 new_pci->pcflow = pci->pcflow;
1915 return PCODE(new_pci);
1918 /*-----------------------------------------------------------------*/
1919 /*-----------------------------------------------------------------*/
1920 void pCodeDeleteChain(pCode *f,pCode *t)
1926 DFPRINTF((stderr,"delete pCode:\n"));
1928 //f->print(stderr,f);
1929 //f->delete(f); this dumps core...
1936 /*-----------------------------------------------------------------*/
1937 /*-----------------------------------------------------------------*/
1938 int pCodePeepMatchRule(pCode *pc)
1940 pCodePeep *peepBlock;
1942 pCodeCSource *pc_cline=NULL;
1946 peeprules = (_DLL *)peepSnippets;
1949 peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
1951 if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
1952 fprintf(stderr, "skipping rule because target pb is NULL\n");
1956 pCodePeepClrVars(peepBlock);
1959 if(IS_PCCOMMENT(pcin))
1960 pc = pcin = findNextInstruction(pcin->next);
1962 pcin = pc = findNextInstruction(pc);
1964 pct = peepBlock->target.pb->pcHead;
1967 pCode *pcr = peepBlock->replace.pb->pcHead;
1968 if(pcr) pct->print(stderr,pcr);
1972 while(pct && pcin) {
1974 if(! (matched = pCodePeepMatchLine(peepBlock, pcin,pct)))
1977 pcin = findNextInstruction(pcin->next);
1980 //DFPRINTF((stderr," matched\n"));
1983 DFPRINTF((stderr," partial match... no more code\n"));
1984 fprintf(stderr," partial match... no more code\n");
1988 DFPRINTF((stderr," end of rule\n"));
1992 if(matched && pcin) {
1994 /* So far we matched the rule up to the point of the conditions .
1995 * In other words, all of the opcodes match. Now we need to see
1996 * if the post conditions are satisfied.
1997 * First we check the 'postFalseCond'. This means that we check
1998 * to see if any of the subsequent pCode's in the pCode chain
1999 * following the point just past where we have matched depend on
2000 * the `postFalseCond' as input then we abort the match
2002 DFPRINTF((stderr," matched rule so far, now checking conditions\n"));
2003 //pcin->print(stderr,pcin);
2005 if (pcin && peepBlock->postFalseCond &&
2006 (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
2009 //fprintf(stderr," condition results = %d\n",pCodeSearchCondition(pcin,peepBlock->postFalseCond));
2012 //if(!matched) fprintf(stderr,"failed on conditions\n");
2021 /* We matched a rule! Now we have to go through and remove the
2022 inefficient code with the optimized version */
2024 DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
2025 printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
2026 DFPRINTF((stderr,"first thing matched\n"));
2027 pc->print(stderr,pc);
2029 DFPRINTF((stderr,"last thing matched\n"));
2030 pcin->print(stderr,pcin);
2035 /* Unlink the original code */
2037 pcprev->next = pcin;
2039 pcin->prev = pc->prev;
2045 /* Converted the deleted pCodes into comments */
2048 pCodeCSource *pc_cline2=NULL;
2053 while(pc && pc!=pcin) {
2055 if(pc->type == PC_OPCODE && PCI(pc)->cline) {
2057 pc_cline2->pc.next = PCODE(PCI(pc)->cline);
2058 pc_cline2 = PCCS(pc_cline2->pc.next);
2060 pc_cline = pc_cline2 = PCI(pc)->cline;
2061 pc_cline->pc.seq = pc->seq;
2065 pCode2str(&buf[2], 254, pc);
2066 pCodeInsertAfter(pcprev, newpCodeCharP(buf));
2067 pcprev = pcprev->next;
2072 pc_cline2->pc.next = NULL;
2077 pCodeDeleteChain(pc,pcin);
2079 /* Generate the replacement code */
2081 pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
2085 /* If the replace pcode is an instruction with an operand, */
2086 /* then duplicate the operand (and expand wild cards in the process). */
2087 if(pcr->type == PC_OPCODE) {
2088 if(PCI(pcr)->pcop) {
2089 /* The replacing instruction has an operand.
2091 if(PCI(pcr)->pcop->type == PO_WILD) {
2092 int index = PCOW(PCI(pcr)->pcop)->id;
2093 //DFPRINTF((stderr,"copying wildopcode\n"));
2094 if(peepBlock->target.wildpCodeOps[index])
2095 pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
2097 DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
2099 pcop = pCodeOpCopy(PCI(pcr)->pcop);
2101 //DFPRINTF((stderr,"inserting pCode\n"));
2102 pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
2103 } else if (pcr->type == PC_WILD) {
2104 if(PCW(pcr)->invertBitSkipInst)
2105 DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
2106 pCodeInsertAfter(pc,
2107 pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
2108 PCW(pcr)->invertBitSkipInst));
2109 } else if (pcr->type == PC_COMMENT) {
2110 pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
2116 DFPRINTF((stderr," NEW Code:"));
2117 if(pc) pc->print(stderr,pc);
2122 /* We have just replaced the inefficient code with the rule.
2123 * Now, we need to re-add the C-source symbols if there are any */
2127 pc = findNextInstruction(pc->next);
2128 PCI(pc)->cline = pc_cline;
2129 pc_cline = PCCS(pc_cline->pc.next);
2136 peeprules = peeprules->next;
2138 DFPRINTF((stderr," no rule matched\n"));