#include "pcode.h"
#include "ralloc.h"
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
// Eventually this will go into device dependent files:
pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,NULL};
pCodeOpReg pc_indf = {{PO_INDF, "INDF"}, -1, NULL,NULL};
AnalyzeRETURN,
genericDestruct,
genericPrint},
- POC_RETLW,
+ POC_RETURN,
"RETURN",
NULL, // operand
0, // num ops
}
+
+/*-----------------------------------------------------------------*/
+/* 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);
+#if 0
+ // Alas, vsnprintf is not ANSI standard, and does not exist
+ // on Solaris (and probably other non-Gnu flavored Unixes).
+ vsnprintf(*str, *size, format, val);
+#else
+ // This, of course, is *not* safe, despite the name.
+ vsprintf(*str, format, val);
+#endif
+
+ va_end (val);
+
+ len = strlen(*str);
+ *str += len;
+ *size -= len;
+
+}
+
void pCodeInitRegisters(void)
{
/* */
/*-----------------------------------------------------------------*/
-int mnem2key(char *mnem)
+int mnem2key(char const *mnem)
{
int key = 0;
while(*mnem) {
- key += *mnem++ +1;
+ key += toupper(*mnem++) +1;
}
for(i=0; i<MAX_PIC14MNEMONICS; i++)
if(pic14Mnemonics[i])
hTabAddItem(&pic14MnemonicsHash, mnem2key(pic14Mnemonics[i]->mnemonic), pic14Mnemonics[i]);
-/*
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpADDLW), scpADDLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpADDWF),scpADDWF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpANDLW),scpANDLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpANDWF),scpANDWF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBCF),scpBCF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBSF),scpBSF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBTFSC),scpBTFSC);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpBTFSS),scpBTFSS);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCALL),scpCALL);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCOMF),scpCOMF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCLRF),scpCLRF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpCLRW),scpCLRW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpDECF),scpDECF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpDECFSZ),scpDECFSZ);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpGOTO),scpGOTO);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpINCF),scpINCF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpINCFSZ),scpINCFSZ);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpIORLW),scpIORLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpIORWF),scpIORWF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpMOVF),scpMOVF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpMOVLW),scpMOVLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpMOVWF),scpMOVWF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpNEGF),scpNEGF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpRETLW),scpRETLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpRETURN),scpRETURN);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpSUBLW),scpSUBLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpSUBWF),scpSUBWF);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpTRIS),scpTRIS);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpXORLW),scpXORLW);
- hTabAddItem(&pic14MnemonicsHash, mnem2key(scpXORWF),scpXORWF);
-*/
-
pci = hTabFirstItem(pic14MnemonicsHash, &key);
while(pci) {
mnemonics_initialized = 1;
}
+int getpCode(char *mnem,unsigned dest)
+{
+
+ pCodeInstruction *pci;
+ int key = mnem2key(mnem);
+
+ if(!mnemonics_initialized)
+ pic14initMnemonics();
+
+ pci = hTabFirstItemWK(pic14MnemonicsHash, key);
+
+ while(pci) {
+
+ if(STRCASECMP(pci->mnemonic, mnem) == 0) {
+ if((pci->num_ops <= 1) || (pci->dest == dest))
+ return(pci->op);
+ }
+
+ pci = hTabNextItemWK (pic14MnemonicsHash);
+
+ }
+
+ return -1;
+}
char getpBlock_dbName(pBlock *pb)
{
pci = Safe_calloc(1, sizeof(pCodeInstruction));
- if((op < MAX_PIC14MNEMONICS) && pic14Mnemonics[op]) {
+ if((op>=0) && (op < MAX_PIC14MNEMONICS) && pic14Mnemonics[op]) {
memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction));
pci->pcop = pcop;
/* 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;
}
+static void pCodeLabelDestruct(pCode *pc)
+{
+
+ if(!pc)
+ return;
+
+ unlinkPC(pc);
+
+ if(PCL(pc)->label)
+ free(PCL(pc)->label);
+
+ free(pc);
+
+}
pCode *newpCodeLabel(int key)
{
pcl->pc.pb = NULL;
pcl->pc.analyze = genericAnalyze;
- pcl->pc.destruct = genericDestruct;
+ pcl->pc.destruct = pCodeLabelDestruct;
pcl->pc.print = pCodePrintLabel;
pcl->key = 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;
}
/*-----------------------------------------------------------------*/
-/* 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
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 */
/*-----------------------------------------------------------------*/
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;
+ }
}
/*-----------------------------------------------------------------*/
}
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);
+
}
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;