static hTab *pic14pCodePeepCommandsHash = NULL;
-static pFile *the_pFile = NULL;
+pFile *the_pFile = NULL;
static pBlock *pb_dead_pcodes = NULL;
/* Hardcoded flags to change the behavior of the PIC port */
-static int peepOptimizing = 1; /* run the peephole optimizer if nonzero */
static int functionInlining = 1; /* inline functions if nonzero */
int debug_verbose = 0; /* Set true to inundate .asm file */
0, // literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z) // outCond
+ (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z) // outCond
};
pCodeInstruction pciADDFW = {
0, // literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z) // outCond
+ (PCC_W | PCC_C | PCC_DC | PCC_Z) // outCond
};
pCodeInstruction pciADDLW = {
0,0, // branch, skip
0, // literal operand
POC_BSF,
- (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- PCC_REGISTER // outCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
};
pCodeInstruction pciBSF = {
0,0, // branch, skip
0, // literal operand
POC_BCF,
- (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
};
pCodeInstruction pciBTFSC = {
1,1, // branch, skip
0, // literal operand
POC_BTFSS,
- (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- PCC_EXAMINE_PCOP // outCond
+ (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
+ PCC_NONE // outCond
};
pCodeInstruction pciBTFSS = {
0, // literal operand
POC_BTFSC,
(PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond
- PCC_EXAMINE_PCOP // outCond
+ PCC_NONE // outCond
};
pCodeInstruction pciCALL = {
1,0, // branch, skip
0, // literal operand
POC_NOP,
- PCC_NONE, // inCond
- PCC_NONE // outCond
+ (PCC_NONE | PCC_W), // inCond, reads argument from WREG
+ (PCC_NONE | PCC_W | PCC_C | PCC_DC | PCC_Z) // outCond, flags are destroyed by called function
};
pCodeInstruction pciCOMF = {
0, // literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER | PCC_Z // outCond
};
pCodeInstruction pciCOMFW = {
0, // literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W | PCC_Z // outCond
};
pCodeInstruction pciCLRF = {
0, // literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER | PCC_Z // outCond
};
pCodeInstruction pciCLRW = {
0, // literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_W // outCond
+ PCC_W | PCC_Z // outCond
};
pCodeInstruction pciCLRWDT = {
0, // literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER | PCC_Z // outCond
};
pCodeInstruction pciDECFW = {
0, // literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W | PCC_Z // outCond
};
pCodeInstruction pciDECFSZ = {
0, // literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_REGISTER // outCond
+ PCC_REGISTER | PCC_Z // outCond
};
pCodeInstruction pciINCFW = {
0, // literal operand
POC_NOP,
PCC_REGISTER, // inCond
- PCC_W // outCond
+ PCC_W | PCC_Z // outCond
};
pCodeInstruction pciINCFSZ = {
0, // literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_NONE // outCond (not true... affects the GIE bit too)
+ (PCC_NONE | PCC_C | PCC_DC | PCC_Z) // outCond (not true... affects the GIE bit too), STATUS bit are retored
};
pCodeInstruction pciRETLW = {
1, // literal operand
POC_NOP,
PCC_LITERAL, // inCond
- PCC_W // outCond
+ (PCC_W| PCC_C | PCC_DC | PCC_Z) // outCond, STATUS bits are irrelevant after RETLW
};
pCodeInstruction pciRETURN = {
1,0, // branch, skip
0, // literal operand
POC_NOP,
- PCC_NONE, // inCond
- PCC_NONE // outCond
+ PCC_NONE | PCC_W, // inCond, return value is possibly present in W
+ (PCC_NONE | PCC_C | PCC_DC | PCC_Z) // outCond, STATUS bits are irrelevant after RETURN
};
pCodeInstruction pciRLF = {
0, // literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
+ (PCC_REGISTER | PCC_C ) // outCond
};
pCodeInstruction pciRLFW = {
0, // literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+ (PCC_W | PCC_C) // outCond
};
pCodeInstruction pciRRF = {
0, // literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
+ (PCC_REGISTER | PCC_C) // outCond
};
pCodeInstruction pciRRFW = {
0, // literal operand
POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+ (PCC_W | PCC_C) // outCond
};
pCodeInstruction pciSUBWF = {
0, // literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_REGISTER | PCC_Z) // outCond
+ (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z) // outCond
};
pCodeInstruction pciSUBFW = {
0, // literal operand
POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
- (PCC_W | PCC_Z) // outCond
+ (PCC_W | PCC_C | PCC_DC | PCC_Z) // outCond
};
pCodeInstruction pciSUBLW = {
0,0, // branch, skip
0, // literal operand
POC_NOP,
- PCC_NONE, // inCond
- PCC_REGISTER // outCond
+ PCC_NONE, // inCond /* FIXME: what's TRIS doing? */
+ PCC_REGISTER // outCond /* FIXME: what's TIS doing */
};
pCodeInstruction pciXORWF = {
1, // literal operand
POC_NOP,
(PCC_W | PCC_LITERAL), // inCond
- (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+ (PCC_W | PCC_Z) // outCond
};
0, // literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_REGISTER // outCond
+ PCC_NONE // outCond
};
pCodeInstruction pciPAGESEL = {
0, // literal operand
POC_NOP,
PCC_NONE, // inCond
- PCC_REGISTER // outCond
+ PCC_NONE // outCond
};
pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS];
char *name = pcop->name;
if (!name)
name = PCOR(pcop)->r->name;
- // if (strcmp(name, pc_status.pcop.name) != 0) { <<< This breaks the peep 2 optimisation
- switch(PCORB(pcop)->bit) {
- case PIC_C_BIT:
- return PCC_C;
- case PIC_DC_BIT:
- return PCC_DC;
- case PIC_Z_BIT:
- return PCC_Z;
+ if (strcmp(name, pc_status.pcop.name) == 0)
+ {
+ switch(PCORB(pcop)->bit) {
+ case PIC_C_BIT:
+ return PCC_C;
+ case PIC_DC_BIT:
+ return PCC_DC;
+ case PIC_Z_BIT:
+ return PCC_Z;
+ }
}
- // }
}
return 0;
pcop->name = NULL;
if(lit>=0) {
- sprintf(s,"0x%02x",lit);
+ sprintf(s,"0x%02x", (unsigned char)lit);
if(s)
pcop->name = Safe_strdup(s);
}
- ((pCodeOpLit *)pcop)->lit = lit;
+ ((pCodeOpLit *)pcop)->lit = (unsigned char)lit;
return pcop;
}
} else
SAFE_snprintf(&s,&size,"LOW (%s+%d)",pcop->name,PCOI(pcop)->index);
} else {
- if( !PCOI(pcop)->offset) { // && PCOI(pcc->pcop)->offset<4) {
+ if( !PCOI(pcop)->offset) { // && PCOI(pcc->pcop)->offset<4)
SAFE_snprintf(&s,&size,"(%s + %d)",
pcop->name,
PCOI(pcop)->index);
SAFE_snprintf(&s,&size,"%s",pcop->name);
}
return buffer;
-
+
case PO_GPR_BIT:
if(PCOR(pcop)->r) {
if(use_buffer) {
}
}
- printf("PIC port internal warning: (%s:%d) %s not found\n",
- __FUNCTION__,
- __LINE__,
+ printf("PIC port internal warning: (%s:%d(%s)) %s not found\n",
+ __FILE__, __LINE__, __FUNCTION__,
pCodeOpType(pcop));
return "NO operand";
/* Debug */
if(debug_verbose) {
pCodeOpReg *pcor = PCOR(pci->pcop);
- fprintf(of, "\t;id=%u,key=%03x",pc->id,pc->seq);
+ fprintf(of, "\t;id=%u,key=%03x,inCond:%x,outCond:%x",pc->id,pc->seq, pci->inCond, pci->outCond);
if(pci->pcflow)
fprintf(of,",flow seq=%03x",pci->pcflow->pc.seq);
if (pcor && pcor->pcop.type==PO_GPR_TEMP && !pcor->r->isFixed)
if(PCFL(pc)->ancestor)
fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq);
fprintf(of,"\n");
+ fprintf(of,"; from: ");
+ {
+ pCodeFlowLink *link;
+ for (link = setFirstItem(PCFL(pc)->from); link; link = setNextItem (PCFL(pc)->from))
+ {
+ fprintf(of,"%03x ",link->pcflow->pc.seq);
+ }
+ }
+ fprintf(of,"; to: ");
+ {
+ pCodeFlowLink *link;
+ for (link = setFirstItem(PCFL(pc)->to); link; link = setNextItem (PCFL(pc)->to))
+ {
+ fprintf(of,"%03x ",link->pcflow->pc.seq);
+ }
+ }
+ fprintf(of,"\n");
}
break;
return NULL;
switch(PCI(pc)->pcop->type) {
- case PO_INDF:
+ case PO_STATUS:
case PO_FSR:
- return PCOR(PCI(pc)->pcop)->r;
-
+ case PO_INDF:
+ case PO_INTCON:
case PO_BIT:
case PO_GPR_TEMP:
+ case PO_SFR_REGISTER:
+ case PO_PCL:
+ case PO_PCLATH:
return PCOR(PCI(pc)->pcop)->r;
-
- case PO_IMMEDIATE:
- r = PCOI(PCI(pc)->pcop)->r;
- if (r)
- return r;
- return dirregWithName(PCI(pc)->pcop->name);
-
+
+ case PO_GPR_REGISTER:
case PO_GPR_BIT:
+ case PO_DIR:
r = PCOR(PCI(pc)->pcop)->r;
if (r)
return r;
return dirregWithName(PCI(pc)->pcop->name);
- case PO_GPR_REGISTER:
- case PO_DIR:
- r = PCOR(PCI(pc)->pcop)->r;
+ case PO_LITERAL:
+ break;
+
+ case PO_IMMEDIATE:
+ r = PCOI(PCI(pc)->pcop)->r;
if (r)
return r;
return dirregWithName(PCI(pc)->pcop->name);
- case PO_LITERAL:
- break;
default:
break;
//fprintf(stderr," build: ");
//pflow->print(stderr,pflow);
- if( PCI(pc)->isSkip) {
+ if (checkLabel(pc)) {
+
+ /* This instruction marks the beginning of a
+ * new flow segment */
+
+ pc->seq = 0;
+ seq = 1;
+
+ /* If the previous pCode is not a flow object, then
+ * insert a new flow object. (This check prevents
+ * two consecutive flow objects from being insert in
+ * the case where a skip instruction preceeds an
+ * instruction containing a label.) */
+
+ last_pci = findPrevInstruction (pc->prev);
+
+ if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow)))
+ InsertpFlow(last_pci, &pflow);
+
+ PCI(pc)->pcflow = PCFL(pflow);
+
+ }
+
+ if(isPCI_SKIP(pc)) {
/* The two instructions immediately following this one
* mark the beginning of a new flow segment */
- while(pc && PCI(pc)->isSkip) {
+ while(pc && isPCI_SKIP(pc)) {
PCI(pc)->pcflow = PCFL(pflow);
pc->seq = seq-1;
pc->seq = 0;
InsertpFlow(pc, &pflow);
- } else if ( PCI(pc)->isBranch && !checkLabel(findNextInstruction(pc->next))) {
+ } else if ( isPCI_BRANCH(pc) && !checkLabel(findNextInstruction(pc->next))) {
InsertpFlow(pc, &pflow);
seq = 0;
- } else if (checkLabel(pc)) {
-
- /* This instruction marks the beginning of a
- * new flow segment */
-
- pc->seq = 0;
- seq = 1;
-
- /* If the previous pCode is not a flow object, then
- * insert a new flow object. (This check prevents
- * two consecutive flow objects from being insert in
- * the case where a skip instruction preceeds an
- * instruction containing a label.) */
-
- if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow)))
- InsertpFlow(findPrevInstruction(pc->prev), &pflow);
-
- PCI(pc)->pcflow = PCFL(pflow);
-
}
+
last_pci = pc;
pc = pc->next;
}
//FillFlow(PCFL(pcflow));
- pc = PCFL(pcflow)->end;
+ /* find last instruction in flow */
+ pc = findPrevInstruction (PCFL(pcflow)->end);
//fprintf(stderr, "LinkFlow - flow block (seq=%d) ", pcflow->seq);
if(isPCI_SKIP(pc)) {
//fprintf(stderr, "ends with branch\n ");
//pc->print(stderr,pc);
-
+
if(!(pcol && isPCOLAB(pcol))) {
if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
pc->print(stderr,pc);
__FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
//fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
- continue;
+ /* link CALLs to next instruction */
+ if (PCI(pc)->op != POC_CALL) continue;
}
if(isPCI(pc)) {
}
if(pc) {
- //fprintf(stderr, "ends with unknown\n");
- //pc->print(stderr,pc);
+ fprintf(stderr, "ends with unknown\n");
+ pc->print(stderr,pc);
continue;
}
- //fprintf(stderr, "ends with nothing: ERROR\n");
+ fprintf(stderr, "ends with nothing: ERROR\n");
}
}
}
*/
+void pCodeReplace (pCode *old, pCode *new)
+{
+ pCodeInsertAfter (old, new);
+
+ /* special handling for pCodeInstructions */
+ if (isPCI(new) && isPCI(old))
+ {
+ assert (!PCI(new)->from && !PCI(new)->to && !PCI(new)->label && /*!PCI(new)->pcflow && */!PCI(new)->cline);
+ PCI(new)->from = PCI(old)->from;
+ PCI(new)->to = PCI(old)->to;
+ PCI(new)->label = PCI(old)->label;
+ PCI(new)->pcflow = PCI(old)->pcflow;
+ PCI(new)->cline = PCI(old)->cline;
+ } // if
+
+ old->destruct (old);
+}
+
/*-----------------------------------------------------------------*/
/* Inserts a new pCodeInstruction before an existing one */
/*-----------------------------------------------------------------*/
static void insertPCodeInstruction(pCodeInstruction *pci, pCodeInstruction *new_pci)
{
+ pCode *pcprev;
+
+ pcprev = findPrevInstruction(pci->pc.prev);
pCodeInsertAfter(pci->pc.prev, &new_pci->pc);
/* The new instruction has the same pcflow block */
new_pci->pcflow = pci->pcflow;
-
+
+ /* Arrrrg: is pci's previous instruction is a skip, we need to
+ * change that into a jump (over pci and the new instruction) ... */
+ if (pcprev && isPCI_SKIP(pcprev))
+ {
+ symbol *lbl = newiTempLabel (NULL);
+ pCode *label = newpCodeLabel (NULL, lbl->key);
+ pCode *jump = newpCode(POC_GOTO, newpCodeOpLabel(NULL, lbl->key));
+
+ pCodeInsertAfter (pcprev, jump);
+
+ pCodeReplace (pcprev, pCodeInstructionCopy (PCI(pcprev), 1));
+ pcprev = NULL;
+ pCodeInsertAfter((pCode*)pci, label);
+ }
}
/*-----------------------------------------------------------------*/
/* Therefore banksel is only called for external registers or the */
/* first time a local register is encountered. */
/*-----------------------------------------------------------------*/
-static int LastRegIdx; /* If the previous register is the same one again then no need to change bank. */
+static int LastRegIdx = -1; /* If the previous register is the same one again then no need to change bank. */
static int BankSelect(pCodeInstruction *pci, int cur_bank, regs *reg)
{
int bank;
* not a skip type instruction */
pcprev = findPrevpCode(pc->prev, PC_OPCODE);
- if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+ /* This approach does not honor the presence of labels at this instruction... */
+ //if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
cur_bank = BankSelect(PCI(pc),cur_bank,reg);
- } else {
- cur_bank = BankSelect(PCI(pcprev),cur_bank,reg);
- }
+ //} else {
+ // cur_bank = BankSelect(PCI(pcprev),cur_bank,reg);
+ //}
if (!PCI(pc)->pcflow)
fprintf(stderr,"PCI ID=%d missing flow pointer ???\n",pc->id);
else
pCode *pc, *pcprev;
int matches =0;
- if(!pb || !peepOptimizing)
+ if(!pb || options.nopeep)
return 0;
DFPRINTF((stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb)));
OptimizepCode('*');
-
- /*
+ /*
for(pb = the_pFile->pbHead; pb; pb = pb->next)
DumpFlow(pb);
*/
void AnalyzeBanking(void)
{
pBlock *pb;
-
+
if(!picIsInitialized()) {
setDefMaxRam(); // Max RAM has not been included, so use default setting
}
+ if (!the_pFile) return;
+
/* Phase x - Flow Analysis - Used Banks
*
* In this phase, the individual flow blocks are examined
{
pBlock *pb;
InitReuseReg();
+ if (!the_pFile) return;
for(pb = the_pFile->pbHead; pb; pb = pb->next) {
/* Non static functions can be called from other modules so their registers must reassign */
if (pb->function_entries&&(PCF(setFirstItem(pb->function_entries))->isPublic||!pb->visited))