extern char *pic16_aopGet (struct asmop *aop, int offset, bool bit16, bool dname);
#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
#define inline
-#else
-#define STRCASECMP strcasecmp
#endif
#define DUMP_DF_GRAPHS 0
for(i=0; i<MAX_PIC16MNEMONICS; i++)
if(pic16Mnemonics[i])
- hTabAddItem(&pic16MnemonicsHash, mnem2key(pic16Mnemonics[i]->mnemonic), pic16Mnemonics[i]);
+ hTabAddItem(&pic16MnemonicsHash, mnem2key((const unsigned char *)pic16Mnemonics[i]->mnemonic), pic16Mnemonics[i]);
pci = hTabFirstItem(pic16MnemonicsHash, &key);
while(pci) {
{
pCodeInstruction *pci;
- int key = mnem2key(mnem);
+ int key = mnem2key((unsigned char *)mnem);
if(!mnemonics_initialized)
pic16initMnemonics();
i = 0;
do {
hTabAddItem(&pic16pCodePeepCommandsHash,
- mnem2key(peepCommands[i].cmd), &peepCommands[i]);
+ mnem2key((const unsigned char *)peepCommands[i].cmd), &peepCommands[i]);
i++;
} while (peepCommands[i].cmd);
{
peepCommand *pcmd;
- int key = mnem2key(cmd);
+ int key = mnem2key((unsigned char *)cmd);
pcmd = hTabFirstItemWK(pic16pCodePeepCommandsHash, key);
return 0;
}
+
/*-----------------------------------------------------------------*/
/* pic16_newpCode - create and return a newly initialized pCode */
/* */
/* pic16_newpCodeCSource - create a new pCode Source Symbol */
/*-----------------------------------------------------------------*/
-pCode *pic16_newpCodeCSource(int ln, char *f, char *l)
+pCode *pic16_newpCodeCSource(int ln, const char *f, const char *l)
{
pCodeCSource *pccs;
return pcop;
}
+/* Allow for 12 bit literals, required for LFSR */
+pCodeOp *pic16_newpCodeOpLit12(int lit)
+{
+ char *s = buffer;
+ pCodeOp *pcop;
+
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
+ pcop->type = PO_LITERAL;
+
+ pcop->name = NULL;
+ //if(lit>=0)
+ sprintf(s,"0x%03x", ((unsigned int)lit) & 0x0fff);
+ //else
+ // sprintf(s, "%i", lit);
+
+ if(s)
+ pcop->name = Safe_strdup(s);
+
+ ((pCodeOpLit *)pcop)->lit = lit;
+
+ return pcop;
+}
+
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2)
// fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
} else {
pcop->name = NULL;
+ PCOI(pcop)->rIdx = -1;
}
PCOI(pcop)->index = index;
if(!r) {
fprintf(stderr, "%s:%d Could not find a free GPR register\n",
__FUNCTION__, __LINE__);
- exit(-1);
+ exit(EXIT_FAILURE);
}
}
else
pcop = pic16_newpCodeOpReg(-1);
break;
+
+ case PO_TWO_OPS:
+ assert( !"Cannot create PO_TWO_OPS from string!" );
+ pcop = NULL;
+ break;
default:
pcop = Safe_calloc(1,sizeof(pCodeOp) );
return pcop;
}
+pCodeOp *pic16_newpCodeOp2(pCodeOp *src, pCodeOp *dst)
+{
+ pCodeOp2 *pcop2 = Safe_calloc(1, sizeof(pCodeOp2));
+ pcop2->pcop.type = PO_TWO_OPS;
+ pcop2->pcopL = src;
+ pcop2->pcopR = dst;
+ return PCOP(pcop2);
+}
+
/* This is a multiple of two as gpasm pads DB directives to even length,
* thus the data would be interleaved with \0 bytes...
* This is a multiple of three in order to have arrays of 3-byte pointers
/*-----------------------------------------------------------------*/
/* Add "DB" directives to a pBlock */
/*-----------------------------------------------------------------*/
-void pic16_emitDB(char c, char ptype, void *p)
+void pic16_emitDB(int c, char ptype, void *p)
{
int l;
}
if(pcop) {
+
switch(pcop->type) {
case PO_W:
case PO_WREG:
case PO_FSR0:
if(use_buffer) {
SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
- return buffer;
+ return (buffer);
}
- return PCOR(pcop)->r->name;
+ return (PCOR(pcop)->r->name);
break;
case PO_GPR_TEMP:
r = pic16_regWithIdx(PCOR(pcop)->r->rIdx);
if(use_buffer) {
SAFE_snprintf(&buffer,&size,"%s",r->name);
- return buffer;
+ return (buffer);
}
- return r->name;
+ return (r->name);
case PO_IMMEDIATE:
s = buffer;
pcop->name);
}
}
- return buffer;
+ return (buffer);
case PO_GPR_REGISTER:
case PO_DIR:
} else {
SAFE_snprintf(&s,&size,"%s",pcop->name);
}
- return buffer;
+ return (buffer);
case PO_GPR_BIT:
s = buffer;
if(PCORB(pcop)->subtype == PO_GPR_TEMP) {
}
return (buffer);
+ case PO_TWO_OPS:
+ return (pic16_get_op( PCOP2(pcop)->pcopL, use_buffer ? buffer : NULL, size ));
+
default:
if(pcop->name) {
if(use_buffer) {
SAFE_snprintf(&buffer,&size,"%s",pcop->name);
- return buffer;
+ return (buffer);
}
- return pcop->name;
+ return (pcop->name);
}
}
+ return ("unhandled type for op1");
}
- return "NO operand1";
+ return ("NO operand1");
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size)
{
- regs *r;
- static char b[128];
- char *s;
- int use_buffer = 1; // copy the string to the passed buffer pointer
-
- if(!buffer) {
- buffer = b;
- size = sizeof(b);
- use_buffer = 0; // Don't bother copying the string to the buffer.
- }
-
-#if 0
- fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n",
- __FUNCTION__, __LINE__, PCOR(PCOR2(pcop)->pcop2)->r->name, PCOR2(pcop)->pcop2->type,
- PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0);
-#endif
-
- if(pcop) {
- switch(PCOR2(pcop)->pcop2->type) {
- case PO_W:
- case PO_WREG:
- case PO_PRODL:
- case PO_PRODH:
- case PO_INDF0:
- case PO_FSR0:
- if(use_buffer) {
- SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
- return buffer;
- }
- return PCOR(PCOR2(pcop)->pcop2)->r->name;
- break;
- case PO_GPR_TEMP:
- r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx);
-
- if(use_buffer) {
- SAFE_snprintf(&buffer,&size,"%s",r->name);
- return buffer;
- }
- return r->name;
- case PO_IMMEDIATE:
- assert( 0 );
- break;
-#if 0
- s = buffer;
-
- if(PCOI(pcop)->_const) {
- if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
- SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
- pcop->name,
- PCOI(pcop)->index,
- 8 * PCOI(pcop)->offset );
- } else
- SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
- } else {
- if( PCOI(pcop)->index) {
- SAFE_snprintf(&s,&size,"(%s + %d)",
- pcop->name,
- PCOI(pcop)->index );
- } else {
- if(PCOI(pcop)->offset)
- SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
- else
- SAFE_snprintf(&s,&size,"%s",pcop->name);
- }
- }
- return buffer;
-#endif
- case PO_DIR:
- s = buffer;
- if( PCOR(PCOR2(pcop)->pcop2)->instance) {
- SAFE_snprintf(&s,&size,"(%s + %d)",
- PCOR(PCOR2(pcop)->pcop2)->r->name,
- PCOR(PCOR2(pcop)->pcop2)->instance );
- } else {
- SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
- }
- return buffer;
-
- default:
- if(PCOR(PCOR2(pcop)->pcop2)->r->name) {
- if(use_buffer) {
- SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
- return buffer;
- }
- return PCOR(PCOR2(pcop)->pcop2)->r->name;
- }
- }
- }
+ if(pcop && pcop->type == PO_TWO_OPS) {
+ return pic16_get_op( PCOP2(pcop)->pcopR, buffer, size );
+ }
return "NO operand2";
}
if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) {
fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n",
__FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC);
-// exit(-1);
+// exit(EXIT_FAILURE);
}
#endif
if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
- if(PCI(pc)->is2MemOp) {
- SAFE_snprintf(&s,&size, "%s, %s",
- pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
- pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
+ //if(PCI(pc)->is2MemOp)
+ if (PCI(pc)->pcop->type == PO_TWO_OPS)
+ {
+ /* split into two phases due to static buffer in pic16_get_op() */
+ SAFE_snprintf(&s,&size, "%s",
+ pic16_get_op((PCI(pc)->pcop), NULL, 0));
+ SAFE_snprintf(&s, &size, ", %s",
+ pic16_get_op2((PCI(pc)->pcop), NULL, 0));
break;
}
r = pic16_getRegFromInstruction(pc);
// fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n",
-// __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?r->accessBank:-1);
+// __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?isACCESS_BANK(r):-1);
if(PCI(pc)->isAccess) {
static char *bank_spec[2][2] = {
{ ", B", ", BANKED" }/* MPASM (should) use BANKED by default */
};
- SAFE_snprintf(&s,&size,"%s", bank_spec[(r && !r->accessBank) ? 1 : 0][pic16_mplab_comp ? 1 : 0]);
+ SAFE_snprintf(&s,&size,"%s", bank_spec[(r && !isACCESS_BANK(r)) ? 1 : 0][pic16_mplab_comp ? 1 : 0]);
}
}
//
case PO_WILD:
break;
+
+ case PO_TWO_OPS:
+ return pic16_getRegFrompCodeOp( PCOP2(pcop)->pcopL );
+ break;
default:
- fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d (%s)\n",pcop->type, dumpPicOptype (pcop->type));
+ fprintf(stderr, "pic16_getRegFrompCodeOp - unknown reg type %d (%s)\n",pcop->type, dumpPicOptype (pcop->type));
// assert( 0 );
break;
}
/*-----------------------------------------------------------------*/
regs * pic16_getRegFromInstruction(pCode *pc)
{
-
if(!pc ||
!isPCI(pc) ||
!PCI(pc)->pcop ||
dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type);
#endif
- return pic16_getRegFrompCodeOp (PCI(pc)->pcop);
+ return( pic16_getRegFrompCodeOp (PCI(pc)->pcop) );
}
/*-------------------------------------------------------------------------------*/
(PCI(pc)->num_ops == 1)) // accept only 2 operand commands
return NULL;
+ if (PCI(pc)->pcop->type != PO_TWO_OPS)
+ return NULL;
#if 0
fprintf(stderr, "pic16_getRegFromInstruction2 - reg type %s (%d)\n",
dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type);
#endif
- return pic16_getRegFrompCodeOp (PCOR2(PCI(pc)->pcop)->pcop2);
+ return pic16_getRegFrompCodeOp (PCOP2(PCI(pc)->pcop)->pcopR);
}
/*-----------------------------------------------------------------*/
{
pCode *pc; pCodeLabel *pcl;
- if(!pb)
+ if(!pb || !pb->pcHead)
return;
for(pc = pb->pcHead; (pc=pic16_findNextInstruction(pc->next)) != NULL; ) {
"PO_BIT", // bit operand.
"PO_STR", // (8051 legacy)
"PO_LABEL",
- "PO_WILD" // Wild card operand in peep optimizer
+ "PO_WILD", // Wild card operand in peep optimizer
+ "PO_TWO_OPS" // combine two operands
};
char *dumpPicOptype(PIC_OPTYPE type)
{
+ assert( type >= 0 && type < sizeof(pic_optype_names)/sizeof( char *) );
return (pic_optype_names[ type ]);
}
/* getSymbolFromOperand - return a pointer to the symbol in */
/* the given operand and its length */
/*----------------------------------------------------------*/
-char *getSymbolFromOperand (char *op, unsigned int *len)
+char *getSymbolFromOperand (char *op, int *len)
{
char *sym, *curr;
*len = 0;
defmap_t *map;
pCodeFlow *pcfl;
+ assert(pb);
+
pcfl = PCI(pic16_findNextInstruction (pb->pcHead))->pcflow;
/* find initial value (assigning pc == NULL) */
set *todo;
set *blacklist;
+ if (!pb) return;
+
/* initialize out_vals to unique'fied defmaps per pCodeFlow */
for (pc = pic16_findNextInstruction (pb->pcHead); pc; pc = pic16_findNextInstruction (pc->next)) {
if (isPCFL(pc)) {
if (!isSpecial1 && pic16_regIsLocal (reg1) && val && oldval && !pic16_isAlive (SPO_STATUS, pc)) {
//pc->print (stderr, pc); fprintf (stderr, "lit: %d (%x, %x)\n", lit, lit, val->in_val);
if (lit == 0) {
- newpc = pic16_newpCode (POC_CLRF, PCOR2(pci->pcop)->pcop2);
+ newpc = pic16_newpCode (POC_CLRF, PCOP2(pci->pcop)->pcopR);
} else if (lit == 0x00ff) {
- newpc = pic16_newpCode (POC_SETF, PCOR2(pci->pcop)->pcop2);
+ newpc = pic16_newpCode (POC_SETF, PCOP2(pci->pcop)->pcopR);
} else {
newpc = NULL;
}
pc = newpc;
break; // do not process instruction as MOVFF...
}
- } else if (!isSpecial1 && !isSpecial2 && pic16_regIsLocal (reg1) && pic16_regIsLocal (reg2)) {
- if (val && oldval && (val->in_val != 0) && (val->in_val == oldval->in_val)) {
+ } else if (!isSpecial1 && !isSpecial2
+ && pic16_regIsLocal (reg1) && pic16_regIsLocal (reg2)
+ && val && oldval && (val->in_val != 0)) {
+ if (val->in_val == oldval->in_val) {
//fprintf (stderr, "MOVFF: F2 (%s) already set up correctly (%x) at %p\n", strFromSym (sym2), oldval->in_val, pc);
pic16_safepCodeRemove (pc, "=DF= redundant MOVFF removed");
} else {
if (copy->val && copy->val == val->in_val) {
//fprintf (stderr, "found replacement symbol for %s (val %x) <-- %s (assigned %x @ %p)\n", strFromSym(sym1), val->in_val, strFromSym(copy->sym), copy->val, copy->pc);
if (copy->sym == SPO_WREG) {
- newpc = pic16_newpCode (POC_MOVWF, pic16_pCodeOpCopy (PCOR2(pci->pcop)->pcop2));
+ newpc = pic16_newpCode (POC_MOVWF, pic16_pCodeOpCopy (PCOP2(pci->pcop)->pcopR));
} else {
+ pCodeOp *pcop = NULL;
+ /* the code below fails if we try to replace
+ * MOVFF PRODL, r0x03
+ * MOVFF r0x03, PCLATU
+ * with
+ * MOVFF PRODL, PCLATU
+ * as copy(PRODL) contains has pc==NULL, by name fails...
+ */
+ if (!copy->pc || !PCI(copy->pc)->pcop) break;
+
+ if (copy->pc && PCI(copy->pc)->pcop)
+ pcop = PCI(copy->pc)->pcop;
+#if 0
+ /* This code is broken--see above. */
+ else
+ {
+ const char *symname = strFromSym(copy->sym);
+
+ assert( symname );
+ pic16_InsertCommentAfter (pc->prev, "BUG-ME");
+ pic16_InsertCommentAfter (pc->prev, "=DF= MOVFF: newpCodeOpregFromStr(%s)", (char *)symname);
+ //pcop = pic16_newpCodeOpRegFromStr((char *)symname);
+ }
+#endif
+ assert( pcop );
newpc = pic16_newpCode(POC_MOVFF, pic16_popGet2p(
-// /*TODO: change to copy->pc's out symbol*/pic16_pCodeOpCopy (pci->pcop),
- pic16_pCodeOpCopy (PCI(copy->pc)->pcop),
- pic16_pCodeOpCopy (PCOR2(pci->pcop)->pcop2)));
+ pcop,
+ pic16_pCodeOpCopy (PCOP2(pci->pcop)->pcopR)));
}
pic16_InsertCommentAfter (pc->prev, "=DF= MOVFF: SRC op %s replaced by %s", strFromSym(sym1), strFromSym(copy->sym));
pic16_df_saved_bytes += PCI(pc)->isize - PCI(newpc)->isize;
static void pic16_destructDF (pBlock *pb) {
pCode *pc, *next;
+ if (!pb) return;
+
/* remove old defmaps */
pc = pic16_findNextInstruction (pb->pcHead);
while (pc) {
static int pic16_pBlockHasAsmdirs (pBlock *pb) {
pCode *pc;
+ if (!pb) return 0;
+
pc = pic16_findNextInstruction (pb->pcHead);
while (pc) {
if (isPCAD(pc)) return 1;
pCode *pc, *next;
int change=0;
+ if (!pb) return;
+
//fprintf (stderr, "creating DF for pb %p (%s)\n", pb, pic16_pBlockGetFunctionName (pb));
pic16_destructDF (pb);
static void pic16_vcg_dump (FILE *of, pBlock *pb) {
pCode *pc;
+ if (!pb) return;
+
/* check pBlock: do not analyze pBlocks with ASMDIRs (for now...) */
if (pic16_pBlockHasAsmdirs (pb)) {
//fprintf (stderr, "%s: pBlock contains ASMDIRs -- data flow analysis not performed!\n", __FUNCTION__);
char buf[BUF_SIZE];
pCode *pc;
+ if (!pb) return;
+
/* get function name */
pc = pb->pcHead;
while (pc && !isPCF(pc)) pc = pc->next;