// static int GpCodeSequenceNumber = 1;
int GpcFlowSeq = 1;
+/* statistics (code size estimation) */
+static unsigned int pcode_insns = 0;
+static unsigned int pcode_doubles = 0;
+
+
unsigned maxIdx; /* This keeps track of the maximum register index for call tree register reuse */
unsigned peakIdx; /* This keeps track of the peak register index for call tree register reuse */
pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval);
void pCodeRegMapLiveRanges(pBlock *pb);
+pBranch * pBranchAppend(pBranch *h, pBranch *n);
+
/****************************************************************/
/* PIC Instructions */
/* */
/*-----------------------------------------------------------------*/
-int mnem2key(char const *mnem)
+int mnem2key(unsigned char const *mnem)
{
int key = 0;
if(!of || !the_pFile)
return;
-
+
for(pb = the_pFile->pbHead; pb; pb = pb->next) {
if(getpBlock_dbName(pb) == dbName) {
pBlockStats(of,pb);
}
}
+
+void resetpCodeStatistics (void)
+{
+ pcode_insns = pcode_doubles = 0;
+}
+
+void dumppCodeStatistics (FILE *of)
+{
+ /* dump statistics */
+ fprintf (of, "\n");
+ fprintf (of, ";\tcode size estimation:\n");
+ fprintf (of, ";\t%5u+%5u = %5u instructions (%5u byte)\n", pcode_insns, pcode_doubles, pcode_insns + pcode_doubles, 2*(pcode_insns + 2*pcode_doubles));
+ fprintf (of, "\n");
+}
+
void pcode_test(void)
{
/* newpCodeCSource - create a new pCode Source Symbol */
/*-----------------------------------------------------------------*/
-pCode *newpCodeCSource(int ln, char *f, char *l)
+pCode *newpCodeCSource(int ln, char *f, const char *l)
{
pCodeCSource *pccs;
if(asdir && *asdir) {
- while(isspace(*asdir))asdir++; // strip any white space from the beginning
+ while(isspace((unsigned char)*asdir))asdir++; // strip any white space from the beginning
pcad->directive = Safe_strdup( asdir );
}
va_end(ap);
- while(isspace(*lbp))lbp++;
+ while(isspace((unsigned char)*lbp))lbp++;
if(lbp && *lbp)
pcad->arg = Safe_strdup( lbp );
if(!of)
of = stderr;
- for(pc = pb->pcHead; pc; pc = pc->next)
+ for(pc = pb->pcHead; pc; pc = pc->next) {
printpCode(of,pc);
-
+
+ if (isPCI(pc))
+ {
+ if (isPCI(pc) && (PCI(pc)->op == POC_PAGESEL || PCI(pc)->op == POC_BANKSEL)) {
+ pcode_doubles++;
+ } else {
+ pcode_insns++;
+ }
+ }
+ } // for
+
}
/*-----------------------------------------------------------------*/
pc->prev->next = pc->next;
if(pc->next)
pc->next->prev = pc->prev;
-
+
+#if 0
+ /* RN: I believe this should be right here, but this did not
+ * cure the bug I was hunting... */
+ /* must keep labels -- attach to following instruction */
+ if (isPCI(pc) && PCI(pc)->label && pc->next)
+ {
+ pCodeInstruction *pcnext = PCI(findNextInstruction (pc->next));
+ if (pcnext)
+ {
+ pBranchAppend (pcnext->label, PCI(pc)->label);
+ }
+ }
+#endif
pc->prev = pc->next = NULL;
}
}
return NULL;
switch(pcop->type) {
+ case PO_NONE:
+ case PO_STR:
+ pcopnew = Safe_calloc (1, sizeof (pCodeOp));
+ memcpy (pcopnew, pcop, sizeof (pCodeOp));
+ break;
+
+ case PO_W:
+ case PO_STATUS:
+ case PO_FSR:
+ case PO_INDF:
+ case PO_INTCON:
+ case PO_GPR_REGISTER:
+ case PO_GPR_TEMP:
+ case PO_GPR_POINTER:
+ case PO_SFR_REGISTER:
+ case PO_PCL:
+ case PO_PCLATH:
+ case PO_DIR:
+ //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
+ memcpy (pcopnew, pcop, sizeof (pCodeOpReg));
+ DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
+ break;
+
+ case PO_LITERAL:
+ //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
+ memcpy (pcopnew, pcop, sizeof (pCodeOpLit));
+ break;
+
+ case PO_IMMEDIATE:
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
+ memcpy (pcopnew, pcop, sizeof (pCodeOpImmd));
+ break;
+
+ case PO_GPR_BIT:
case PO_CRY:
case PO_BIT:
//DFPRINTF((stderr,"pCodeOpCopy bit\n"));
pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
- PCORB(pcopnew)->bit = PCORB(pcop)->bit;
- PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
-
+ memcpy (pcopnew, pcop, sizeof (pCodeOpRegBit));
+ break;
+
+ case PO_LABEL:
+ //DFPRINTF((stderr,"pCodeOpCopy label\n"));
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
+ memcpy (pcopnew, pcop, sizeof(pCodeOpLabel));
break;
case PO_WILD:
return pcopnew;
break;
-
- case PO_LABEL:
- //DFPRINTF((stderr,"pCodeOpCopy label\n"));
- pcopnew = Safe_calloc(1,sizeof(pCodeOpLabel) );
- PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
- break;
-
- case PO_IMMEDIATE:
- pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
- PCOI(pcopnew)->index = PCOI(pcop)->index;
- PCOI(pcopnew)->offset = PCOI(pcop)->offset;
- PCOI(pcopnew)->_const = PCOI(pcop)->_const;
- PCOI(pcopnew)->_function = PCOI(pcop)->_function;
- break;
-
- case PO_LITERAL:
- //DFPRINTF((stderr,"pCodeOpCopy lit\n"));
- pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
- PCOL(pcopnew)->lit = PCOL(pcop)->lit;
- break;
-
- case PO_GPR_BIT:
-
- pcopnew = newpCodeOpBit(pcop->name, PCORB(pcop)->bit,PCORB(pcop)->inBitSpace);
- PCOR(pcopnew)->r = PCOR(pcop)->r;
- PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
- DFPRINTF((stderr," pCodeOpCopy Bit -register index\n"));
- return pcopnew;
- break;
-
- case PO_GPR_POINTER:
- case PO_GPR_REGISTER:
- case PO_GPR_TEMP:
- case PO_FSR:
- case PO_INDF:
- //DFPRINTF((stderr,"pCodeOpCopy GPR register\n"));
- pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcopnew)->r = PCOR(pcop)->r;
- PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
- PCOR(pcopnew)->instance = PCOR(pcop)->instance;
- DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
- break;
-
- case PO_DIR:
- //fprintf(stderr,"pCodeOpCopy PO_DIR\n");
- pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcopnew)->r = PCOR(pcop)->r;
- PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx;
- PCOR(pcopnew)->instance = PCOR(pcop)->instance;
+
+ default:
+ assert ( !"unhandled pCodeOp type copied" );
break;
- case PO_STATUS:
- DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
- case PO_SFR_REGISTER:
- case PO_STR:
- case PO_NONE:
- case PO_W:
- case PO_INTCON:
- case PO_PCL:
- case PO_PCLATH:
-
- //DFPRINTF((stderr,"pCodeOpCopy register type %d\n", pcop->type));
- pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
-
- }
+ } // switch
- pcopnew->type = pcop->type;
if(pcop->name)
pcopnew->name = Safe_strdup(pcop->name);
else
s = buffer;
if(PCOI(pcop)->_const) {
- if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+ if( PCOI(pcop)->offset >= 0 && PCOI(pcop)->offset<4) {
switch(PCOI(pcop)->offset) {
case 0:
- SAFE_snprintf(&s,&size,"low %s",pcop->name);
+ SAFE_snprintf(&s,&size,"low (%s+%d)",pcop->name, PCOI(pcop)->index);
break;
case 1:
- SAFE_snprintf(&s,&size,"high %s",pcop->name);
+ SAFE_snprintf(&s,&size,"high (%s+%d)",pcop->name, PCOI(pcop)->index);
break;
default:
+ fprintf (stderr, "PO_IMMEDIATE/_const/offset=%d\n", PCOI(pcop)->offset);
+ assert ( !"offset too large" );
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);
+ SAFE_snprintf(&s,&size,"LOW (%s+%d)",pcop->name,PCOI(pcop)->index);
} else {
if( !PCOI(pcop)->offset) { // && PCOI(pcc->pcop)->offset<4) {
SAFE_snprintf(&s,&size,"(%s + %d)",
SAFE_snprintf(&s,&size,"high (%s + %d)",pcop->name, PCOI(pcop)->index);
break;
default:
+ fprintf (stderr, "PO_IMMEDIATE/mutable/offset=%d\n", PCOI(pcop)->offset);
+ assert ( !"offset too large" );
SAFE_snprintf(&s,&size,"((%s + %d) >> %d)&0xff",pcop->name, PCOI(pcop)->index, 8*PCOI(pcop)->offset);
break;
}
SAFE_snprintf(&s,&size,";\t--FLOW change\n");
break;
case PC_CSOURCE:
- SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+// SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+ SAFE_snprintf(&s,&size,"%s\t.line\t%d; \"%s\"\t%s\n",(options.debug?"":";"),PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
break;
case PC_ASMDIR:
if(PCAD(pc)->directive) {
break;
case PC_CSOURCE:
- fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+// fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+ fprintf(of,"%s\t.line\t%d; \"%s\"\t%s\n", (options.debug?"":";"), PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
break;
case PC_ASMDIR:
}
}
+#if 1
if (LastRegIdx == reg->rIdx) // If this is the same register as last time then it is in same bank
return cur_bank;
LastRegIdx = reg->rIdx;
+#endif
if (reg->isFixed) {
bank = REG_BANK(reg);
if (isCALL(pc)) {
pCode *pcf = findFunction(get_op_from_instruction(PCI(pc)));
+ LastRegIdx = -1; /* do not know which register is touched in the called function... */
if (pcf && isPCF(pcf)) {
pCode *pcfr;
int rbank = 'U'; // Undetermined
if (isPCI(pcfr)) {
if ((PCI(pcfr)->op==POC_RETURN) || (PCI(pcfr)->op==POC_RETLW)) {
if (rbank == 'U')
- rbank = PCFL(pcfr)->lastBank;
+ rbank = PCI(pcfr)->pcflow->lastBank;
else
- if (rbank != PCFL(pcfr)->lastBank)
+ if (rbank != PCI(pcfr)->pcflow->lastBank)
return -1; // Unknown bank - multiple returns with different banks
}
}
/* Extern functions may use registers in different bank - must call banksel */
return -1; /* Unknown bank */
}
+ /* play safe... */
+ return -1;
}
if ((isPCI(pc)) && (PCI(pc)->op == POC_BANKSEL)) {
pBlockMergeLabels(pb);
AnalyzepBlock(pb);
} else {
- DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName));
+ DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName(pb)));
}
}