AnalyzeRETURN,
genericDestruct,
genericPrint},
- POC_RETLW,
+ POC_RETURN,
"RETURN",
NULL, // operand
0, // num ops
mnemonics_initialized = 1;
}
-int getpCode(char *mnem)
+int getpCode(char *mnem,int dest)
{
pCodeInstruction *pci;
while(pci) {
- if(strcasecmp(pci->mnemonic, mnem) == 0)
- return(pci->op);
+ if(strcasecmp(pci->mnemonic, mnem) == 0) {
+ if((pci->num_ops <= 1) || (pci->dest == dest))
+ return(pci->op);
+ }
+
pci = hTabNextItemWK (pic14MnemonicsHash);
}
/* line (of assembly code) is declared matched. Note that the */
/* operand may be wild too. */
/* */
+/* Note, a wild instruction is specified just like a wild var: */
+/* %4 ; A wild instruction, */
+/* See the peeph.def file for additional examples */
+/* */
/*-----------------------------------------------------------------*/
pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label)
pcw->pc.destruct = genericDestruct;
pcw->pc.print = genericPrint;
- pcw->id = pCodeID;
+ pcw->id = pCodeID; // this is the 'n' in %n
pcw->operand = optional_operand;
pcw->label = optional_label;
free(PCL(pc)->label);
free(pc);
+
}
pCode *newpCodeLabel(int key)
pBlock *PpB;
- _ALLOC(PpB,sizeof(pBlock));
+ PpB = Safe_calloc(1,sizeof(pBlock) );
PpB->next = PpB->prev = NULL;
PpB->function_entries = PpB->function_exits = PpB->function_calls = NULL;
return pB;
}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-
-pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
-{
- pCodeOp *pcop;
-
- pcop = Safe_calloc(1,sizeof(pCodeOp) );
- pcop->type = type;
- pcop->name = Safe_strdup(name);
-
- return pcop;
-}
-
/*-----------------------------------------------------------------*/
/* newpCodeOpLabel - Create a new label given the key */
/* Note, a negative key means that the label is part of wild card */
pCodeOp *pcop;
- _ALLOC(pcop,sizeof(pCodeOpLit) );
+ pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
pcop->type = PO_LITERAL;
- sprintf(s,"0x%02x",lit);
- _ALLOC_ATOMIC(pcop->name,strlen(s)+1);
- strcpy(pcop->name,s);
+ if(lit>=0) {
+ sprintf(s,"0x%02x",lit);
+ pcop->name = Safe_strdup(s);
+ } else
+ pcop->name = NULL;
+
((pCodeOpLit *)pcop)->lit = lit;
return pcop;
{
pCodeOp *pcop;
- _ALLOC(pcop,sizeof(pCodeOpBit) );
+ pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
pcop->type = PO_BIT;
pcop->name = Safe_strdup(s);
+
PCOB(pcop)->bit = bit;
if(bit>=0)
PCOB(pcop)->inBitSpace = 1;
return pcop;
}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
+{
+ pCodeOp *pcop;
+
+ switch(type) {
+ case PO_BIT:
+ pcop = newpCodeOpBit(name, -1);
+ break;
+
+ case PO_LITERAL:
+ pcop = newpCodeOpLit(-1);
+ break;
+
+ case PO_LABEL:
+ pcop = newpCodeOpLabel(-1);
+ break;
+
+ default:
+ pcop = Safe_calloc(1,sizeof(pCodeOp) );
+ pcop->type = type;
+ pcop->name = Safe_strdup(name);
+ }
+
+ return pcop;
+}
+
/*-----------------------------------------------------------------*/
/* addpCode2pBlock - place the pCode into the pBlock linked list */
/*-----------------------------------------------------------------*/
}
static void genericDestruct(pCode *pc)
{
+ fprintf(stderr,"warning, calling default pCode destructor\n");
+
unlinkPC(pc);
- fprintf(stderr,"warning, calling default pCode destructor\n");
free(pc);
+
}
#include "ralloc.h"
+pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
+
+
pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype);
pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
pCode * findNextInstruction(pCode *pc);
char *Safe_strdup(char *str);
-int getpCode(char *mnem);
+int getpCode(char *mnem,int dest);
+extern pCodeInstruction *pic14Mnemonics[];
+
/****************************************************************/
/*
typedef enum {
ALT_LABEL=1,
ALT_MNEM0,
+ ALT_MNEM0A,
ALT_MNEM1,
ALT_MNEM1A,
ALT_MNEM1B,
static char alt_label[] = { PCP_LABEL, 0};
static char alt_mnem0[] = { PCP_STR, 0};
+static char alt_mnem0a[] = { PCP_WILDVAR, 0};
static char alt_mnem1[] = { PCP_STR, PCP_STR, 0};
static char alt_mnem1a[] = { PCP_STR, PCP_WILDVAR, 0};
static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0};
static void * cvt_altpat_label(void *pp);
static void * cvt_altpat_mnem0(void *pp);
+static void * cvt_altpat_mnem0a(void *pp);
static void * cvt_altpat_mnem1(void *pp);
static void * cvt_altpat_mnem1a(void *pp);
static void * cvt_altpat_mnem1b(void *pp);
{ALT_MNEM1B, alt_mnem1b, cvt_altpat_mnem1b},
{ALT_MNEM1A, alt_mnem1a, cvt_altpat_mnem1a},
{ALT_MNEM1, alt_mnem1, cvt_altpat_mnem1},
+ {ALT_MNEM0A, alt_mnem0a, cvt_altpat_mnem0a},
{ALT_MNEM0, alt_mnem0, cvt_altpat_mnem0},
};
#define ALTPATTERNS (sizeof(altArr)/sizeof(pcPattern))
+// forward declarations
+static void * DLL_append(_DLL *list, _DLL *next);
+
+/*-----------------------------------------------------------------*/
+/* cvt_extract_destination - helper function extracts the register */
+/* destination from a parsedPattern. */
+/* */
+/*-----------------------------------------------------------------*/
+static int cvt_extract_destination(parsedPattern *pp)
+{
+
+ if(pp->pct[0].tt == PCT_STRING) {
+
+ // just check first letter for now
+
+ if(toupper(*pp->pct[0].tok.s) == 'F')
+ return 1;
+
+ } else if (pp->pct[0].tt == PCT_NUMBER) {
+
+ if(pp->pct[0].tok.n)
+ return 1;
+ }
+
+ return 0;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* pCodeOp *cvt_extract_status(char *reg, char *bit) */
+/* if *reg is the "status" register and *bit is one of the */
+/* status bits, then this function will create a new pCode op */
+/* containing the status register. */
+/*-----------------------------------------------------------------*/
+
+static pCodeOp *cvt_extract_status(char *reg, char *bit)
+{
+ int len;
+
+ if(strcasecmp(reg, pc_status.pcop.name))
+ return NULL;
+
+ len = strlen(bit);
+
+ if(len == 1) {
+ // check C,Z
+ if(toupper(*bit) == 'C')
+ return PCOP(popCopyGPR2Bit(&pc_status,PIC_C_BIT));
+ if(toupper(*bit) == 'Z')
+ return PCOP(popCopyGPR2Bit(&pc_status,PIC_Z_BIT));
+ }
+
+ // Check DC
+ if(len ==2 && toupper(bit[0]) == 'D' && toupper(bit[1]) == 'C')
+ return PCOP(popCopyGPR2Bit(&pc_status,PIC_DC_BIT));
+
+ return NULL;
+
+}
+
/*-----------------------------------------------------------------*/
/* cvt_altpat_label - convert assembly line type to a pCode label */
/* INPUT: pointer to the parsedPattern */
/*-----------------------------------------------------------------*/
static void * cvt_altpat_mnem0(void *pp)
{
- fprintf(stderr,"altpat_mnem0\n");
- return NULL;
+ parsedPattern *p = pp;
+ int opcode;
+
+ pCodeInstruction *pci=NULL;
+
+ fprintf(stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s);
+
+ opcode = getpCode(p->pct[0].tok.s,0);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+
+ pci = PCI(newpCode(opcode, NULL));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+
+ return pci;
}
/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem0a - convert assembly line type to a wild pCode */
+/* instruction */
+/* */
+/* pp[0] - wild var */
+/* */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem0a(void *pp)
+{
+ parsedPattern *p = pp;
+
+ fprintf(stderr,"altpat_mnem0a wild mnem # %d\n", p[0].pct[1].tok.n);
+
+ return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem1 - convert assembly line type to a pCode */
+/* instruction with 1 operand. */
+/* */
+/* pp[0] - mnem */
+/* pp[1] - Operand */
+/* */
/*-----------------------------------------------------------------*/
static void * cvt_altpat_mnem1(void *pp)
{
- fprintf(stderr,"altpat_mnem1\n");
- return NULL;
+
+ parsedPattern *p = pp;
+ int opcode;
+
+ pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype;
+
+ fprintf(stderr,"altpat_mnem1 %s var %s\n", p->pct[0].tok.s,p[1].pct[0].tok.s);
+
+ opcode = getpCode(p->pct[0].tok.s,0);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+
+ if(pic14Mnemonics[opcode]->bit_inst)
+ pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
+ else
+ pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+
+
+ pci = PCI(newpCode(opcode, pcosubtype));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+
+ return pci;
}
/*-----------------------------------------------------------------*/
static void * cvt_altpat_mnem1a(void *pp)
{
parsedPattern *p = pp;
+ int opcode;
pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype;
- // pCodeOp *pcw;
+ fprintf(stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n);
- // pcw = newpCodeOpWild(0,pcp,newpCodeOp(NULL,PO_GPR_REGISTER));
+ opcode = getpCode(p->pct[0].tok.s,0);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
- fprintf(stderr,"altpat_mnem1a %s var %d\n", p->pct[0].tok.s,p[1].pct[1].tok.n);
+ if(pic14Mnemonics[opcode]->bit_inst)
+ pcosubtype = newpCodeOp(NULL,PO_BIT);
+ else
+ pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
-/*
- pci = PCI(newpCode(getpCode(p->pct[0].tok.s),
- newpCodeOpWild(p[1].pct[1].tok.n, curPeep, NULL)));
+
+ pci = PCI(newpCode(opcode,
+ newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
if(!pci)
fprintf(stderr,"couldn't find mnemonic\n");
-*/
+
return pci;
}
/*-----------------------------------------------------------------*/
static void * cvt_altpat_mnem1b(void *pp)
{
- fprintf(stderr,"altpat_mnem1b\n");
- return NULL;
+ parsedPattern *p = pp;
+ int opcode;
+
+ pCodeInstruction *pci=NULL;
+
+ fprintf(stderr,"altpat_mnem1b %s var %d\n", p->pct[0].tok.s,p[1].pct[0].tok.n);
+
+ opcode = getpCode(p->pct[0].tok.s,0);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+
+ pci = PCI(newpCode(opcode, newpCodeOpLit(p[1].pct[0].tok.n) ));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+
+ return pci;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void * cvt_altpat_mnem2(void *pp)
{
- fprintf(stderr,"altpat_mnem2\n");
- return NULL;
+ parsedPattern *p = pp;
+ int opcode;
+ int dest;
+
+ pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype;
+
+ dest = cvt_extract_destination(&p[3]);
+
+ fprintf(stderr,"altpat_mnem2 %s var %s destination %s(%d)\n",
+ p->pct[0].tok.s,
+ p[1].pct[0].tok.s,
+ p[3].pct[0].tok.s,
+ dest);
+
+
+ opcode = getpCode(p->pct[0].tok.s,dest);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+
+ if(pic14Mnemonics[opcode]->bit_inst) {
+ pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
+ if(pcosubtype == NULL) {
+ fprintf(stderr, "bad operand?\n");
+ return NULL;
+ }
+
+ } else
+ pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+
+
+ pci = PCI(newpCode(opcode,pcosubtype));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+ return pci;
+
}
/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem2a - convert assembly line type to a pCode */
+/* instruction with 1 wild operand and a */
+/* destination operand (e.g. w or f) */
+/* */
+/* pp[0] - mnem */
+/* pp[1] - wild var */
+/* pp[2] - comma */
+/* pp[3] - destination */
+/* */
/*-----------------------------------------------------------------*/
static void * cvt_altpat_mnem2a(void *pp)
{
- fprintf(stderr,"altpat_mnem2a\n");
- return NULL;
-}
+ parsedPattern *p = pp;
+ int opcode;
+ int dest;
+ pCodeInstruction *pci=NULL;
+ pCodeOp *pcosubtype;
+ dest = cvt_extract_destination(&p[3]);
+ fprintf(stderr,"altpat_mnem2a %s var %d destination %s(%d)\n",
+ p->pct[0].tok.s,
+ p[1].pct[1].tok.n,
+ p[3].pct[0].tok.s,
+ dest);
-#if 0
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static pCode * cvt_pcpat_wildMnem(parsedPattern *pp)
-{
- fprintf(stderr,"pcpat_wildMnem\n");
- return NULL;
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static pCode * cvt_pcpat_Mnem(parsedPattern *pp)
-{
- fprintf(stderr,"pcpat_Mnem\n");
- return NULL;
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static pCode * cvt_pcpat_wildVar(parsedPattern *pp)
-{
- fprintf(stderr,"pcpat_wildVar\n");
- return NULL;
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static pCode * cvt_pcpat_var(parsedPattern *pp)
-{
- fprintf(stderr,"pcpat_var\n");
- return NULL;
-}
-#endif
+ opcode = getpCode(p->pct[0].tok.s,dest);
+ if(opcode < 0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+ if(pic14Mnemonics[opcode]->bit_inst)
+ pcosubtype = newpCodeOp(NULL,PO_BIT);
+ else
+ pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
+ pci = PCI(newpCode(opcode,
+ newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
+
+ if(!pci)
+ fprintf(stderr,"couldn't find mnemonic\n");
+
+ return pci;
+
+}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
if(isdigit(*ln)) {
tokArr[tokIdx].tt = PCT_NUMBER;
- tokArr[tokIdx++].tok.n = strtol(ln, &ln, 10);
+ tokArr[tokIdx++].tok.n = strtol(ln, &ln, 0);
continue;
int lpcpIdx;
int ltokIdx =0;
int matching = 0;
- int j,k;
+ int j=0;
+ int k=0;
char * cPmnem = NULL; // Pointer to non-wild mnemonic (if any)
char * cP1stop = NULL;
matching = 0;
//fprintf(stderr,"ltokIdx = %d\n",ltokIdx);
- if( ((tokArr[ltokIdx].tt == PCT_SPACE) )//|| (tokArr[ltokIdx].tt == PCT_COMMA))
+ if( ((tokArr[ltokIdx].tt == PCT_SPACE) )
&& (advTokIdx(<okIdx, 1)) ) // eat space
break;
j=k=0;
do {
int c;
- //fprintf(stderr,"comparing alt pattern %d (first token %d)\n",k,altArr[k].tokens[0]);
+
if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
- //fprintf(stderr," found a valid assembly line!!!\n");
+
if( altArr[k].f) {
pc = altArr[k].f(&parsedPatArr[j]);
if(pc && pc->print)
pc->print(stderr,pc);
- if(pc && pc->destruct) pc->destruct(pc);
+ //if(pc && pc->destruct) pc->destruct(pc); dumps core?
}
j += c;
}
}
while(j<=lparsedPatIdx && k<ALTPATTERNS);
-
+/*
fprintf(stderr,"\nConverting parsed line to pCode:\n\n");
j = 0;
j++;
}
while(j<lparsedPatIdx);
-
+*/
fprintf(stderr,"\n");
}
pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
curPeep = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
- //peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
+ //curPeep->target = curPeep->replace = NULL;
+ curPeep->vars = NULL; curPeep->wildpCodes = NULL;
+ peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
+
+ curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL);
for(ln = pr->match; ln; ln = ln->next) {
+
fprintf(stderr,"%s\n",ln->line);
parseLineNode(ln->line);
}
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);
if(pr->cond)
fprintf(stderr,"\nCondition: %s\n",pr->cond);
+ return;
}
}
void pCodePeepInit(void)
{
+#if 0
pBlock *pb;
// pCode *pc;
pCodePeep *pcp;
-
+#endif
}
/*-----------------------------------------------------------------*/
{
int i;
+ if(!pcp)
+ return;
for(i=0;i<pcp->nvars; i++)
pcp->vars[i] = NULL;
while(peeprules) {
peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
+ if(!peepBlock || !peepBlock->target || !peepBlock->target->pcHead)
+ goto next_rule;
+
pCodePeepClrVars(peepBlock);
pcin = pc;
return 1;
}
-
+ next_rule:
peeprules = peeprules->next;
}