Safe_free (*item);
*item = NULL;
}
+
+/*-----------------------------------------------------------------*/
+/* deleteSet - will throw away the entire list */
+/* note - setToNull doesn't actually throw away the whole list. */
+/* Instead it only throws away the first item. */
+/*-----------------------------------------------------------------*/
+void deleteSet(set **s)
+{
+ set *curr;
+ set *next;
+
+ if(!s || !*s)
+ return;
+
+ curr = *s;
+ next = curr->next;
+ while (next) {
+ Safe_free (curr);
+ curr = next;
+ next = next->next;
+ }
+
+ Safe_free (curr);
+
+ *s = NULL;
+}
+
void *setNextItem (set *);
void setToNull (void **);
set *reverseSet (set *);
+void deleteSet(set **s);
#endif
void genMult8X8_8 (operand *, operand *,operand *);
static int labelOffset=0;
-static int debug_verbose=1;
+extern int debug_verbose;
static int optimized_for_speed = 0;
/* max_key keeps track of the largest label number used in
if(!resIfx)
return;
- DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
resIfx->condition = 1; /* assume that the ifx is true */
resIfx->generated = 0; /* indicate that the ifx has not been used */
if(!ifx) {
resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
+/*
DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
__FUNCTION__,__LINE__,resIfx->lbl->key);
+*/
} else {
if(IC_TRUE(ifx)) {
resIfx->lbl = IC_TRUE(ifx);
resIfx->lbl = IC_FALSE(ifx);
resIfx->condition = 0;
}
+/*
if(IC_TRUE(ifx))
DEBUGpic14_emitcode("; ***","ifx true is non-null");
if(IC_FALSE(ifx))
DEBUGpic14_emitcode("; ***","ifx false is non-null");
+*/
}
- DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
+ // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static int resultRemat (iCode *ic)
{
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (SKIP_IC(ic) || ic->op == IFX)
- return 0;
+ // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (SKIP_IC(ic) || ic->op == IFX)
+ return 0;
- if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
- symbol *sym = OP_SYMBOL(IC_RESULT(ic));
- if (sym->remat && !POINTER_SET(ic))
- return 1;
- }
+ if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
+ symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+ if (sym->remat && !POINTER_SET(ic))
+ return 1;
+ }
- return 0;
+ return 0;
}
#if defined(__BORLANDC__) || defined(_MSC_VER)
// resolvedIfx rTrueIfx;
symbol *truelbl;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+/*
if(ifx) {
DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
}
-
+*/
resolveIfx(&rFalseIfx,ifx);
truelbl = newiTempLabel(NULL);
unsigned long mask = (0x100 << (8*(size-1))) - 1;
lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
#ifdef _swapp
- DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
- lit = (lit - 1) & mask;
- DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
+ lit = (lit - 1) & mask;
right = left;
left = tmp;
rFalseIfx.condition ^= 1;
return ;
}
-
+#if 0
/*-----------------------------------------------------------------*/
/* genDataPointerGet - generates code when ptr offset is known */
/*-----------------------------------------------------------------*/
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
-
+#endif
/*-----------------------------------------------------------------*/
/* genNearPointerGet - pic14_emitcode for near pointer fetch */
/*-----------------------------------------------------------------*/
iCode *ic)
{
asmop *aop = NULL;
- regs *preg = NULL ;
+ //regs *preg = NULL ;
char *rname ;
sym_link *rtype, *retype;
sym_link *ltype = operandType(left);
- char buffer[80];
+ //char buffer[80];
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* 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 */
static int GpCodeSequenceNumber = 1;
int GpcFlowSeq = 1;
extern void RemoveUnusedRegisters(void);
+extern void RegsUnMapLiveRanges(void);
extern void BuildFlowTree(pBlock *pb);
extern void pCodeRegOptimizeRegUsage(void);
/*-----------------------------------------------------------------*/
/* newpCodeFlow */
/*-----------------------------------------------------------------*/
-
void destructpCodeFlow(pCode *pc)
{
if(!pc || !isPCFL(pc))
return;
- if(PCFL(pc)->uses)
- free(PCFL(pc)->uses);
/*
if(PCFL(pc)->from)
if(PCFL(pc)->to)
*/
+ unlinkpCode(pc);
+
+ deleteSet(&PCFL(pc)->registers);
+ deleteSet(&PCFL(pc)->from);
+ deleteSet(&PCFL(pc)->to);
free(pc);
+
}
pCode *newpCodeFlow(void )
pcflow->pc.type = PC_FLOW;
pcflow->pc.prev = pcflow->pc.next = NULL;
- //pcflow->pc.from = pcflow->pc.to = pcflow->pc.label = NULL;
pcflow->pc.pb = NULL;
// pcflow->pc.analyze = genericAnalyze;
pcflow->pc.seq = GpcFlowSeq++;
- pcflow->nuses = 7;
- pcflow->uses = Safe_calloc(pcflow->nuses, sizeof(set *));
-
pcflow->from = pcflow->to = NULL;
pcflow->inCond = PCC_NONE;
fprintf(of,"%s",str);
/* Debug */
- fprintf(of, "\t;key=%03x",pc->seq);
- if(PCI(pc)->pcflow)
- fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
+ if(debug_verbose) {
+ fprintf(of, "\t;key=%03x",pc->seq);
+ if(PCI(pc)->pcflow)
+ fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
+ }
}
#if 0
{
break;
case PC_FLOW:
- fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
+ if(debug_verbose)
+ fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
break;
case PC_CSOURCE:
switch(PCI(pc)->pcop->type) {
case PO_INDF:
case PO_FSR:
- return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0);
+ return PCOR(PCI(pc)->pcop)->r;
+
+ // return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0);
case PO_BIT:
case PO_GPR_TEMP:
void InsertpFlow(pCode *pc, pCode **pflow)
{
- PCFL(*pflow)->end = pc;
+ if(*pflow)
+ PCFL(*pflow)->end = pc;
if(!pc || !pc->next)
return;
{
pCode *pc;
pCode *last_pci=NULL;
- pCode *pflow;
+ pCode *pflow=NULL;
int seq = 0;
if(!pb)
//fprintf (stderr,"build flow start seq %d ",GpcFlowSeq);
/* Insert a pCodeFlow object at the beginning of a pBlock */
- pflow = newpCodeFlow(); /* Create a new Flow object */
- pflow->next = pb->pcHead; /* Make the current head the next object */
- pb->pcHead->prev = pflow; /* let the current head point back to the flow object */
- pb->pcHead = pflow; /* Make the Flow object the head */
- pflow->pb = pb;
+ InsertpFlow(pb->pcHead, &pflow);
+
+ //pflow = newpCodeFlow(); /* Create a new Flow object */
+ //pflow->next = pb->pcHead; /* Make the current head the next object */
+ //pb->pcHead->prev = pflow; /* let the current head point back to the flow object */
+ //pb->pcHead = pflow; /* Make the Flow object the head */
+ //pflow->pb = pb;
for( pc = findNextInstruction(pb->pcHead);
pc != NULL;
}
//fprintf (stderr,",end seq %d",GpcFlowSeq);
- PCFL(pflow)->end = pb->pcTail;
+ if(pflow)
+ PCFL(pflow)->end = pb->pcTail;
}
/*-------------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void unBuildFlow(pBlock *pb)
{
- pCode *pc;
+ pCode *pc,*pcnext;
if(!pb)
return;
pc = pb->pcHead;
+
while(pc) {
- pCode *pcn = pc->next;
+ pcnext = pc->next;
if(isPCI(pc)) {
+
pc->seq = 0;
- PCI(pc)->pcflow = NULL;
- pc = pcn;
- } else if(isPCFL(pc)) {
- unlinkpCode(pc);
+ if(PCI(pc)->pcflow) {
+ //free(PCI(pc)->pcflow);
+ PCI(pc)->pcflow = NULL;
+ }
+
+ } else if(isPCFL(pc) )
pc->destruct(pc);
- } else
- pc = pcn;
+ pc = pcnext;
}
+
}
/*-----------------------------------------------------------------*/
*/
pc = findNextInstruction(pb->pcHead);
+ if(!pc)
+ return 0;
+
pcprev = pc->prev;
do {
}
/*-----------------------------------------------------------------*/
-/* AnalyzeBanking - Called after the memory addresses have been */
-/* assigned to the registers. */
+/* AnalyzeFlow - Examine the flow of the code and optimize */
/* */
/*-----------------------------------------------------------------*/
-void AnalyzeBanking(void)
+
+void AnalyzeFlow(void)
{
+ static int times_called=0;
pBlock *pb;
return;
+ /* if this is not the first time this function has been called,
+ then clean up old flow information */
+ if(times_called++) {
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ unBuildFlow(pb);
+
+ RegsUnMapLiveRanges();
+
+ }
+
+ GpcFlowSeq = 1;
+
/* Phase 2 - Flow Analysis - Register Banking
*
* In this phase, the individual flow blocks are examined
BuildFlowTree(pb);
*/
- /* Phase x - Flow Analysis - Used Banks
- *
- * In this phase, the individual flow blocks are examined
- * to determine the Register Banks they use
- */
-
- for(pb = the_pFile->pbHead; pb; pb = pb->next)
- BanksUsedFlow(pb);
-
/* Phase x - Flow Analysis - Used Banks
*
* In this phase, the individual flow blocks are examined
OptimizepCode('*');
+
/*
for(pb = the_pFile->pbHead; pb; pb = pb->next)
DumpFlow(pb);
FillFlow(PCFL(pcflow));
}
}
+
/*
for(pb = the_pFile->pbHead; pb; pb = pb->next) {
pCode *pcflow;
*/
}
+/*-----------------------------------------------------------------*/
+/* AnalyzeBanking - Called after the memory addresses have been */
+/* assigned to the registers. */
+/* */
+/*-----------------------------------------------------------------*/
+
+void AnalyzeBanking(void)
+{
+ pBlock *pb;
+
+ /* Phase x - Flow Analysis - Used Banks
+ *
+ * In this phase, the individual flow blocks are examined
+ * to determine the Register Banks they use
+ */
+
+ AnalyzeFlow();
+ AnalyzeFlow();
+
+ for(pb = the_pFile->pbHead; pb; pb = pb->next)
+ BanksUsedFlow(pb);
+}
+
/*-----------------------------------------------------------------*/
/* buildCallTree - look at the flow and extract all of the calls */
/* */
pCode *end; /* Last pCode in this flow. Note that
the first pCode is pc.next */
- set **uses; /* map the pCode instruction inCond and outCond conditions
+ /* set **uses; * map the pCode instruction inCond and outCond conditions
* in this array of set's. The reason we allocate an
* array of pointers instead of declaring each type of
* usage is because there are port dependent usage definitions */
- int nuses; /* number of uses sets */
+ //int nuses; /* number of uses sets */
set *from; /* flow blocks that can send control to this flow block */
set *to; /* flow blocks to which this one can send control */
pcin->prev = pc->prev;
- //#if 0
+#if 0
{
/* DEBUG */
/* Converted the deleted pCodes into comments */
if(pc_cline2)
pc_cline2->pc.next = NULL;
}
- //#endif
+#endif
if(pcin)
pCodeDeleteChain(pc,pcin);
pCodeRegMapLiveRangesInFlow(PCFL(pcflow));
}
-
+#if 0
for( pcflow = findNextpCode(pb->pcHead, PC_FLOW);
pcflow != NULL;
pcflow = findNextpCode(pcflow->next, PC_FLOW) ) {
regs *r = setFirstItem(PCFL(pcflow)->registers);
- //fprintf(stderr,"flow seq %d\n", pcflow->seq);
+ fprintf(stderr,"flow seq %d\n", pcflow->seq);
+
while (r) {
- //fprintf(stderr, " %s\n",r->name);
+ fprintf(stderr, " %s\n",r->name);
r = setNextItem(PCFL(pcflow)->registers);
}
}
+#endif
// dbg_dumpregusage();
reg = regset->item;
regset = regset->next;
-/*
- for (reg = setFirstItem(regset) ; reg ;
- reg = setNextItem(regset)) {
-*/
used = elementsInSet(reg->reglives.usedpCodes);
if(used <= 1) {
/*-----------------------------------------------------------------*
*
*-----------------------------------------------------------------*/
-static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg)
+static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int can_free)
{
if(!reg)
return;
Remove1pcode(pc2, reg);
deleteSetItem (&(PCFL(pcflow)->registers), reg);
- reg->isFree = 1;
- reg->wasUsed = 0;
+ if(can_free) {
+ reg->isFree = 1;
+ reg->wasUsed = 0;
+ }
}
return 0;
}
+/*-----------------------------------------------------------------*
+ * void pCodeOptime2pCodes(pCode *pc1, pCode *pc2)
+ *
+ * ADHOC pattern checking
+ * Now look for specific sequences that are easy to optimize.
+ * Many of these sequences are characteristic of the compiler
+ * (i.e. it'd probably be a waste of time to apply these adhoc
+ * checks to hand written assembly.)
+ *
+ *
+ *-----------------------------------------------------------------*/
+void pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free)
+{
+ pCode *pct1, *pct2;
+ regs *reg1, *reg2;
+
+ if(pc2->seq < pc1->seq) {
+ pct1 = pc2;
+ pc2 = pc1;
+ pc1 = pct1;
+ }
+
+
+ if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
+
+ /*
+ clrf reg
+ stuff...
+ movf reg,w
+
+ can be replaced with
+
+ stuff...
+ movlw 0
+ */
+
+ pCode *newpc;
+ //fprintf(stderr, " CLRF/MOVFW. instruction after MOVFW is:\n");
+ pct1 = findNextInstruction(pc2->next);
+ //t->print(stderr,t);
+
+ if(PCI(pct1)->op == POC_MOVWF) {
+ newpc = newpCode(POC_CLRF, PCI(pct1)->pcop);
+ pct1->destruct(pct1);
+ } else {
+ newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
+ }
+
+ pCodeInsertAfter(pc2, newpc);
+ PCI(newpc)->pcflow = PCFL(pcfl_used);
+ newpc->seq = pc2->seq;
+
+ Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
+ total_registers_saved++; // debugging stats.
+
+ } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){
+ //fprintf(stderr, " CLRF/IORFW.\n");
+
+ Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
+ total_registers_saved++; // debugging stats.
+
+ } else if(PCI(pc1)->op == POC_MOVWF) {
+
+ pct2 = findNextInstruction(pc2->next);
+
+ if(PCI(pc2)->op == POC_MOVFW) {
+ //fprintf(stderr, " MOVWF/MOVFW. instruction after MOVFW is:\n");
+ //pct2->print(stderr,pct2);
+
+ if(PCI(pct2)->op == POC_MOVWF) {
+ reg2 = getRegFromInstruction(pct2);
+ if(reg2 && !regUsedinRange(pc1,pc2,reg2)) {
+ pct2->seq = pc1->seq;
+ unlinkpCode(pct2);
+ pCodeInsertAfter(pc1,pct2);
+ Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
+ total_registers_saved++; // debugging stats.
+ return;
+ }
+/*
+ fprintf(stderr, " couldn't optimize\n");
+ if(reg2)
+ fprintf(stderr, " %s is used in range\n",reg2->name);
+ else
+ fprintf(stderr, " reg2 is NULL\n");
+*/
+ }
+ }
+
+ pct1 = findPrevInstruction(pc1->prev);
+ if(pct1 &&
+ (PCI(pct1)->pcflow == PCI(pc1)->pcflow) &&
+ (PCI(pct1)->op == POC_MOVFW)) {
+
+ reg1 = getRegFromInstruction(pct1);
+ if(reg1 && !regUsedinRange(pc1,pc2,reg1)) {
+ //fprintf(stderr, " MOVF/MOVFW. \n");
+ /*
+ movf reg1,w
+ movwf reg
+
+ stuff...
+ opcode reg,w
+ */
+ pct2 = newpCode(PCI(pc2)->op, PCI(pct1)->pcop);
+ pCodeInsertAfter(pc2, pct2);
+ PCI(pct2)->pcflow = PCFL(pcfl_used);
+ pct2->seq = pc2->seq;
+
+ Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
+ Remove2pcodes(pcfl_used, pct1, NULL, reg1, 0);
+ total_registers_saved++; // debugging stats.
+
+ }
+ }
+
+
+ }
+
+}
+
/*-----------------------------------------------------------------*
* void pCodeRegOptimeRegUsage(pBlock *pb)
*-----------------------------------------------------------------*/
while(fregs) {
- pCode *pcfl_used, *pcfl_assigned;
+ pCode *pcfl_used, *pcfl_assigned;
/* Step through the set by directly accessing the 'next' pointer.
* We could also step through by using the set API, but the
*/
pCode *pc1, *pc2;
- pCode *pct1, *pct2; /* two temporaries */
- regs *reg1, *reg2;
-
/*
fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n",
reg->name,
if(pcfl_used->seq == pcfl_assigned->seq) {
//fprintf(stderr, " and used in same flow\n");
- if(pc2->seq < pc1->seq) {
- pct1 = pc2;
- pc2 = pc1;
- pc1 = pct1;
- }
-
- //pc1->print(stderr,pc1);
- //pc2->print(stderr,pc2);
-
-
- /* ADHOC pattern checking
- * Now look for specific sequences that are easy to optimize.
- * Many of these sequences are characteristic of the compiler
- * (i.e. it'd probably be a waste of time to apply these adhoc
- * checks to hand written assembly.)
- *
- */
- if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
-
- /*
- clrf reg
- stuff...
- movf reg,w
-
- can be replaced with
-
- stuff...
- movlw 0
- */
-
- pCode *newpc;
- //fprintf(stderr, " CLRF/MOVFW. instruction after MOVFW is:\n");
- pct1 = findNextInstruction(pc2->next);
- //t->print(stderr,t);
-
- if(PCI(pct1)->op == POC_MOVWF) {
- newpc = newpCode(POC_CLRF, PCI(pct1)->pcop);
- pct1->destruct(pct1);
- } else {
- newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
- }
-
- pCodeInsertAfter(pc2, newpc);
- PCI(newpc)->pcflow = PCFL(pcfl_used);
- newpc->seq = pc2->seq;
-
- Remove2pcodes(pcfl_used, pc1, pc2, reg);
- total_registers_saved++; // debugging stats.
-
- } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){
- //fprintf(stderr, " CLRF/IORWF.\n");
-
- Remove2pcodes(pcfl_used, pc1, pc2, reg);
- total_registers_saved++; // debugging stats.
-
- } else if(PCI(pc1)->op == POC_MOVWF) {
-
- pct2 = findNextInstruction(pc2->next);
-
- if(PCI(pc2)->op == POC_MOVFW) {
- //fprintf(stderr, " MOVWF/MOVFW. instruction after MOVFW is:\n");
- // t->print(stderr,t);
-
- if(PCI(pct2)->op == POC_MOVWF) {
- reg2 = getRegFromInstruction(pct2);
- if(reg2 && !regUsedinRange(pc1,pc2,reg2)) {
- pct2->seq = pc1->seq;
- unlinkpCode(pct2);
- pCodeInsertAfter(pc1,pct2);
- Remove2pcodes(pcfl_used, pc1, pc2, reg);
- total_registers_saved++; // debugging stats.
- continue;
- }
- }
- }
-
- pct1 = findPrevInstruction(pc1->prev);
- if(pct1 &&
- (PCI(pct1)->pcflow == PCI(pc1)->pcflow) &&
- (PCI(pct1)->op == POC_MOVFW)) {
-
- reg1 = getRegFromInstruction(pct1);
- if(reg1 && !regUsedinRange(pc1,pc2,reg1)) {
- //fprintf(stderr, " MOVF/MOVFW. \n");
- /*
- movf reg1,w
- movwf reg
-
- stuff...
- opcode reg,w
- */
- pct2 = newpCode(PCI(pc2)->op, PCI(pct1)->pcop);
- pCodeInsertAfter(pc2, pct2);
- PCI(pct2)->pcflow = PCFL(pcfl_used);
- pct2->seq = pc2->seq;
-
- Remove2pcodes(pcfl_used, pc1, pc2, reg);
- Remove2pcodes(pcfl_used, pct1, NULL, reg1);
- total_registers_saved++; // debugging stats.
-
- }
- }
-
- }
+ pCodeOptime2pCodes(pc1, pc2, pcfl_used, reg, 1);
} else {
// fprintf(stderr, " and used in different flows\n");
- //pc1->print(stderr,pc1);
- //pc2->print(stderr,pc2);
}
} else if(pcfl_used) {
} else {
//fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
- Remove2pcodes(pcfl_assigned, pc1, pc2, reg);
+ Remove2pcodes(pcfl_assigned, pc1, pc2, reg, 1);
total_registers_saved++; // debugging stats.
}
} else {
+ /* register has been used either once, or more than twice */
+
if(used && !pcfl_used && pcfl_assigned) {
pCode *pc;
reg->wasUsed = 0;
total_registers_saved++; // debugging stats.
- }
+ } else if(used > 2) {
+
+ /* examine the number of times this register is used */
+ }
}
}
int passes = 4;
int saved = 0;
+ int t = total_registers_saved;
do {
saved = total_registers_saved;
} while( passes-- && (total_registers_saved != saved));
+
+ if(total_registers_saved == t)
+ fprintf(stderr, "No registers saved on this pass\n");
+
+
/*
fprintf(stderr,"dynamically allocated regs:\n");
dbg_regusage(dynAllocRegs);
fprintf(stderr,"direct regs:\n");
dbg_regusage(dynDirectRegs);
*/
+}
+
+
+/*-----------------------------------------------------------------*
+ * void RegsUnMapLiveRanges(set *regset)
+ *
+ *-----------------------------------------------------------------*/
+void RegsSetUnMapLiveRanges(set *regset)
+{
+ regs *reg;
+
+ while(regset) {
+ reg = regset->item;
+ regset = regset->next;
+
+
+ deleteSet(®->reglives.usedpCodes);
+ deleteSet(®->reglives.usedpFlows);
+ deleteSet(®->reglives.assignedpFlows);
+
+ }
+
+}
+
+void RegsUnMapLiveRanges(void)
+{
+ RegsSetUnMapLiveRanges(dynAllocRegs);
+ RegsSetUnMapLiveRanges(dynStackRegs);
+ RegsSetUnMapLiveRanges(dynDirectRegs);
+ RegsSetUnMapLiveRanges(dynProcessorRegs);
+ RegsSetUnMapLiveRanges(dynDirectBitRegs);
+ RegsSetUnMapLiveRanges(dynInternalRegs);
}
movwf %1
iorwf %2,w
}
+
+replace restart {
+ movf %1,w
+ movwf %2
+ movf %2,w
+} by {
+ ; peep 9c - Removed redundant move
+ movf %1,w
+ movwf %2
+}