1 /*-------------------------------------------------------------------------
3 pcode.h - 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 -------------------------------------------------------------------------*/
23 #include "common.h" // Include everything in the SDCC src directory
27 // Eventually this will go into device depended files:
28 pCodeOp pc_status = {PO_STATUS, "status"};
29 pCodeOp pc_indf = {PO_INDF, "indf"};
30 pCodeOp pc_fsr = {PO_FSR, "fsr"};
33 //static char *PIC_mnemonics[] = {
34 static char *scpADDLW = "ADDLW";
35 static char *scpADDWF = "ADDWF";
36 static char *scpANDLW = "ANDLW";
37 static char *scpANDWF = "ANDWF";
38 static char *scpBCF = "BCF";
39 static char *scpBSF = "BSF";
40 static char *scpBTFSC = "BTFSC";
41 static char *scpBTFSS = "BTFSS";
42 static char *scpCALL = "CALL";
43 static char *scpCOMF = "COMF";
44 static char *scpCLRF = "CLRF";
45 static char *scpCLRW = "CLRW";
46 static char *scpDECF = "DECF";
47 static char *scpDECFSZ = "DECFSZ";
48 static char *scpGOTO = "GOTO";
49 static char *scpINCF = "INCF";
50 static char *scpINCFSZ = "INCFSZ";
51 static char *scpIORLW = "IORLW";
52 static char *scpIORWF = "IORWF";
53 static char *scpMOVF = "MOVF";
54 static char *scpMOVLW = "MOVLW";
55 static char *scpMOVWF = "MOVWF";
56 static char *scpNEGF = "NEGF";
57 static char *scpRETLW = "RETLW";
58 static char *scpRETURN = "RETURN";
59 static char *scpSUBLW = "SUBLW";
60 static char *scpSUBWF = "SUBWF";
61 static char *scpTRIS = "TRIS";
62 static char *scpXORLW = "XORLW";
63 static char *scpXORWF = "XORWF";
66 static pFile *the_pFile = NULL;
68 /****************************************************************/
69 /****************************************************************/
70 static pBlock *peepSnippets=NULL;
72 /****************************************************************/
73 /* Forward declarations */
74 /****************************************************************/
76 static void unlink(pCode *pc);
77 static void genericAnalyze(pCode *pc);
78 static void AnalyzeGOTO(pCode *pc);
79 static void AnalyzeSKIP(pCode *pc);
80 static void AnalyzeRETURN(pCode *pc);
82 static void genericDestruct(pCode *pc);
83 static void genericPrint(FILE *of,pCode *pc);
85 static void pCodePrintLabel(FILE *of, pCode *pc);
86 static void pCodePrintFunction(FILE *of, pCode *pc);
87 static char *get_op( pCodeInstruction *pcc);
89 void copypCode(FILE *of, char dbName)
96 fprintf(of,";dumping pcode to a file");
98 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
99 if(pb->cmemmap->dbName == dbName)
104 void pcode_test(void)
107 printf("pcode is alive!\n");
115 /* create the file name */
116 strcpy(buffer,srcFileName);
119 if( !(pFile = fopen(buffer, "w" ))) {
120 werror(E_FILE_OPEN_ERR,buffer);
124 fprintf(pFile,"pcode dump\n\n");
126 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
127 fprintf(pFile,"\n\tNew pBlock\n\n");
128 fprintf(pFile,"%s, dbName =%c\n",pb->cmemmap->sname,pb->cmemmap->dbName);
129 printpBlock(pFile,pb);
134 /*-----------------------------------------------------------------*/
135 /* newpCode - create and return a newly initialized pCode */
136 /*-----------------------------------------------------------------*/
137 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop)
139 pCodeInstruction *pci ;
142 _ALLOC(pci,sizeof(pCodeInstruction));
143 pci->pc.analyze = genericAnalyze;
144 pci->pc.destruct = genericDestruct;
145 pci->pc.type = PC_OPCODE;
147 pci->pc.prev = pci->pc.next = NULL;
152 pci->pc.print = genericPrint;
153 pci->pc.from = pci->pc.to = pci->pc.label = NULL;
155 if(pcop && pcop->name)
156 printf("newpCode operand name %s\n",pcop->name);
161 pci->mnemonic = scpANDLW;
167 pci->mnemonic = scpANDWF;
171 pci->mnemonic = scpADDLW;
177 pci->mnemonic = scpADDWF;
181 pci->mnemonic = scpBCF;
185 pci->mnemonic = scpBSF;
189 pci->mnemonic = scpBTFSC;
190 pci->pc.analyze = AnalyzeSKIP;
194 pci->mnemonic = scpBTFSS;
195 pci->pc.analyze = AnalyzeSKIP;
199 pci->mnemonic = scpCALL;
202 pci->mnemonic = scpCOMF;
206 pci->mnemonic = scpCLRF;
210 pci->mnemonic = scpCLRW;
215 pci->mnemonic = scpDECF;
220 pci->mnemonic = scpDECFSZ;
221 pci->pc.analyze = AnalyzeSKIP;
225 pci->mnemonic = scpGOTO;
226 pci->pc.analyze = AnalyzeGOTO;
231 pci->mnemonic = scpINCF;
236 pci->mnemonic = scpINCFSZ;
237 pci->pc.analyze = AnalyzeSKIP;
241 pci->mnemonic = scpIORLW;
246 pci->mnemonic = scpIORWF;
251 pci->mnemonic = scpMOVF;
255 pci->mnemonic = scpMOVLW;
259 pci->mnemonic = scpMOVWF;
262 pci->mnemonic = scpNEGF;
266 pci->mnemonic = scpRETLW;
267 pci->pc.analyze = AnalyzeRETURN;
271 pci->mnemonic = scpRETURN;
272 pci->pc.analyze = AnalyzeRETURN;
275 pci->mnemonic = scpSUBLW;
281 pci->mnemonic = scpSUBWF;
284 pci->mnemonic = scpTRIS;
288 pci->mnemonic = scpXORLW;
293 pci->mnemonic = scpXORWF;
297 pci->pc.print = genericPrint;
304 /*-----------------------------------------------------------------*/
305 /* newPcodeCharP - create a new pCode from a char string */
306 /*-----------------------------------------------------------------*/
308 pCode *newpCodeCharP(char *cP)
313 _ALLOC(pcc,sizeof(pCodeComment));
315 pcc->pc.type = PC_COMMENT;
316 pcc->pc.prev = pcc->pc.next = NULL;
317 pcc->pc.from = pcc->pc.to = pcc->pc.label = NULL;
319 pcc->pc.analyze = genericAnalyze;
320 pcc->pc.destruct = genericDestruct;
321 pcc->pc.print = genericPrint;
324 _ALLOC_ATOMIC(pcc->comment,strlen(cP)+1);
325 strcpy(pcc->comment,cP);
329 return ( (pCode *)pcc);
333 /*-----------------------------------------------------------------*/
334 /* newpCodeGLabel - create a new global label */
335 /*-----------------------------------------------------------------*/
338 pCode *newpCodeFunction(char *mod,char *f)
342 _ALLOC(pcf,sizeof(pCodeFunction));
344 pcf->pc.type = PC_FUNCTION;
345 pcf->pc.prev = pcf->pc.next = NULL;
346 pcf->pc.from = pcf->pc.to = pcf->pc.label = NULL;
348 pcf->pc.analyze = genericAnalyze;
349 pcf->pc.destruct = genericDestruct;
350 pcf->pc.print = pCodePrintFunction;
353 _ALLOC_ATOMIC(pcf->modname,strlen(mod)+1);
354 strcpy(pcf->modname,mod);
359 _ALLOC_ATOMIC(pcf->fname,strlen(f)+1);
360 strcpy(pcf->fname,f);
364 return ( (pCode *)pcf);
369 pCode *newpCodeLabel(int key)
374 _ALLOC(pcl,sizeof(pCodeLabel));
376 pcl->pc.type = PC_LABEL;
377 pcl->pc.prev = pcl->pc.next = NULL;
378 pcl->pc.from = pcl->pc.to = pcl->pc.label = NULL;
380 pcl->pc.analyze = genericAnalyze;
381 pcl->pc.destruct = genericDestruct;
382 pcl->pc.print = pCodePrintLabel;
386 return ( (pCode *)pcl);
390 /*-----------------------------------------------------------------*/
391 /* newpBlock - create and return a pointer to a new pBlock */
392 /*-----------------------------------------------------------------*/
393 pBlock *newpBlock(void)
398 _ALLOC(PpB,sizeof(pBlock));
399 PpB->next = PpB->prev = NULL;
405 /*-----------------------------------------------------------------*/
406 /* newpCodeChain - create a new chain of pCodes */
407 /*-----------------------------------------------------------------*
409 * This function will create a new pBlock and the pointer to the
410 * pCode that is passed in will be the first pCode in the block.
411 *-----------------------------------------------------------------*/
414 pBlock *newpCodeChain(memmap *cm,pCode *pc)
417 pBlock *pB = newpBlock();
419 pB->pcHead = pB->pcTail = pc;
425 /*-----------------------------------------------------------------*/
426 /*-----------------------------------------------------------------*/
428 pCodeOp *newpCodeOp(char *name)
432 _ALLOC(pcop,sizeof(pCodeOp) );
433 pcop->type = PO_NONE;
434 pcop->name = strdup(name);
439 pCodeOp *newpCodeOpLabel(int key)
444 _ALLOC(pcop,sizeof(pCodeOpLabel) );
445 sprintf(s,"_%05d_DS_",key);
446 pcop->type = PO_LABEL;
447 pcop->name = strdup(s);
448 ((pCodeOpLabel *)pcop)->key = key;
453 pCodeOp *newpCodeOpLit(int lit)
459 _ALLOC(pcop,sizeof(pCodeOpLit) );
460 pcop->type = PO_LITERAL;
461 sprintf(s,"0x%02x",lit);
462 _ALLOC_ATOMIC(pcop->name,strlen(s)+1);
463 strcpy(pcop->name,s);
464 ((pCodeOpLit *)pcop)->lit = lit;
469 pCodeOp *newpCodeOpWild(int id)
475 _ALLOC(pcop,sizeof(pCodeOpWild) );
476 pcop->type = PO_WILD;
477 sprintf(s,"%%%d",id);
478 _ALLOC_ATOMIC(pcop->name,strlen(s)+1);
479 strcpy(pcop->name,s);
480 ((pCodeOpWild *)pcop)->id = id;
485 pCodeOp *newpCodeOpBit(char *s, int bit)
489 _ALLOC(pcop,sizeof(pCodeOpBit) );
491 pcop->name = strdup(s);
492 ((pCodeOpBit *)pcop)->bit = bit;
493 ((pCodeOpBit *)pcop)->inBitSpace = 1;
498 /*-----------------------------------------------------------------*/
499 /* addpCode2pBlock - place the pCode into the pBlock linked list */
500 /*-----------------------------------------------------------------*/
501 void addpCode2pBlock(pBlock *pb, pCode *pc)
504 pb->pcTail->next = pc;
505 pc->prev = pb->pcTail;
510 /*-----------------------------------------------------------------*/
511 /* addpBlock - place a pBlock into the pFile */
512 /*-----------------------------------------------------------------*/
513 void addpBlock(pBlock *pb)
517 /* First time called, we'll pass through here. */
518 _ALLOC(the_pFile,sizeof(the_pFile));
519 the_pFile->pbHead = the_pFile->pbTail = pb;
520 the_pFile->functions = NULL;
524 the_pFile->pbTail->next = pb;
525 pb->prev = the_pFile->pbTail;
527 the_pFile->pbTail = pb;
531 /*-----------------------------------------------------------------*/
532 /* printpCode - write the contents of a pCode to a file */
533 /*-----------------------------------------------------------------*/
534 void printpCode(FILE *of, pCode *pc)
545 fprintf(of,"warning - unable to print pCode\n");
548 /*-----------------------------------------------------------------*/
549 /* printpBlock - write the contents of a pBlock to a file */
550 /*-----------------------------------------------------------------*/
551 void printpBlock(FILE *of, pBlock *pb)
561 for(pc = pb->pcHead; pc; pc = pc->next)
566 /*-----------------------------------------------------------------*/
568 /* pCode processing */
570 /* The stuff that follows is very PIC specific! */
575 /*-----------------------------------------------------------------*/
577 static void unlink(pCode *pc)
579 if(pc && pc->prev && pc->next) {
581 pc->prev->next = pc->next;
582 pc->next->prev = pc->prev;
585 static void genericDestruct(pCode *pc)
589 fprintf(stderr,"warning, calling default pCode destructor\n");
593 static char *get_op( pCodeInstruction *pcc)
595 if(pcc && pcc->pcop && pcc->pcop->name)
596 return pcc->pcop->name;
604 op = IC_RESULT(pcc->ic);
607 op = IC_LEFT(pcc->ic);
610 op = IC_RIGHT(pcc->ic);
614 return "get_op bad lrr";
617 return(OP_SYMBOL(op)->rname[0] ? OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name);
622 /*-----------------------------------------------------------------*/
623 /* genericPrint - the contents of a pCode to a file */
624 /*-----------------------------------------------------------------*/
625 static void genericPrint(FILE *of, pCode *pc)
633 fprintf(of,";%s\n", ((pCodeComment *)pc)->comment);
637 // If the opcode has a label, print that first
639 pBranch *pbl = pc->label;
641 if(pbl->pc->type == PC_LABEL)
642 pCodePrintLabel(of, pbl->pc);
647 fprintf(of, "\t%s\t", PCI(pc)->mnemonic);
648 if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
650 if(PCI(pc)->bit_inst) {
651 if(PCI(pc)->pcop->type == PO_BIT) {
652 if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) )
653 fprintf(of,"(%s >> 3), (%s & 7)",
654 PCI(pc)->pcop->name ,
655 PCI(pc)->pcop->name );
657 fprintf(of,"%s,%d", get_op(PCI(pc)), (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
659 fprintf(of,"%s,0 ; ?bug", get_op(PCI(pc)));
660 //PCI(pc)->pcop->t.bit );
663 if(PCI(pc)->pcop->type == PO_BIT) {
664 if( PCI(pc)->num_ops == 2)
665 fprintf(of,"(%s >> 3),%c",PCI(pc)->pcop->name,((PCI(pc)->dest) ? 'F':'W'));
667 fprintf(of,"(1 << (%s & 7))",PCI(pc)->pcop->name);
669 fprintf(of,"%s",get_op(PCI(pc)));
671 if( PCI(pc)->num_ops == 2)
672 fprintf(of,",%c", ( (PCI(pc)->dest) ? 'F':'W'));
678 pBranch *dpb = pc->to; // debug
680 switch ( dpb->pc->type) {
682 fprintf(of, "\t;%s", PCI(dpb->pc)->mnemonic);
685 fprintf(of, "\t;label %d", PCL(dpb->pc)->key);
688 fprintf(of, "\t;function %s", ( (PCF(dpb->pc)->fname) ? (PCF(dpb->pc)->fname) : "[END]"));
703 fprintf(of,"unknown pCode type %d\n",pc->type);
708 /*-----------------------------------------------------------------*/
709 /* pCodePrintFunction - prints function begin/end */
710 /*-----------------------------------------------------------------*/
712 static void pCodePrintFunction(FILE *of, pCode *pc)
718 if( ((pCodeFunction *)pc)->modname)
719 fprintf(of,"F_%s",((pCodeFunction *)pc)->modname);
722 pBranch *exits = pc->to;
724 fprintf(of,"%s\t;Function start\n",PCF(pc)->fname);
730 fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
734 pc->from->pc->type == PC_FUNCTION &&
735 PCF(pc->from->pc)->fname)
736 fprintf(of,"; exit point of %s\n",PCF(pc->from->pc)->fname);
738 fprintf(of,"; exit point [can't find entry point]\n");
741 /*-----------------------------------------------------------------*/
742 /* pCodePrintLabel - prints label */
743 /*-----------------------------------------------------------------*/
745 static void pCodePrintLabel(FILE *of, pCode *pc)
751 fprintf(of,"_%05d_DS_:\n",((pCodeLabel *)pc)->key);
755 /*-----------------------------------------------------------------*/
757 static pBranch * pBranchAppend(pBranch *h, pBranch *n)
773 /*-----------------------------------------------------------------*/
774 /* pBranchLink - given two pcodes, this function will link them */
775 /* together through their pBranches */
776 /*-----------------------------------------------------------------*/
777 static void pBranchLink(pCode *f, pCode *t)
781 // Declare a new branch object for the 'from' pCode.
783 _ALLOC(b,sizeof(pBranch));
784 b->pc = t; // The link to the 'to' pCode.
787 f->to = pBranchAppend(f->to,b);
789 // Now do the same for the 'to' pCode.
791 _ALLOC(b,sizeof(pBranch));
795 t->from = pBranchAppend(t->from,b);
800 /*-----------------------------------------------------------------*/
801 /* pBranchFind - find the pBranch in a pBranch chain that contains */
803 /*-----------------------------------------------------------------*/
804 static pBranch *pBranchFind(pBranch *pb,pCode *pc)
817 /*-----------------------------------------------------------------*/
818 /* pCodeUnlink - Unlink the given pCode from its pCode chain. */
819 /*-----------------------------------------------------------------*/
820 static void pCodeUnlink(pCode *pc)
825 if(!pc->prev || !pc->next) {
826 fprintf(stderr,"unlinking bad pCode in %s:%d\n",__FILE__,__LINE__);
830 /* first remove the pCode from the chain */
831 pc->prev->next = pc->next;
832 pc->next->prev = pc->prev;
834 /* Now for the hard part... */
836 /* Remove the branches */
840 pc1 = pb1->pc; /* Get the pCode that branches to the
841 * one we're unlinking */
843 /* search for the link back to this pCode (the one we're
845 if(pb2 = pBranchFind(pc1->to,pc)) {
846 pb2->pc = pc->to->pc; // make the replacement
848 /* if the pCode we're unlinking contains multiple 'to'
849 * branches (e.g. this a skip instruction) then we need
850 * to copy these extra branches to the chain. */
852 pBranchAppend(pb2, pc->to->next);
861 /*-----------------------------------------------------------------*/
862 /*-----------------------------------------------------------------*/
863 static void genericAnalyze(pCode *pc)
873 // Go through the pCodes that are in pCode chain and link
874 // them together through the pBranches. Note, the pCodes
875 // are linked together as a contiguous stream like the
876 // assembly source code lines. The linking here mimics this
877 // except that comments are not linked in.
879 pCode *npc = pc->next;
881 if(npc->type == PC_OPCODE || npc->type == PC_LABEL) {
891 /*-----------------------------------------------------------------*/
892 /* findLabel - Search the pCode for a particular label */
893 /*-----------------------------------------------------------------*/
894 pCode * findLabel(pCodeOpLabel *pcop_label)
903 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
904 for(pc = pb->pcHead; pc; pc = pc->next) {
905 if(pc->type == PC_LABEL) {
906 if( ((pCodeLabel *)pc)->key == pcop_label->key)
909 if(pc->type == PC_OPCODE) {
912 if(pbr->pc->type == PC_LABEL) {
913 if( ((pCodeLabel *)(pbr->pc))->key == pcop_label->key)
923 fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name);
927 /*-----------------------------------------------------------------*/
928 /* findNextInstruction - given a pCode, find the next instruction */
929 /* in the linked list */
930 /*-----------------------------------------------------------------*/
931 pCode * findNextInstruction(pCode *pc)
935 if(pc->type == PC_OPCODE)
941 fprintf(stderr,"Couldn't find instruction\n");
945 /*-----------------------------------------------------------------*/
946 /* findFunctionEnd - given a pCode find the end of the function */
947 /* that contains it t */
948 /*-----------------------------------------------------------------*/
949 pCode * findFunctionEnd(pCode *pc)
953 if(pc->type == PC_FUNCTION && !(PCF(pc)->fname))
959 fprintf(stderr,"Couldn't find function end\n");
964 /*-----------------------------------------------------------------*/
965 /* AnalyzeLabel - if the pCode is a label, then merge it with the */
966 /* instruction with which it is associated. */
967 /*-----------------------------------------------------------------*/
968 static void AnalyzeLabel(pCode *pc)
976 static void AnalyzeGOTO(pCode *pc)
979 pBranchLink(pc,findLabel( (pCodeOpLabel *) (PCI(pc)->pcop) ));
983 static void AnalyzeSKIP(pCode *pc)
986 pBranchLink(pc,findNextInstruction(pc->next));
987 pBranchLink(pc,findNextInstruction(pc->next->next));
991 static void AnalyzeRETURN(pCode *pc)
994 // branch_link(pc,findFunctionEnd(pc->next));
999 void optimizepBlock(pBlock *pb)
1006 for(pc = pb->pcHead; pc; pc = pc->next)
1010 /*-----------------------------------------------------------------*/
1011 /* pBlockMergeLabels - remove the pCode labels from the pCode */
1012 /* chain and put them into pBranches that are */
1013 /* associated with the appropriate pCode */
1015 /*-----------------------------------------------------------------*/
1016 void pBlockMergeLabels(pBlock *pb)
1019 pCode *pc, *pcnext=NULL;
1024 for(pc = pb->pcHead; pc; pc = pc->next) {
1026 if(pc->type == PC_LABEL) {
1027 if( !(pcnext = findNextInstruction(pc)) )
1028 return; // Couldn't find an instruction associated with this label
1030 // Unlink the pCode label from it's pCode chain
1032 pc->prev->next = pc->next;
1034 pc->next->prev = pc->prev;
1036 // And link it into the instruction's pBranch labels. (Note, since
1037 // it's possible to have multiple labels associated with one instruction
1038 // we must provide a means to accomodate the additional labels. Thus
1039 // the labels are placed into the singly-linked list "label" as
1040 // opposed to being a single member of the pCodeInstruction.)
1042 _ALLOC(pbr,sizeof(pBranch));
1046 pcnext->label = pBranchAppend(pcnext->label,pbr);
1052 /*-----------------------------------------------------------------*/
1053 /* AnalyzepCode - parse the pCode that has been generated and form */
1054 /* all of the logical connections. */
1056 /* Essentially what's done here is that the pCode flow is */
1058 /*-----------------------------------------------------------------*/
1060 void AnalyzepCode(char dbName)
1069 fprintf(stderr," Analyzing pCode");
1071 /* First, merge the labels with the instructions */
1072 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
1073 if(pb->cmemmap->dbName == dbName)
1074 pBlockMergeLabels(pb);
1077 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
1078 if(pb->cmemmap->dbName == dbName)
1082 /* Now build the call tree.
1083 First we examine all of the pCodes for functions.
1086 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
1087 if(pb->cmemmap->dbName == dbName) {
1088 pCode *pc_fstart=NULL;
1089 for(pc = pb->pcHead; pc; pc = pc->next) {
1090 if(pc->type == PC_FUNCTION) {
1091 if (PCF(pc)->fname) {
1092 // Found the beginning of a function.
1093 _ALLOC(pbr,sizeof(pBranch));
1094 pbr->pc = pc_fstart = pc;
1097 the_pFile->functions = pBranchAppend(the_pFile->functions,pbr);
1099 // Found an exit point in a function, e.g. return
1100 // (Note, there may be more than one return per function)
1102 pBranchLink(pc_fstart, pc);
1110 /*-----------------------------------------------------------------*/
1111 /* ispCodeFunction - returns true if *pc is the pCode of a */
1113 /*-----------------------------------------------------------------*/
1114 bool ispCodeFunction(pCode *pc)
1117 if(pc && pc->type == PC_FUNCTION && PCF(pc)->fname)
1123 void printCallTree(FILE *of)
1133 pbr = the_pFile->functions;
1135 fprintf(of,"Call Tree\n");
1138 pCode *pc = pbr->pc;
1139 if(!ispCodeFunction(pc))
1140 fprintf(of,"bug in call tree");
1143 fprintf(of,"Function: %s\n", PCF(pc)->fname);
1145 while(pc->next && !ispCodeFunction(pc->next)) {
1147 if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL)
1148 fprintf(of,"\t%s\n",get_op(PCI(pc)));
1156 /*-----------------------------------------------------------------*/
1158 /*-----------------------------------------------------------------*/
1159 int pCodePeepCompare(pCode *pc, pCodePeep *pcp)
1161 pCode *pcfrom,*pcto;
1164 for( pcto=pcp->target; pcto; pcto=pcto->next) {
1166 pcfrom = findNextInstruction(pcfrom);
1169 (PCI(pcfrom)->op == PCI(pcto)->op ||
1170 PCI(pcto)->op == POC_WILD))
1177 /*-----------------------------------------------------------------*/
1179 /*-----------------------------------------------------------------*/
1180 void pCodePeepSearch(pCodePeep *snippet)
1188 /* compare the chain to the pCode that we've
1189 got so far. If a match is found, then replace
1192 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
1193 for(pc = pb->pcHead; pc; pc = pc->next) {
1194 pCodePeepCompare(pc,snippet);
1202 pBlock *pBlockAppend(pBlock *pb1, pBlock *pb2)
1219 void pCodePeepInit(void)
1225 _ALLOC(peepSnippets,sizeof(pBlock));
1228 pb = newpCodeChain(NULL,newpCodeCharP("; Starting pCode block"));
1230 if(!peepSnippets->next)
1231 peepSnippets->next = pb;
1233 peepSnippets->next->next = pb;
1234 pb->prev = peepSnippets->next;
1236 // now create some sample peep pcodes
1238 addpCode2pBlock( pb, newpCode(POC_MOVWF, newpCodeOpWild(1)) );
1239 addpCode2pBlock( pb, newpCode(POC_MOVFW, newpCodeOpWild(1)) );