+
+
+ //-------------
+
+ /* Now for another peep example */
+ pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
+ pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
+ peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
+
+ {
+ pCodeOp *pcw;
+
+ pcw = newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER));
+
+ pb = newpCodeChain(NULL, newpCode(POC_MOVWF, pcw));
+ addpCode2pBlock( pb, newpCode(POC_MOVWF, pcw));
+
+ pcp->target = pb;
+
+ pb = newpCodeChain(NULL, newpCode(POC_MOVWF, pcw));
+
+ pcp->replace = pb;
+
+ /* Allocate space to store pointers to the wildcard variables */
+ pcp->nvars = 1;
+ pcp->vars = Safe_calloc(pcp->nvars, sizeof(char *));
+ pcp->nwildpCodes = 0;
+ pcp->wildpCodes = NULL;
+
+ pcp->postFalseCond = PCC_NONE;
+ pcp->postTrueCond = PCC_NONE;
+ }
+
+
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* pCodeSearchCondition - Search a pCode chain for a 'condition' */
+/* */
+/* return conditions */
+/* 1 - The Condition was found for a pCode's input */
+/* 0 - No matching condition was found for the whole chain */
+/* -1 - The Condition was found for a pCode's output */
+/* */
+/*-----------------------------------------------------------------*/
+int pCodeSearchCondition(pCode *pc, unsigned int cond)
+{
+
+ while(pc) {
+
+ /* If we reach a function end (presumably an end since we most
+ probably began the search in the middle of a function), then
+ the condition was not found. */
+ if(pc->type == PC_FUNCTION)
+ return 0;
+
+ if(pc->type == PC_OPCODE) {
+ if(PCI(pc)->inCond & cond)
+ return 1;
+ if(PCI(pc)->outCond & cond)
+ return -1;
+ }
+
+ pc = pc->next;
+ }
+
+ return 0;
+}
+/*-----------------------------------------------------------------*/
+/* pCodePeepMatchLine - Compare source and destination pCodes to */
+/* see they're the same. */
+/*-----------------------------------------------------------------*/
+int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
+{
+ int index; // index into wild card arrays
+
+ if(pcs->type == pcd->type) {
+
+ if(pcs->type == PC_OPCODE) {
+
+ /* If the opcodes don't match then the line doesn't match */
+ if(PCI(pcs)->op != PCI(pcd)->op)
+ return 0;
+
+ fprintf(stderr,"%s comparing\n",__FUNCTION__);
+ pcs->print(stderr,pcs);
+ pcd->print(stderr,pcd);
+
+ /* Compare the operands */
+ if(PCI(pcd)->pcop) {
+ if (PCI(pcd)->pcop->type == PO_WILD) {
+ index = PCOW(PCI(pcd)->pcop)->id;
+
+#ifdef DEBUG_PCODEPEEP
+ if (index > peepBlock->nvars) {
+ fprintf(stderr,"%s - variables exceeded\n",__FUNCTION__);
+ exit(1);
+ }
+#endif
+ if(peepBlock->vars[index])
+ return (strcmp(peepBlock->vars[index],PCI(pcs)->pcop->name) == 0);
+ else {
+ peepBlock->vars[index] = PCI(pcs)->pcop->name;
+ return 1;
+ }
+ }
+ } else
+ /* The pcd has no operand. Lines match if pcs has no operand either*/
+ return (PCI(pcs)->pcop == NULL);
+ }
+ }
+
+
+ if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
+
+ int labindex;
+
+ index = PCW(pcd)->id;
+
+ fprintf(stderr,"%s comparing wild cards\n",__FUNCTION__);
+ pcs->print(stderr,pcs);
+ pcd->print(stderr,pcd);
+
+ peepBlock->wildpCodes[PCW(pcd)->id] = pcs;
+
+ /* Check for a label associated with this wild pCode */
+ // If the wild card has a label, make sure the source code does too.
+ if(PCW(pcd)->label) {
+ if(!pcs->label)
+ return 0;
+
+ labindex = PCOW(PCW(pcd)->label)->id;
+ if(peepBlock->vars[labindex] == NULL) {
+ // First time to encounter this label
+ peepBlock->vars[labindex] = PCL(pcs->label->pc)->label;
+ fprintf(stderr,"first time for a label\n");
+ } else {
+ if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) {
+ fprintf(stderr,"labels don't match\n");
+ return 0;
+ }
+ fprintf(stderr,"matched a label\n");
+ }
+
+ }
+
+ if(PCW(pcd)->operand) {
+ if(peepBlock->vars[index]) {
+ int i = (strcmp(peepBlock->vars[index],PCI(pcs)->pcop->name) == 0);
+ if(i)
+ fprintf(stderr," (matched)\n");
+ else {
+ fprintf(stderr," (no match: wild card operand mismatch\n");
+ fprintf(stderr," peepblock= %s, pcodeop= %s\n",
+ peepBlock->vars[index],
+ PCI(pcs)->pcop->name);
+ }
+ return i;
+ } else {
+ peepBlock->vars[index] = PCI(pcs)->pcop->name;
+ return 1;
+ }
+ }
+
+ pcs = findNextInstruction(pcs->next);
+ fprintf(stderr," (next to match)\n");
+ pcs->print(stderr,pcs);
+ return 1; /* wild card matches */
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void pCodePeepClrVars(pCodePeep *pcp)
+{
+
+ int i;
+
+ for(i=0;i<pcp->nvars; i++)
+ pcp->vars[i] = NULL;
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void pCodeInsertAfter(pCode *pc1, pCode *pc2)
+{
+
+ if(!pc1 || !pc2)
+ return;
+
+ pc2->next = pc1->next;
+ if(pc1->next)
+ pc1->next->prev = pc2;
+
+ pc2->prev = pc1;
+ pc1->next = pc2;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* pCodeOpCopy - copy a pcode operator */
+/*-----------------------------------------------------------------*/
+static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
+{
+ pCodeOp *pcopnew=NULL;
+
+ if(!pcop)
+ return NULL;
+
+ switch(pcop->type) {
+ case PO_CRY:
+ case PO_BIT:
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpBit) );
+ PCOB(pcopnew)->bit = PCOB(pcop)->bit;
+ PCOB(pcopnew)->inBitSpace = PCOB(pcop)->inBitSpace;
+
+ break;
+
+ case PO_WILD:
+ /* Here we expand the wild card into the appropriate type: */
+ /* By recursively calling pCodeOpCopy */
+ pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
+ pcopnew->name = Safe_strdup(PCOW(pcop)->pcp->vars[PCOW(pcop)->id]);
+ return pcopnew;
+ break;
+
+ case PO_LABEL:
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
+ PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
+ break;
+
+ case PO_LITERAL:
+ case PO_IMMEDIATE:
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
+ PCOL(pcopnew)->lit = PCOL(pcop)->lit;
+ break;
+
+ case PO_GPR_REGISTER:
+ case PO_SFR_REGISTER:
+ case PO_DIR:
+ case PO_STR:
+ case PO_NONE:
+ case PO_W:
+ case PO_STATUS:
+ case PO_FSR:
+ case PO_INDF:
+
+ pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
+