}
+
+/*-----------------------------------------------------------------*/
+/* SAFE_snprintf - like snprintf except the string pointer is */
+/* after the string has been printed to. This is */
+/* useful for printing to string as though if it */
+/* were a stream. */
+/*-----------------------------------------------------------------*/
+void SAFE_snprintf(char **str, size_t *size, const char *format, ...)
+{
+ va_list val;
+ int len;
+
+ if(!str || !*str)
+ return;
+
+ va_start(val, format);
+ vsnprintf(*str, *size, format, val);
+ va_end (val);
+
+ len = strlen(*str);
+ *str += len;
+ *size -= len;
+
+}
+
void pCodeInitRegisters(void)
{
}
/*-----------------------------------------------------------------*/
-/* newpCodeChain - create a new chain of pCodes */
+/* newpCodeChai0n - create a new chain of pCodes */
/*-----------------------------------------------------------------*
*
* This function will create a new pBlock and the pointer to the
/*-----------------------------------------------------------------*/
void addpCode2pBlock(pBlock *pb, pCode *pc)
{
-
- pb->pcTail->next = pc;
- pc->prev = pb->pcTail;
- pc->next = NULL;
- pc->pb = pb;
- pb->pcTail = pc;
+ if(!pb->pcHead) {
+ /* If this is the first pcode to be added to a block that
+ * was initialized with a NULL pcode, then go ahead and
+ * make this pcode the head and tail */
+ pb->pcHead = pb->pcTail = pc;
+ } else {
+ pb->pcTail->next = pc;
+ pc->prev = pb->pcTail;
+ pc->next = NULL;
+ pc->pb = pb;
+ pb->pcTail = pc;
+ }
}
/*-----------------------------------------------------------------*/
r = setFirstItem(pb->registers);
while (r) {
- fprintf(of," %s\n",r->name);
r = setNextItem(pb->registers);
}
}
case PO_FSR:
case PO_GPR_TEMP:
r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
- fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
+ //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
pBlockRegs(stderr,pcc->pc.pb);
return r->name;
fprintf(of,"pcodeopprint\n");
}
+char *pCode2str(char *str, int size, pCode *pc)
+{
+ char *s = str;
+
+ switch(pc->type) {
+
+ case PC_OPCODE:
+
+ SAFE_snprintf(&s,&size, "\t%s\t", PCI(pc)->mnemonic);
+
+ if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
+
+ if(PCI(pc)->bit_inst) {
+ if(PCI(pc)->pcop->type == PO_BIT) {
+ if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) )
+ SAFE_snprintf(&s,&size,"(%s >> 3), (%s & 7)",
+ PCI(pc)->pcop->name ,
+ PCI(pc)->pcop->name );
+ else
+ SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),
+ (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
+ } else
+ SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op(PCI(pc)));
+ //PCI(pc)->pcop->t.bit );
+ } else {
+
+ if(PCI(pc)->pcop->type == PO_BIT) {
+ if( PCI(pc)->num_ops == 2)
+ SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W'));
+ else
+ SAFE_snprintf(&s,&size,"(1 << (%s & 7))",get_op(PCI(pc)));
+
+ }else {
+ SAFE_snprintf(&s,&size,"%s",get_op(PCI(pc)));
+
+ if( PCI(pc)->num_ops == 2)
+ SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->dest) ? 'F':'W'));
+ }
+ }
+
+ }
+ break;
+
+ case PC_COMMENT:
+ /* assuming that comment ends with a \n */
+ SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment);
+ break;
+
+ case PC_LABEL:
+ SAFE_snprintf(&s,&size,";label=%s, key=%d\n",PCL(pc)->label,PCL(pc)->key);
+ break;
+ case PC_FUNCTION:
+ SAFE_snprintf(&s,&size,";modname=%s,function=%s: id=%d\n",PCF(pc)->modname,PCF(pc)->fname);
+ break;
+ case PC_WILD:
+ SAFE_snprintf(&s,&size,";\tWild opcode: id=%d\n",PCW(pc)->id);
+ break;
+
+ }
+
+ return str;
+
+}
+
/*-----------------------------------------------------------------*/
/* genericPrint - the contents of a pCode to a file */
/*-----------------------------------------------------------------*/
}
}
- fprintf(of, "\t%s\t", PCI(pc)->mnemonic);
- if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
- if(PCI(pc)->bit_inst) {
- if(PCI(pc)->pcop->type == PO_BIT) {
- if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) )
- fprintf(of,"(%s >> 3), (%s & 7)",
- PCI(pc)->pcop->name ,
- PCI(pc)->pcop->name );
- else
- fprintf(of,"%s,%d", get_op(PCI(pc)), (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
- } else
- fprintf(of,"%s,0 ; ?bug", get_op(PCI(pc)));
- //PCI(pc)->pcop->t.bit );
- } else {
-
- if(PCI(pc)->pcop->type == PO_BIT) {
- if( PCI(pc)->num_ops == 2)
- fprintf(of,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W'));
- else
- fprintf(of,"(1 << (%s & 7))",get_op(PCI(pc)));
-
-/*
- if( PCI(pc)->num_ops == 2)
- fprintf(of,"(%s >> 3),%c",PCI(pc)->pcop->name,((PCI(pc)->dest) ? 'F':'W'));
- else
- fprintf(of,"(1 << (%s & 7))",PCI(pc)->pcop->name);
-*/
- }else {
- fprintf(of,"%s",get_op(PCI(pc)));
+ {
+ char str[256];
+
+ pCode2str(str, 256, pc);
- if( PCI(pc)->num_ops == 2)
- fprintf(of,",%c", ( (PCI(pc)->dest) ? 'F':'W'));
- }
- }
+ fprintf(of,"%s",str);
}
{
case PC_WILD:
fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
+ if(pc->label)
+ pCodePrintLabel(of, pc->label->pc);
+
if(PCW(pc)->operand) {
fprintf(of,";\toperand ");
pCodeOpPrint(of,PCW(pc)->operand );
else if (PCL(pc)->key >=0)
fprintf(of,"_%05d_DS_:\n",PCL(pc)->key);
else
- fprintf(of,";wild card label\n");
+ fprintf(of,";wild card label: id=%d\n",-PCL(pc)->key);
}
/*-----------------------------------------------------------------*/
{
while(pc) {
- if(pc->type == PC_OPCODE)
+ if((pc->type == PC_OPCODE) || (pc->type == PC_WILD))
return pc;
pc = pc->next;
pCode * findNextInstruction(pCode *pc);
char *Safe_strdup(char *str);
int getpCode(char *mnem,int dest);
+void pBlockMergeLabels(pBlock *pb);
+char *pCode2str(char *str, int size, pCode *pc);
+
extern pCodeInstruction *pic14Mnemonics[];
static pBlock *curBlock=NULL;
+/****************************************************************/
+/* */
+/* max wild cards in a peep rule */
+/* */
+/****************************************************************/
+
+static int sMaxWildVar = 0;
+static int sMaxWildMnem = 0;
+
+
typedef struct pCodeToken
{
int tt; // token type;
typedef enum {
+ PCT_NULL=0,
PCT_SPACE=1,
PCT_PERCENT,
PCT_COLON,
PCP_STR,
PCP_WILDVAR,
PCP_WILDSTR,
- PCP_COMMA
+ PCP_COMMA,
+ PCP_COMMENT
} pCodePatterns;
static char pcpat_label[] = {PCT_PERCENT, PCT_NUMBER, PCT_COLON, 0};
static char pcpat_wildString[] = {PCT_PERCENT, PCT_STRING, 0};
static char pcpat_wildVar[] = {PCT_PERCENT, PCT_NUMBER, 0};
static char pcpat_comma[] = {PCT_COMMA, 0};
+static char pcpat_comment[] = {PCT_COMMENT, 0};
typedef struct pcPattern {
{PCP_STR, pcpat_string, NULL},
{PCP_WILDVAR, pcpat_wildVar, NULL},
{PCP_COMMA, pcpat_comma, NULL},
+ {PCP_COMMENT, pcpat_comment, NULL},
{PCP_NUMBER, pcpat_number, NULL}
};
// Assembly Line Token
typedef enum {
ALT_LABEL=1,
+ ALT_COMMENT,
ALT_MNEM0,
ALT_MNEM0A,
ALT_MNEM1,
ALT_MNEM2A
} altPatterns;
+static char alt_comment[] = { PCP_COMMENT, 0};
static char alt_label[] = { PCP_LABEL, 0};
static char alt_mnem0[] = { PCP_STR, 0};
static char alt_mnem0a[] = { PCP_WILDVAR, 0};
static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
static void * cvt_altpat_label(void *pp);
+static void * cvt_altpat_comment(void *pp);
static void * cvt_altpat_mnem0(void *pp);
static void * cvt_altpat_mnem0a(void *pp);
static void * cvt_altpat_mnem1(void *pp);
pcPattern altArr[] = {
{ALT_LABEL, alt_label, cvt_altpat_label},
+ {ALT_COMMENT, alt_comment,cvt_altpat_comment},
{ALT_MNEM2A, alt_mnem2a, cvt_altpat_mnem2a},
{ALT_MNEM2, alt_mnem2, cvt_altpat_mnem2},
{ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
parsedPattern *p = pp;
fprintf(stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n);
- return newpCodeOpLabel(-p->pct[1].tok.n);
+ return newpCodeLabel(-p->pct[1].tok.n);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_comment - convert assembly line type to a comment */
+/* INPUT: pointer to the parsedPattern */
+/* */
+/* pp[0] - comment */
+/* */
+/* */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_comment(void *pp)
+{
+ parsedPattern *p = pp;
+
+ fprintf(stderr,"altpat_comment = %s\n",p->pct[0].tok.s);
+ return newpCodeCharP(p->pct[0].tok.s);
}
fprintf(stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n);
+ /* Save the index of the maximum wildcard mnemonic */
+
+ if(p[0].pct[1].tok.n > sMaxWildVar)
+ sMaxWildMnem = p[0].pct[1].tok.n;
+
return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
}
}
if(pic14Mnemonics[opcode]->bit_inst)
- pcosubtype = newpCodeOp(NULL,PO_BIT);
+ pcosubtype = newpCodeOpBit(NULL,-1);
else
pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
pci = PCI(newpCode(opcode,
newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
+ /* Save the index of the maximum wildcard variable */
+ if(p[1].pct[1].tok.n > sMaxWildVar)
+ sMaxWildVar = p[1].pct[1].tok.n;
+
if(!pci)
fprintf(stderr,"couldn't find mnemonic\n");
pci = PCI(newpCode(opcode,
newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
+ /* Save the index of the maximum wildcard variable */
+ if(p[1].pct[1].tok.n > sMaxWildVar)
+ sMaxWildVar = p[1].pct[1].tok.n;
+
if(!pci)
fprintf(stderr,"couldn't find mnemonic\n");
}
/*-----------------------------------------------------------------*/
+/* tokenizeLineNode - Convert a string (of char's) that was parsed */
+/* by SDCCpeeph.c into a string of tokens. */
+/* */
+/* */
+/* The tokenizer is of the classic type. When an item is encounterd*/
+/* it is converted into a token. The token is a structure that */
+/* encodes the item's type and it's value (when appropriate). */
+/* */
+/* Accepted token types: */
+/* SPACE NUMBER STRING % : , ; */
+/* */
+/* */
+/* */
/*-----------------------------------------------------------------*/
-static void parseLineNode(char *ln)
+static void tokenizeLineNode(char *ln)
{
- tokIdx = 0;
+ tokIdx = 0; // Starting off at the beginning
+ tokArr[0].tt = PCT_NULL; // and assume invalid character for first token.
if(!ln || !*ln)
return;
while(*ln) {
if(isspace(*ln)) {
+ // add a SPACE token and eat the extra spaces.
tokArr[tokIdx++].tt = PCT_SPACE;
while (isspace (*ln))
ln++;
case ';':
tokArr[tokIdx].tok.s = Safe_strdup(ln);
tokArr[tokIdx++].tt = PCT_COMMENT;
+ tokArr[tokIdx].tt = PCT_NULL;
return;
case ',':
tokArr[tokIdx++].tt = PCT_COMMA;
buffer[i] = 0;
tokArr[tokIdx].tok.s = Safe_strdup(buffer);
- //fprintf(stderr," string %s",tokArr[tokIdx].tok.s);
-
tokArr[tokIdx++].tt = PCT_STRING;
}
}
+
+ /* Advance to next character in input string .
+ * Note, if none of the tests passed above, then
+ * we effectively ignore the `bad' character.
+ * Since the line has already been parsed by SDCCpeeph,
+ * chance are that there are no invalid characters... */
+
ln++;
+
}
tokArr[tokIdx].tt = 0;
fputc(':',stderr);
break;
case PCT_COMMA:
- fprintf(stderr, " com ");
- fputc(',',stderr);
+ fprintf(stderr, " comma , ");
break;
case PCT_COMMENT:
+ fprintf(stderr, " comment ");
+ //fprintf(stderr,"%s",tokArr[i].tok.s);
+ break;
case PCT_STRING:
fprintf(stderr, " str ");
//fprintf(stderr,"%s",tokArr[i].tok.s);
case PCT_NUMBER:
fprintf(stderr, " num ");
//fprintf(stderr,"%d",tokArr[i].tok.n);
-
+ break;
+ case PCT_NULL:
+ fprintf(stderr, " null ");
}
}
}
/*-----------------------------------------------------------------*/
+/* parseTokens - convert the tokens corresponding to a single line */
+/* of a peep hole assembly into a pCode object. */
+/* */
+/* */
+/* */
+/* */
+/* This is a simple parser that looks for strings of the type */
+/* allowed in the peep hole definition file. Essentially the format*/
+/* is the same as a line of assembly: */
+/* */
+/* label: mnemonic op1, op2, op3 ; comment */
+/* */
+/* Some of these items aren't present. It's the job of the parser */
+/* to determine which are and convert those into the appropriate */
+/* pcode. */
/*-----------------------------------------------------------------*/
-void dumpTokens(void)
+void parseTokens(void)
{
unsigned i;
pCode *pc;
for(i=0; i<=tokIdx; i++)
dump1Token(tokArr[i].tt);
-
fputc('\n',stderr);
{
lpcpIdx=0;
matching = 0;
- //fprintf(stderr,"ltokIdx = %d\n",ltokIdx);
if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
&& (advTokIdx(<okIdx, 1)) ) // eat space
do {
j = pcComparePattern(&tokArr[ltokIdx], pcpArr[lpcpIdx].tokens, tokIdx +1);
if( j ) {
- //fprintf(stderr,"found token pattern match\n");
+
switch(pcpArr[lpcpIdx].pt) {
case PCP_LABEL:
if(state == PS_START){
if(pc && pc->print)
pc->print(stderr,pc);
//if(pc && pc->destruct) pc->destruct(pc); dumps core?
+ if(curBlock && pc)
+ addpCode2pBlock(curBlock, pc);
}
j += c;
}
}
+/*-----------------------------------------------------------------*/
+/* */
+/*-----------------------------------------------------------------*/
+void peepRuleBlock2pCodeBlock( lineNode *ln)
+{
+
+ if(!ln)
+ return;
+
+ for( ; ln; ln = ln->next) {
+
+ fprintf(stderr,"%s\n",ln->line);
+
+ tokenizeLineNode(ln->line);
+ parseTokens();
+
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* peepRuleCondition */
+/*-----------------------------------------------------------------*/
+static void peepRuleCondition(char *cond)
+{
+ if(!cond)
+ return;
+
+ fprintf(stderr,"\nCondition: %s\n",cond);
+
+ /* brute force compares for now */
+
+ if(STRCASECMP(cond, "NZ") == 0) {
+ fprintf(stderr,"found NZ\n");
+ curPeep->postFalseCond = PCC_Z;
+
+ }
+
+}
/*-----------------------------------------------------------------*/
/* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
/* pCode. */
void peepRules2pCode(peepRule *rules)
{
peepRule *pr;
- lineNode *ln;
pCodePeepSnippets *pcps;
+ /* The rules are in a linked-list. Each rule has two portions */
+ /* There's the `target' and there's the `replace'. The target */
+ /* is compared against the SDCC generated code and if it */
+ /* matches, it gets replaced by the `replace' block of code. */
+ /* */
+ /* Here we loop through each rule and convert the target's and*/
+ /* replace's into pCode target and replace blocks */
+
for (pr = rules; pr; pr = pr->next) {
+
fprintf(stderr,"\nRule:\n\n");
pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
curPeep = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
- //curPeep->target = curPeep->replace = NULL;
- curPeep->vars = NULL; curPeep->wildpCodes = NULL;
+
+ curPeep->vars = NULL;
+ curPeep->wildpCodes = NULL; curPeep->wildpCodeOps = NULL;
+ curPeep->postFalseCond = PCC_NONE;
+ curPeep->postTrueCond = PCC_NONE;
+
peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL);
+ sMaxWildVar = 0;
+ sMaxWildMnem = 0;
- for(ln = pr->match; ln; ln = ln->next) {
+ /* Convert the target block */
+ peepRuleBlock2pCodeBlock(pr->match);
- fprintf(stderr,"%s\n",ln->line);
+ fprintf(stderr,"finished target, here it is in pcode form:\n");
+ printpBlock(stderr, curBlock);
- parseLineNode(ln->line);
- dumpTokens();
-
- }
+ fprintf(stderr,"target with labels merged:\n");
+ pBlockMergeLabels(curBlock);
+ printpBlock(stderr, curBlock);
fprintf(stderr,"\nReplaced by:\n");
+
curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL);
- for(ln = pr->replace; ln; ln = ln->next)
- fprintf(stderr,"%s\n",ln->line);
+ /* Convert the replace block */
+ peepRuleBlock2pCodeBlock(pr->replace);
- if(pr->cond)
- fprintf(stderr,"\nCondition: %s\n",pr->cond);
+ fprintf(stderr,"finished replace block, here it is in pcode form:\n");
+ printpBlock(stderr, curBlock);
- return;
+ fprintf(stderr,"replace with labels merged:\n");
+ pBlockMergeLabels(curBlock);
+ printpBlock(stderr, curBlock);
+
+ peepRuleCondition(pr->cond);
+
+ /* The rule has been converted to pCode. Now allocate
+ * space for the wildcards */
+
+ ++sMaxWildVar;
+ curPeep->nvars = sMaxWildVar;
+ curPeep->vars = Safe_calloc(sMaxWildVar, sizeof(char *));
+
+ curPeep->nops = sMaxWildVar;
+ curPeep->wildpCodeOps = Safe_calloc(sMaxWildVar, sizeof(pCodeOp *));
+
+ curPeep->nwildpCodes = ++sMaxWildMnem;
+ curPeep->wildpCodes = Safe_calloc(sMaxWildMnem, sizeof(char *));
+
+
+ //return; // debug ... don't want to go through all the rules yet
}
}
/* Declare a peep code snippet */
/* <FIXME> do I really need a separate struct just to DLL the snippets? */
/* e.g. I could put the DLL into the pCodePeep structure */
+
+ /*
+
+ target:
+
+ movwf %1
+ movf %1,w
+
+ replace:
+
+ movwf %1
+
+ Condition:
+ false condition - PCC_Z (Z bit is not used as input to subsequent code)
+ true condition - none
+ */
pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
pcp = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
replace:
btfss %0
- %1: %4
%3
+ %1: %4
The %3 and %4 are wild opcodes. Since the opcodes
are stored in a different array than the wild operands,
fprintf(stderr,"destination is wild\n");
#ifdef DEBUG_PCODEPEEP
- if (index > peepBlock->nvars) {
+ if (index > peepBlock->nops) {
fprintf(stderr,"%s - variables exceeded\n",__FUNCTION__);
exit(1);
}
#endif
PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
+ if(!peepBlock->wildpCodeOps[index]) {
+ peepBlock->wildpCodeOps[index] = PCI(pcs)->pcop;
+
+ //if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
+
+ }
{
char *n;
- if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
+ if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
n = PCOR(PCI(pcs)->pcop)->r->name;
else
n = PCI(pcs)->pcop->name;
/* 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(pcd->label) {
+ pCode *pcl;
+
if(!pcs->label)
return 0;
- labindex = PCOW(PCW(pcd)->label)->id;
+ pcl = pcd->label->pc;
+
+ labindex = PCOW(pcl)->id;
if(peepBlock->vars[labindex] == NULL) {
// First time to encounter this label
peepBlock->vars[labindex] = PCL(pcs->label->pc)->label;
}
fprintf(stderr,"matched a label\n");
}
-
- }
+ } else
+ fprintf(stderr,"wild card doesn't have a label\n");
if(PCW(pcd)->operand) {
PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
if(!pcp)
return;
- for(i=0;i<pcp->nvars; i++)
+ for(i=0;i<pcp->nvars; i++) {
pcp->vars[i] = NULL;
-
+ pcp->wildpCodeOps[i] = NULL;
+ }
}
/*-----------------------------------------------------------------*/
+/* pCodeInsertAfter - splice in the pCode chain starting with pc2 */
+/* into the pCode chain containing pc1 */
/*-----------------------------------------------------------------*/
void pCodeInsertAfter(pCode *pc1, pCode *pc2)
{
if(pc1->next)
pc1->next->prev = pc2;
+ pc2->pb = pc1->pb;
pc2->prev = pc1;
pc1->next = pc2;
switch(pcop->type) {
case PO_CRY:
case PO_BIT:
+ fprintf(stderr,"pCodeOpCopy bit\n");
pcopnew = Safe_calloc(1,sizeof(pCodeOpBit) );
PCOB(pcopnew)->bit = PCOB(pcop)->bit;
PCOB(pcopnew)->inBitSpace = PCOB(pcop)->inBitSpace;
case PO_WILD:
/* Here we expand the wild card into the appropriate type: */
/* By recursively calling pCodeOpCopy */
+ fprintf(stderr,"pCodeOpCopy wild\n");
if(PCOW(pcop)->matched)
pcopnew = pCodeOpCopy(PCOW(pcop)->matched);
else {
break;
case PO_LABEL:
+ fprintf(stderr,"pCodeOpCopy label\n");
pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
break;
case PO_LITERAL:
case PO_IMMEDIATE:
+ fprintf(stderr,"pCodeOpCopy lit\n");
pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
PCOL(pcopnew)->lit = PCOL(pcop)->lit;
break;
case PO_GPR_REGISTER:
case PO_GPR_TEMP:
- case PO_SFR_REGISTER:
+ fprintf(stderr,"pCodeOpCopy GPR register\n");
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcopnew)->r = PCOR(pcop)->r;
+ PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
+ fprintf(stderr," register index %d\n", PCOR(pcop)->r->rIdx);
+ break;
+
case PO_DIR:
+ fprintf(stderr,"pCodeOpCopy PO_DIR\n");
+ case PO_SFR_REGISTER:
case PO_STR:
case PO_NONE:
case PO_W:
case PO_FSR:
case PO_INDF:
+ fprintf(stderr,"pCodeOpCopy register type %d\n", pcop->type);
pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
}
{
pCode *pc;
+
while(f && f!=t) {
fprintf(stderr,"delete pCode:\n");
pc = f->next;
f->print(stderr,f);
- //f->delete(f);
+ //f->delete(f); this dumps core...
+
f = pc;
+
}
}
pcprev = pc->prev;
pcprev->next = pcin;
pcin->prev = pc->prev;
+
+ {
+ /* DEBUG */
+ /* Converted the deleted pCodes into comments */
+
+ char buf[256];
+
+ buf[0] = ';';
+ buf[1] = '#';
+
+ while(pc && pc!=pcin) {
+ pCode2str(&buf[2], 254, pc);
+ pCodeInsertAfter(pcprev, newpCodeCharP(buf));
+ pcprev = pcprev->next;
+ pc = pc->next;
+ }
+ }
+
pCodeDeleteChain(pc,pcin);
/* Generate the replacement code */
/* If the replace pcode is an instruction with an operand, */
/* then duplicate the operand (and expand wild cards in the process). */
if(pcr->type == PC_OPCODE) {
- if(PCI(pcr)->pcop)
- pcop = pCodeOpCopy(PCI(pcr)->pcop);
+ if(PCI(pcr)->pcop) {
+ /* The replacing instruction has an operand.
+ * Is it wild? */
+ if(PCI(pcr)->pcop->type == PO_WILD) {
+ int index = PCOW(PCI(pcr)->pcop)->id;
+ fprintf(stderr,"copying wildopcode\n");
+ if(peepBlock->wildpCodeOps[index])
+ pcop = pCodeOpCopy(peepBlock->wildpCodeOps[index]);
+ else
+ fprintf(stderr,"error, wildopcode in replace but not source?\n");
+ } else
+ pcop = pCodeOpCopy(PCI(pcr)->pcop);
+ }
fprintf(stderr,"inserting pCode\n");
pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
} else if (pcr->type == PC_WILD) {
pCodeInsertAfter(pc,peepBlock->wildpCodes[PCW(pcr)->id]);
+ } else if (pcr->type == PC_COMMENT) {
+ pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
}