extern void RemoveUnusedRegisters(void);
extern void RegsUnMapLiveRanges(void);
extern void BuildFlowTree(pBlock *pb);
-extern void pCodeRegOptimizeRegUsage(void);
+extern void pCodeRegOptimizeRegUsage(int level);
+extern int picIsInitialized(void);
/****************************************************************/
/* Forward declarations */
PCC_W // outCond
};
+pCodeInstruction pciCLRWDT = {
+ {PC_OPCODE, NULL, NULL, 0, NULL,
+ // genericAnalyze,
+ genericDestruct,
+ genericPrint},
+ POC_CLRWDT,
+ "CLRWDT",
+ NULL, // from branch
+ NULL, // to branch
+ NULL, // label
+ NULL, // operand
+ NULL, // flow block
+ NULL, // C source
+ 0, // num ops
+ 0,0, // dest, bit instruction
+ 0,0, // branch, skip
+ POC_NOP,
+ PCC_NONE, // inCond
+ PCC_NONE // outCond
+};
+
pCodeInstruction pciDECF = {
{PC_OPCODE, NULL, NULL, 0, NULL,
// genericAnalyze,
pic14Mnemonics[POC_COMFW] = &pciCOMFW;
pic14Mnemonics[POC_CLRF] = &pciCLRF;
pic14Mnemonics[POC_CLRW] = &pciCLRW;
+ pic14Mnemonics[POC_CLRWDT] = &pciCLRWDT;
pic14Mnemonics[POC_DECF] = &pciDECF;
pic14Mnemonics[POC_DECFW] = &pciDECFW;
pic14Mnemonics[POC_DECFSZ] = &pciDECFSZ;
while(pci) {
if(STRCASECMP(pci->mnemonic, mnem) == 0) {
- if((pci->num_ops <= 1) || (pci->isModReg == dest))
+ if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst))
return(pci->op);
}
PCORB(pcop)->bit = bit;
PCORB(pcop)->inBitSpace = inBitSpace;
+ /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */
+ PCOR(pcop)->r = NULL;
+ PCOR(pcop)->rIdx = 0;
return pcop;
}
if(PCOR(pcop)->r)
PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
- //fprintf(stderr, "newpcodeOpReg - rIdx = %d\n", PCOR(pcop)->r->rIdx);
}
pcop->type = PCOR(pcop)->r->pc_type;
pcop = newpCodeOpReg(-1);
break;
+ case PO_GPR_REGISTER:
+ if(name)
+ pcop = newpCodeOpRegFromStr(name);
+ else
+ pcop = newpCodeOpReg(-1);
+ break;
+
default:
pcop = Safe_calloc(1,sizeof(pCodeOp) );
pcop->type = type;
/*-----------------------------------------------------------------*/
void addpCode2pBlock(pBlock *pb, pCode *pc)
{
+
+ if(!pc)
+ return;
+
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 {
+ // if(pb->pcTail)
pb->pcTail->next = pc;
+
pc->prev = pb->pcTail;
- //pc->next = NULL;
pc->pb = pb;
+
pb->pcTail = pc;
}
}
break;
case PC_FLOW:
- if(debug_verbose)
- fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
+ if(debug_verbose) {
+ fprintf(of,";<>Start of new flow, seq=0x%x",pc->seq);
+ if(PCFL(pc)->ancestor)
+ fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq);
+ fprintf(of,"\n");
+
+ }
break;
case PC_CSOURCE:
InsertpFlow(pc, &pflow);
seq = 0;
- } else if (checkLabel(pc)) { //(PCI_HAS_LABEL(pc)) {
+ } else if (checkLabel(pc)) {
/* This instruction marks the beginning of a
* new flow segment */
pc->seq = 0;
- seq = 1;
- InsertpFlow(findPrevInstruction(pc->prev), &pflow);
+ 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);
}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*
+ * void LinkFlow(pBlock *pb)
+ *
+ * In BuildFlow, the PIC code has been partitioned into contiguous
+ * non-branching segments. In LinkFlow, we determine the execution
+ * order of these segments. For example, if one of the segments ends
+ * with a skip, then we know that there are two possible flow segments
+ * to which control may be passed.
+ *-----------------------------------------------------------------*/
void LinkFlow(pBlock *pb)
{
pCode *pc=NULL;
//pc->print(stderr,pc);
if(!(pcol && isPCOLAB(pcol))) {
- if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL)) {
+ 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);
fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
}
}
}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* Now loop through the pBlock and merge the labels with the opcodes */
- for(pc = pb->pcHead; pc; pc = pc->next) {
+ pc = pb->pcHead;
+ // for(pc = pb->pcHead; pc; pc = pc->next) {
+
+ while(pc) {
+ pCode *pcn = pc->next;
if(pc->type == PC_LABEL) {
//fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
if((pcnext = findNextInstruction(pc) )) {
- pCode *pcn = pc->next;
-
// Unlink the pCode label from it's pCode chain
unlinkpCode(pc);
pbr->pc = pc;
pbr->next = NULL;
-
PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr);
-
- pc = pcn;
} else {
fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
/* merge the source line symbolic info into the next instruction */
if((pcnext = findNextInstruction(pc) )) {
- pCode *pcn = pc->next;
-
// Unlink the pCode label from it's pCode chain
unlinkpCode(pc);
PCI(pcnext)->cline = PCCS(pc);
//fprintf(stderr, "merging CSRC\n");
//genericPrint(stderr,pcnext);
- pc = pcn;
}
}
-
+ pc = pcn;
}
pBlockRemoveUnusedLabels(pb);
/*-----------------------------------------------------------------*/
/* AnalyzeFlow - Examine the flow of the code and optimize */
/* */
+/* level 0 == minimal optimization */
+/* optimize registers that are used only by two instructions */
+/* level 1 == maximal optimization */
+/* optimize by looking at pairs of instructions that use the */
+/* register. */
/*-----------------------------------------------------------------*/
-void AnalyzeFlow(void)
+void AnalyzeFlow(int level)
{
static int times_called=0;
* In this phase, the individual flow blocks are examined
* to determine their order of excution.
*/
- /*
+
for(pb = the_pFile->pbHead; pb; pb = pb->next)
BuildFlowTree(pb);
- */
+
/* Phase x - Flow Analysis - Used Banks
*
RemoveUnusedRegisters();
// for(pb = the_pFile->pbHead; pb; pb = pb->next)
- pCodeRegOptimizeRegUsage();
+ pCodeRegOptimizeRegUsage(level);
OptimizepCode('*');
{
pBlock *pb;
+ if(!picIsInitialized()) {
+ fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
+ fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
+ fprintf(stderr,"support/scripts/inc2h.pl\n");
+ fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
+
+ exit(1);
+ }
+
/* Phase x - Flow Analysis - Used Banks
*
* In this phase, the individual flow blocks are examined
* to determine the Register Banks they use
*/
- AnalyzeFlow();
- AnalyzeFlow();
+ AnalyzeFlow(0);
+ AnalyzeFlow(1);
for(pb = the_pFile->pbHead; pb; pb = pb->next)
BanksUsedFlow(pb);
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ FixRegisterBanking(pb);
+
}
/*-----------------------------------------------------------------*/