// Eventually this will go into device dependent files:
-pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,0,NULL};
+pCodeOpReg pc_status = {{PO_STATUS, "_STATUS"}, -1, NULL,0,NULL};
pCodeOpReg pc_indf = {{PO_INDF, "INDF"}, -1, NULL,0,NULL};
pCodeOpReg pc_fsr = {{PO_FSR, "FSR"}, -1, NULL,0,NULL};
pCodeOpReg pc_intcon = {{PO_INTCON, ""}, -1, NULL,0,NULL};
pCodeOpReg pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,0,NULL};
-pCodeOpReg pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,0,NULL};
+pCodeOpReg pc_pclath = {{PO_PCLATH, "_PCLATH"}, -1, NULL,0,NULL};
pCodeOpReg pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,0,NULL};
pCodeOpReg pc_wsave = {{PO_GPR_REGISTER, "WSAVE"}, -1, NULL,0,NULL};
void pCodeInitRegisters(void)
{
+ static int initialized=0;
+
+ if(initialized)
+ return;
+ initialized = 1;
initStack(0xfff, 8);
init_pic(port->processor);
- pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
+ pc_status.r = allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x80);
pc_pcl.r = allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
- pc_pclath.r = allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80);
+ pc_pclath.r = allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
pc_fsr.r = allocProcessorRegister(IDX_FSR,"FSR", PO_FSR, 0x80);
pc_indf.r = allocProcessorRegister(IDX_INDF,"INDF", PO_INDF, 0x80);
pc_intcon.r = allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-static pBranch * pBranchAppend(pBranch *h, pBranch *n)
+pBranch * pBranchAppend(pBranch *h, pBranch *n)
{
pBranch *b;
if(!h)
return n;
+ if(h == n)
+ return n;
+
b = h;
while(b->next)
b = b->next;
//pc->print(stderr,pc);
if(!(pcol && isPCOLAB(pcol))) {
- if((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)) {
pc->print(stderr,pc);
fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
}
extern void pCodeInsertAfter(pCode *pc1, pCode *pc2);
extern void dbg_dumpregusage(void);
extern pCode * findPrevInstruction(pCode *pci);
+extern pBranch * pBranchAppend(pBranch *h, pBranch *n);
void unlinkpCode(pCode *pc);
int total_registers_saved=0;
}
+/*-----------------------------------------------------------------*
+ *
+ *-----------------------------------------------------------------*/
+static void Remove1pcode(pCode *pc, regs *reg)
+{
+ pCode *pcn=NULL;
+
+ if(!reg || !pc)
+ return;
+
+ deleteSetItem (&(reg->reglives.usedpCodes),pc);
+/*
+ fprintf(stderr,"removing instruction:\n");
+ pc->print(stderr,pc);
+*/
+ if(PCI(pc)->label) {
+ pcn = findNextInstruction(pc->next);
+
+ if(pcn)
+ PCI(pcn)->label = pBranchAppend(PCI(pcn)->label,PCI(pc)->label);
+ }
+
+ if(PCI(pc)->cline) {
+ if(!pcn)
+ pcn = findNextInstruction(pc->next);
+
+ if(pcn) {
+ if(PCI(pcn)->cline) {
+ //fprintf(stderr, "source line has been optimized completely out\n");
+ //pc->print(stderr,pc);
+ } else {
+ PCI(pcn)->cline = PCI(pc)->cline;
+ }
+ }
+ }
+
+ pc->destruct(pc);
+
+}
+
/*-----------------------------------------------------------------*
* void RemoveRegsFromSet(set *regset)
*
{
regs *reg;
int used;
- for (reg = setFirstItem(regset) ; reg ;
- reg = setNextItem(regset)) {
+ while(regset) {
+ reg = regset->item;
+ regset = regset->next;
+/*
+ for (reg = setFirstItem(regset) ; reg ;
+ reg = setNextItem(regset)) {
+*/
used = elementsInSet(reg->reglives.usedpCodes);
if(used <= 1) {
//fprintf(stderr," reg %s isfree=%d, wasused=%d\n",reg->name,reg->isFree,reg->wasUsed);
-
if(used == 0) {
//fprintf(stderr," getting rid of reg %s\n",reg->name);
reg->isFree = 1;
pc = setFirstItem(reg->reglives.usedpCodes);
+
+ if(reg->type == REG_SFR) {
+ //fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name);
+ continue;
+ }
+
+
if(isPCI(pc)) {
if(PCI(pc)->label) {
pCode *pcn = findNextInstruction(pc->next);
}
- if(isPCI_SKIP(pc))
+ if(isPCI_SKIP(pc)) {
+ regs *r = getRegFromInstruction(pc);
fprintf(stderr, "WARNING, a skip instruction is being optimized out\n");
-
+ pc->print(stderr,pc);
+ fprintf(stderr,"reg %s, type =%d\n",r->name, r->type);
+ }
//fprintf(stderr," removing reg %s because it is used only once\n",reg->name);
- unlinkpCode(pc);
- deleteSetItem (&(reg->reglives.usedpCodes),pc);
+ Remove1pcode(pc, reg);
+ /*
+ unlinkpCode(pc);
+ deleteSetItem (&(reg->reglives.usedpCodes),pc);
+ */
reg->isFree = 1;
reg->wasUsed = 0;
total_registers_saved++; // debugging stats.
if(!reg)
return;
- if(pc1) {
- deleteSetItem (&(reg->reglives.usedpCodes),pc1);
- pc1->destruct(pc1);
- }
+ if(pc1)
+ Remove1pcode(pc1, reg);
if(pc2) {
- deleteSetItem (&(reg->reglives.usedpCodes),pc2);
- pc2->destruct(pc2);
-
+ Remove1pcode(pc2, reg);
deleteSetItem (&(PCFL(pcflow)->registers), reg);
reg->isFree = 1;
reg = fregs->item;
fregs = fregs->next;
+ if(reg->type == REG_SFR) {
+ //fprintf(stderr,"skipping SFR: %s\n",reg->name);
+ continue;
+ }
pcfl_used = setFirstItem(reg->reglives.usedpFlows);
pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
regs *reg1, *reg2;
/*
- fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x used=%d\n",
+ fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n",
reg->name,
reg->address,
- reg->rIdx, used);
+ reg->rIdx, reg->type, used);
*/
pc1 = setFirstItem(reg->reglives.usedpCodes);
pc2 = setNextItem(reg->reglives.usedpCodes);
reg1 = getRegFromInstruction(pct1);
if(reg1 && !regUsedinRange(pc1,pc2,reg1)) {
+ //fprintf(stderr, " MOVF/MOVFW. \n");
/*
movf reg1,w
movwf reg
/*
register has been used twice without ever being assigned */
- fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name);
+ //fprintf(stderr,"WARNING %s: reg %s used without being assigned\n",__FUNCTION__,reg->name);
} else {
//fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
pc = setFirstItem(reg->reglives.usedpCodes);
while(pc) {
- pcfl_assigned = PCI(pc)->pcflow;
+
+ pcfl_assigned = PCODE(PCI(pc)->pcflow);
+ Remove1pcode(pc, reg);
+
deleteSetItem (&(PCFL(pcfl_assigned)->registers), reg);
+ /*
deleteSetItem (&(reg->reglives.usedpCodes),pc);
pc->destruct(pc);
-
+ */
pc = setNextItem(reg->reglives.usedpCodes);
}
return "REG_CND";
}
- sprintf (buffer, "unkown reg type %d", type);
+ sprintf (buffer, "unknown reg type %d", type);
return buffer;
}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static int regname2key(char const *name)
+{
+ int key = 0;
+
+ if(!name)
+ return 0;
+
+ while(*name) {
+
+ key += (*name++) + 1;
+
+ }
+
+ return ( (key + (key >> 4) + (key>>8)) & 0x3f);
+
+}
+
/*-----------------------------------------------------------------*/
/* newReg - allocate and init memory for a new register */
/*-----------------------------------------------------------------*/
//fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
dReg->isFree = 0;
dReg->wasUsed = 1;
- dReg->isFixed = 0;
+ if(type == REG_SFR)
+ dReg->isFixed = 1;
+ else
+ dReg->isFixed = 0;
+
dReg->isMapped = 0;
dReg->isEmitted = 0;
dReg->address = 0;
dReg->reglives.usedpFlows = newSet();
dReg->reglives.assignedpFlows = newSet();
+ hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+
return dReg;
}
int i;
Gstack_base_addr = base_address;
+ //fprintf(stderr,"initStack");
+
for(i = 0; i<size; i++)
addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
}
regs *
allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
{
+
+ //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
}
{
regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
+ //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
if(reg) {
reg->wasUsed = 0;
return addSet(&dynInternalRegs,reg);
{
debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
+ //fprintf(stderr,"allocReg\n");
return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static int regname2key(char const *name)
-{
- int key = 0;
-
- if(!name)
- return 0;
-
- while(*name) {
-
- key += (*name++) + 1;
-
- }
-
- return ( (key + (key >> 4) + (key>>8)) & 0x3f);
-
-}
/*-----------------------------------------------------------------*/
/* dirregWithName - search for register by name */
return NULL;
/* First, search the hash table to see if there is a register with this name */
- reg = dirregWithName(name);
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
+ reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
+/*
+ if(!reg)
+ fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
+ name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+ else
+ fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
+ name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+*/
+ } else {
+ //fprintf(stderr,"ralloc %s \n", name);
+
+ reg = dirregWithName(name);
+ }
if(!reg) {
int address = 0;
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
if(!IS_CONFIG_ADDRESS(address)) {
+ //fprintf(stderr,"allocating new reg %s\n",name);
+
reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
-/*
+
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+
if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
- reg->isFixed = 1;
- reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
- debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
+
+ //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
+ reg->type = REG_SFR;
}
-*/
- hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+
if (IS_BITVAR (OP_SYM_ETYPE(op)))
addSet(&dynDirectBitRegs, reg);
else
addSet(&dynDirectRegs, reg);
+
} else {
debugLog (" -- %s is declared at address 0x2007\n",name);
exit(1);
}
- debugLog ("%s symbol name %s\n", __FUNCTION__,name);
-
/* First, search the hash table to see if there is a register with this name */
reg = dirregWithName(name);
/* Register wasn't found in hash, so let's create
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
-
+ //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
- hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
addSet(&dynDirectRegs, reg);
}
break;
}
-#if 0
-
- if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
-
- debugLog ("Found a Dynamic Register!\n");
- return dReg;
- }
-
- if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
- debugLog ("Found a Stack Register!\n");
- return dReg;
- }
-
- if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
- debugLog ("Found a Direct Register!\n");
- return dReg;
- }
-
- if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
- debugLog ("Found a Processor Register!\n");
- return dReg;
- }
-#endif
-
- /*
- if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
- debugLog ("Found a bit Register!\n");
- return dReg;
- }
- */
return NULL;
}
case REG_GPR:
if((dReg = regFindFree(dynAllocRegs)) != NULL)
return dReg;
-
+ //fprintf(stderr,"findfreereg\n");
return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
case REG_STK:
return nFreeRegs (type);
}
-//<<<<<<< ralloc.c
void writeSetUsedRegs(FILE *of, set *dRegs)
{
int byte_no=-1;
char buffer[20];
+
for (regset = bregs ; regset ;
regset = regset->next) {
if(!bitfield) {
sprintf (buffer, "fbitfield%02x", breg->address);
//fprintf(stderr,"new bit field\n");
- bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
+ bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
bitfield->isBitField = 1;
bitfield->isFixed = 1;
bitfield->address = breg->address;
addSet(&dynDirectRegs,bitfield);
- hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
} else {
//fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
;
relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
relocbitfield->isBitField = 1;
addSet(&dynDirectRegs,relocbitfield);
- hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
}
}
}
-void aliasEQUs(FILE *of, set *fregs)
+void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
{
regs *reg;
for (reg = setFirstItem(fregs) ; reg ;
reg = setNextItem(fregs)) {
- if(!reg->isEmitted && reg->wasUsed)
- fprintf (of, "%s\tEQU\t0x%03x\n",
- reg->name,
- reg->address);
+ if(!reg->isEmitted && reg->wasUsed) {
+ if(use_rIdx)
+ fprintf (of, "%s\tEQU\t0x%03x\n",
+ reg->name,
+ reg->rIdx);
+ else
+ fprintf (of, "%s\tEQU\t0x%03x\n",
+ reg->name,
+ reg->address);
+ }
}
}
dump_cblock(of);
bitEQUs(of,dynDirectBitRegs);
- aliasEQUs(of,dynAllocRegs);
- aliasEQUs(of,dynDirectRegs);
- aliasEQUs(of,dynStackRegs);
+ aliasEQUs(of,dynAllocRegs,0);
+ aliasEQUs(of,dynDirectRegs,0);
+ aliasEQUs(of,dynStackRegs,0);
+ aliasEQUs(of,dynProcessorRegs,1);
}
return TRUE;
}
#endif
-//=======
-//>>>>>>> 1.28
+
/*-----------------------------------------------------------------*/
/* computeSpillable - given a point find the spillable live ranges */
/*-----------------------------------------------------------------*/
//s += strlen(s);
//ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
//continue ;
- fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+ //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
return buffer;
}