#include "pcode.h"
#include "gen.h"
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
/*-----------------------------------------------------------------*/
/* At this point we start getting processor specific although */
/* some routines are non-processor specific & can be reused when */
/*-----------------------------------------------------------------*/
extern void genpic14Code (iCode *);
+extern void assignConfigWordValue(int address, int value);
/* Global data */
static struct
/* Shared with gen.c */
int pic14_ptrRegReq; /* one byte pointer register required */
-/* pic14 registers */
-/* A nasty, awful, disgusting hack for register declarations */
-#ifdef p16c84
-
-regs regspic14[] =
-{
-
- {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
- {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
-
-};
-#else
-int Gstack_base_addr=0x38; /* The starting address of registers that
- * are used to pass and return parameters */
-regs regspic14[] =
-{
- {REG_GPR, PO_GPR_TEMP, 0x20, "r0x20", "r0x20", 0x20, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x21, "r0x21", "r0x21", 0x21, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x22, "r0x22", "r0x22", 0x22, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x23, "r0x23", "r0x23", 0x23, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x24, "r0x24", "r0x24", 0x24, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x25, "r0x25", "r0x25", 0x25, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x26, "r0x26", "r0x26", 0x26, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x27, "r0x27", "r0x27", 0x27, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x28, "r0x28", "r0x28", 0x28, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x29, "r0x29", "r0x29", 0x29, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x2A, "r0x2A", "r0x2A", 0x2A, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x2B, "r0x2B", "r0x2B", 0x2B, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x2C, "r0x2C", "r0x2C", 0x2C, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x2D, "r0x2D", "r0x2D", 0x2D, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x2E, "r0x2E", "r0x2E", 0x2E, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x2F, "r0x2F", "r0x2F", 0x2F, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x30, "r0x30", "r0x30", 0x30, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x31, "r0x31", "r0x31", 0x31, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x32, "r0x32", "r0x32", 0x32, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x33, "r0x33", "r0x33", 0x33, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x34, "r0x34", "r0x34", 0x34, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x35, "r0x35", "r0x35", 0x35, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x36, "r0x36", "r0x36", 0x36, 1, 0},
- {REG_GPR, PO_GPR_TEMP, 0x37, "r0x37", "r0x37", 0x37, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x38, "r0x38", "r0x38", 0x38, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x39, "r0x39", "r0x39", 0x39, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x3A, "r0x3A", "r0x3A", 0x3A, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x3B, "r0x3B", "r0x3B", 0x3B, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x3C, "r0x3C", "r0x3C", 0x3C, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x3D, "r0x3D", "r0x3D", 0x3D, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x3E, "r0x3E", "r0x3E", 0x3E, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x3F, "r0x3F", "r0x3F", 0x3F, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x40, "r0x40", "r0x40", 0x40, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x41, "r0x41", "r0x41", 0x41, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x42, "r0x42", "r0x42", 0x42, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x43, "r0x43", "r0x43", 0x43, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x44, "r0x44", "r0x44", 0x44, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x45, "r0x45", "r0x45", 0x45, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x46, "r0x46", "r0x46", 0x46, 1, 0},
- {REG_STK, PO_GPR_TEMP, 0x47, "r0x47", "r0x47", 0x47, 1, 0},
-
- {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
-
-};
+set *dynAllocRegs=NULL;
+set *dynStackRegs=NULL;
+set *dynProcessorRegs=NULL;
+set *dynDirectRegs=NULL;
+set *dynDirectBitRegs=NULL;
+set *dynInternalRegs=NULL;
+
+static hTab *dynDirectRegNames= NULL;
+// static hTab *regHash = NULL; /* a hash table containing ALL registers */
+
+static int dynrIdx=0x20;
+static int rDirectIdx=0;
+
+int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
+
+int Gstack_base_addr=0; /* The starting address of registers that
+ * are used to pass and return parameters */
+
+
-#endif
-int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
static void spillThis (symbol *);
static int debug = 1;
static FILE *debugF = NULL;
//char *bufferP=buffer;
va_list ap;
- if (!debug || !srcFileName)
+ if (!debug || !dstFileName)
return;
if (!debugF)
{
/* create the file name */
- strcpy (buffer, srcFileName);
+ strcpy (buffer, dstFileName);
strcat (buffer, ".d");
if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
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 */
+/*-----------------------------------------------------------------*/
+static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
+{
+
+ regs *dReg;
+
+ dReg = Safe_calloc(1,sizeof(regs));
+ dReg->type = type;
+ dReg->pc_type = pc_type;
+ dReg->rIdx = rIdx;
+ if(name)
+ dReg->name = Safe_strdup(name);
+ else {
+ sprintf(buffer,"r0x%02X", dReg->rIdx);
+ if(type == REG_STK)
+ *buffer = 's';
+ dReg->name = Safe_strdup(buffer);
+ }
+ //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
+ dReg->isFree = 0;
+ dReg->wasUsed = 1;
+ if(type == REG_SFR)
+ dReg->isFixed = 1;
+ else
+ dReg->isFixed = 0;
+
+ dReg->isMapped = 0;
+ dReg->isEmitted = 0;
+ dReg->address = 0;
+ dReg->size = size;
+ dReg->alias = alias;
+ dReg->reg_alias = NULL;
+ dReg->reglives.usedpFlows = newSet();
+ dReg->reglives.assignedpFlows = newSet();
+
+ hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+
+ return dReg;
+}
+
+/*-----------------------------------------------------------------*/
+/* regWithIdx - Search through a set of registers that matches idx */
+/*-----------------------------------------------------------------*/
+static regs *
+regWithIdx (set *dRegs, int idx, int fixed)
+{
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
+ return dReg;
+ }
+ }
+
+ return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* regFindFree - Search for a free register in a set of registers */
+/*-----------------------------------------------------------------*/
+static regs *
+regFindFree (set *dRegs)
+{
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if(dReg->isFree)
+ return dReg;
+ }
+
+ return NULL;
+}
+/*-----------------------------------------------------------------*/
+/* initStack - allocate registers for a psuedo stack */
+/*-----------------------------------------------------------------*/
+void initStack(int base_address, int size)
+{
+
+ 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 *
+allocInternalRegister(int rIdx, char * name, short po_type, int alias)
+{
+ regs * reg = newReg(REG_GPR, 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);
+ }
+
+ return NULL;
+}
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
/*-----------------------------------------------------------------*/
static regs *
allocReg (short type)
{
- int i;
debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
+ //fprintf(stderr,"allocReg\n");
- for (i = 0; i < pic14_nRegs; i++)
- {
- /* if type is given as 0 then any
- free register will do */
- if (!type &&
- regspic14[i].isFree)
- {
- regspic14[i].isFree = 0;
- regspic14[i].wasUsed = 1;
- if (currFunc)
- currFunc->regsUsed =
- bitVectSetBit (currFunc->regsUsed, i);
- debugLog (" returning %s\n", regspic14[i].name);
- return ®spic14[i];
- }
- /* other wise look for specific type
- of register */
- if (regspic14[i].isFree &&
- regspic14[i].type == type)
- {
- regspic14[i].isFree = 0;
- regspic14[i].wasUsed = 1;
- if (currFunc)
- currFunc->regsUsed =
- bitVectSetBit (currFunc->regsUsed, i);
- debugLog (" returning %s\n", regspic14[i].name);
- return ®spic14[i];
- }
+ return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* dirregWithName - search for register by name */
+/*-----------------------------------------------------------------*/
+regs *
+dirregWithName (char *name)
+{
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+ reg = hTabFirstItemWK(dynDirectRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ return(reg);
}
+
+ reg = hTabNextItemWK (dynDirectRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
+}
+
+int IS_CONFIG_ADDRESS(int address)
+{
+
+ return address == 0x2007;
+}
+
+/*-----------------------------------------------------------------*/
+/* allocDirReg - allocates register of given type */
+/*-----------------------------------------------------------------*/
+regs *
+allocDirReg (operand *op )
+{
+
+ regs *reg;
+ char *name;
+
+ if(!IS_SYMOP(op)) {
+ debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+ return NULL;
+ }
+
+ name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+
+ /* If the symbol is at a fixed address, then remove the leading underscore
+ * from the name. This is hack to allow the .asm include file named registers
+ * to match the .c declared register names */
+
+ //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
+ //name++;
+
+ debugLog ("%s symbol name %s\n", __FUNCTION__,name);
+ {
+ if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
+ debugLog(" %d const char\n",__LINE__);
+ debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+ }
+
+ debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
+ if (IS_CODE ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d code space\n",__LINE__);
+
+ if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d integral\n",__LINE__);
+ if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d literal\n",__LINE__);
+ if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d specifier\n",__LINE__);
+ debugAopGet(NULL, op);
+ }
+
+ if (IS_CODE ( OP_SYM_ETYPE(op)) )
+ return NULL;
+
+ /* First, search the hash table to see if there is a register with this 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:%d %s \n", __LINE__,name);
+
+ reg = dirregWithName(name);
+ }
+
+ if(!reg) {
+ int address = 0;
+
+ /* if this is at an absolute address, then get the address. */
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+ address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+ //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
+ }
+
+ /* 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 */
+ 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)) ) {
+
+ //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
+ reg->type = REG_SFR;
+ }
+
+ if (IS_BITVAR (OP_SYM_ETYPE(op))) {
+ addSet(&dynDirectBitRegs, reg);
+ reg->isBitField = 1;
+ } else
+ addSet(&dynDirectRegs, reg);
+
+ } else {
+ debugLog (" -- %s is declared at address 0x2007\n",name);
+
+ }
+ }
+
+ 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);
+ }
+
+ return reg;
+}
+
+/*-----------------------------------------------------------------*/
+/* allocDirReg - allocates register of given type */
+/*-----------------------------------------------------------------*/
+regs *
+allocRegByName (char *name, int size)
+{
+
+ regs *reg;
+
+ if(!name) {
+ fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
+ exit(1);
+ }
+
+ /* First, search the hash table to see if there is a register with this name */
+ reg = dirregWithName(name);
+
+ if(!reg) {
+
+ /* 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);
+ addSet(&dynDirectRegs, reg);
+ }
+
+ return reg;
+}
+
+/*-----------------------------------------------------------------*/
+/* RegWithIdx - returns pointer to register with index number */
+/*-----------------------------------------------------------------*/
+regs *
+typeRegWithIdx (int idx, int type, int fixed)
+{
+
+ regs *dReg;
+
+ debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
+
+ switch (type) {
+
+ case REG_GPR:
+ if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
+
+ debugLog ("Found a Dynamic Register!\n");
+ return dReg;
+ }
+ if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
+ debugLog ("Found a Direct Register!\n");
+ return dReg;
+ }
+
+ break;
+ case REG_STK:
+ if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
+ debugLog ("Found a Stack Register!\n");
+ return dReg;
+ }
+ break;
+ case REG_SFR:
+ if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
+ debugLog ("Found a Processor Register!\n");
+ return dReg;
+ }
+
+ case REG_CND:
+ case REG_PTR:
+ default:
+ break;
+ }
+
+
return NULL;
}
/*-----------------------------------------------------------------*/
-/* pic14_regWithIdx - returns pointer to register wit index number */
+/* pic14_regWithIdx - returns pointer to register with index number*/
/*-----------------------------------------------------------------*/
regs *
pic14_regWithIdx (int idx)
{
- int i;
+ regs *dReg;
- debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
+ if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
+ return dReg;
- for (i = 0; i < pic14_nRegs; i++)
- if (regspic14[i].rIdx == idx)
- return ®spic14[i];
+ if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
+ return dReg;
- //return ®spic14[0];
- fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "regWithIdx not found");
- exit (1);
+ if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
+ return dReg;
+
+ return NULL;
}
+/*-----------------------------------------------------------------*/
+/* pic14_regWithIdx - returns pointer to register with index number */
+/*-----------------------------------------------------------------*/
+regs *
+pic14_allocWithIdx (int idx)
+{
+
+ regs *dReg;
+
+ debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
+
+ if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
+
+ debugLog ("Found a Dynamic Register!\n");
+ } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
+ debugLog ("Found a Stack Register!\n");
+ } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
+ debugLog ("Found a Processor Register!\n");
+ } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
+ debugLog ("Found an Internal Register!\n");
+ } else {
+
+ debugLog ("Dynamic Register not found\n");
+
+
+ //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "regWithIdx not found");
+ exit (1);
+
+ }
+
+ dReg->wasUsed = 1;
+ dReg->isFree = 0;
+
+ return dReg;
+}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
regs *
pic14_findFreeReg(short type)
{
- int i;
+ // int i;
+ regs* dReg;
- for (i = 0; i < pic14_nRegs; i++) {
- if (!type && regspic14[i].isFree)
- return ®spic14[i];
- if (regspic14[i].isFree &&
- regspic14[i].type == type)
- return ®spic14[i];
+ switch (type) {
+ case REG_GPR:
+ if((dReg = regFindFree(dynAllocRegs)) != NULL)
+ return dReg;
+ return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+
+ case REG_STK:
+
+ if((dReg = regFindFree(dynStackRegs)) != NULL)
+ return dReg;
+
+ return NULL;
+
+ case REG_PTR:
+ case REG_CND:
+ case REG_SFR:
+ default:
+ return NULL;
}
- return NULL;
}
/*-----------------------------------------------------------------*/
/* freeReg - frees a register */
static int
nFreeRegs (int type)
{
+ /* dynamically allocate as many as we need and worry about
+ * fitting them into a PIC later */
+
+ return 100;
+#if 0
int i;
int nfr = 0;
if (regspic14[i].isFree && regspic14[i].type == type)
nfr++;
return nfr;
+#endif
}
/*-----------------------------------------------------------------*/
return nFreeRegs (type);
}
+void writeSetUsedRegs(FILE *of, set *dRegs)
+{
+
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if(dReg->wasUsed)
+ fprintf (of, "\t%s\n",dReg->name);
+ }
+
+}
+extern void assignFixedRegisters(set *regset);
+extern void assignRelocatableRegisters(set *regset,int used);
+extern void dump_map(void);
+extern void dump_cblock(FILE *of);
+
+
+void packBits(set *bregs)
+{
+ set *regset;
+ regs *breg;
+ regs *bitfield=NULL;
+ regs *relocbitfield=NULL;
+ int bit_no=0;
+ int byte_no=-1;
+ char buffer[20];
+
+
+ for (regset = bregs ; regset ;
+ regset = regset->next) {
+
+ breg = regset->item;
+ breg->isBitField = 1;
+ //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+ if(breg->isFixed) {
+ //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
+
+ bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
+ breg->rIdx = breg->address & 7;
+ breg->address >>= 3;
+
+ if(!bitfield) {
+ sprintf (buffer, "fbitfield%02x", breg->address);
+ //fprintf(stderr,"new bit field\n");
+ 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);
+ } else {
+ //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
+ ;
+ }
+ breg->reg_alias = bitfield;
+ bitfield = NULL;
+
+ } else {
+ if(!relocbitfield || bit_no >7) {
+ byte_no++;
+ bit_no=0;
+ sprintf (buffer, "bitfield%d", byte_no);
+ //fprintf(stderr,"new relocatable bit field\n");
+ relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
+ relocbitfield->isBitField = 1;
+ addSet(&dynDirectRegs,relocbitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+
+ }
+ breg->reg_alias = relocbitfield;
+ breg->address = rDirectIdx; /* byte_no; */
+ breg->rIdx = bit_no++;
+ }
+ }
+
+}
+
+
+
+void bitEQUs(FILE *of, set *bregs)
+{
+ regs *breg,*bytereg;
+ int bit_no=0;
+
+ //fprintf(stderr," %s\n",__FUNCTION__);
+ for (breg = setFirstItem(bregs) ; breg ;
+ breg = setNextItem(bregs)) {
+
+ //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+ bytereg = breg->reg_alias;
+ if(bytereg)
+ fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
+ breg->name,
+ bytereg->name,
+ breg->rIdx & 0x0007);
+
+ else {
+ fprintf(stderr, "bit field is not assigned to a register\n");
+ fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
+ breg->name,
+ bit_no>>3,
+ bit_no & 0x0007);
+
+ bit_no++;
+ }
+ }
+
+}
+void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
+{
+ regs *reg;
+
+
+ for (reg = setFirstItem(fregs) ; reg ;
+ reg = setNextItem(fregs)) {
+
+ 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);
+ }
+ }
+
+}
+
+void writeUsedRegs(FILE *of)
+{
+ packBits(dynDirectBitRegs);
+
+
+ assignFixedRegisters(dynAllocRegs);
+ assignFixedRegisters(dynStackRegs);
+ assignFixedRegisters(dynDirectRegs);
+
+ assignRelocatableRegisters(dynInternalRegs,0);
+ assignRelocatableRegisters(dynAllocRegs,0);
+ assignRelocatableRegisters(dynStackRegs,0);
+ assignRelocatableRegisters(dynDirectRegs,0);
+
+ //dump_map();
+
+ dump_cblock(of);
+ bitEQUs(of,dynDirectBitRegs);
+ aliasEQUs(of,dynAllocRegs,0);
+ aliasEQUs(of,dynDirectRegs,0);
+ aliasEQUs(of,dynStackRegs,0);
+ aliasEQUs(of,dynProcessorRegs,1);
+
+}
+
+#if 0
/*-----------------------------------------------------------------*/
/* allDefsOutOfRange - all definitions are out of a range */
/*-----------------------------------------------------------------*/
return TRUE;
}
+#endif
/*-----------------------------------------------------------------*/
/* computeSpillable - given a point find the spillable live ranges */
return sym->remat;
}
-/*-----------------------------------------------------------------*/
-/* notUsedInBlock - not used in this block */
-/*-----------------------------------------------------------------*/
-static int
-notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
-{
- debugLog ("%s\n", __FUNCTION__);
- return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
- allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
-/* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
-}
-
/*-----------------------------------------------------------------*/
/* notUsedInRemaining - not used or defined in remain of the block */
/*-----------------------------------------------------------------*/
/* if none of the liveRanges have a spillLocation then better
to spill this one than anything else already assigned to registers */
if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
- spillThis (sym);
- continue;
+ /* if this is local to this block then we might find a block spil */
+ if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
+ spillThis (sym);
+ continue;
+ }
}
}
}
}
}
+/*-----------------------------------------------------------------*/
+/* rematStr - returns the rematerialized string for a remat var */
+/*-----------------------------------------------------------------*/
+static symbol *
+rematStr (symbol * sym)
+{
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+ symbol *psym = NULL;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ //printf ("%s\n", s);
+
+ /* if plus or minus print the right hand side */
+
+ if (ic->op == '+' || ic->op == '-') {
+
+ iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+
+ sprintf (s, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ric))->rname,
+ ic->op,
+ (int) operandLitValue (IC_RIGHT (ic)));
+
+
+ //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+
+ psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
+ psym->offset = (int) operandLitValue (IC_RIGHT (ic));
+
+ return psym;
+ }
+
+ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+ psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
+
+ //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
+ return psym;
+}
+
+#if 0
/*-----------------------------------------------------------------*/
/* rematStr - returns the rematerialized string for a remat var */
/*-----------------------------------------------------------------*/
//s += strlen(s);
//ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
//continue ;
+ //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
return buffer;
}
printf ("%s\n", buffer);
return buffer;
}
+#endif
/*-----------------------------------------------------------------*/
/* regTypeNum - computes the type & number of registers required */
DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
/* create a psuedo symbol & force a spil */
- symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
psym->type = sym->type;
psym->etype = sym->etype;
strcpy (psym->rname, psym->name);
getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
getSize (sym->type));
+
+ if(IS_PTR_CONST (sym->type)) {
+ debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
+ sym->nRegs = 2;
+ }
+
if (sym->nRegs > 4) {
fprintf (stderr, "allocated more than 4 or 0 registers for type ");
printTypeChain (sym->type, stderr);
}
}
+DEFSETFUNC (markRegFree)
+{
+ ((regs *)item)->isFree = 1;
+
+ return 0;
+}
+
+DEFSETFUNC (deallocReg)
+{
+ fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
+ ((regs *)item)->isFree = 1;
+ ((regs *)item)->wasUsed = 0;
+ return 0;
+}
/*-----------------------------------------------------------------*/
/* freeAllRegs - mark all registers as free */
/*-----------------------------------------------------------------*/
void
pic14_freeAllRegs ()
{
- int i;
+ // int i;
debugLog ("%s\n", __FUNCTION__);
+
+ applyToSet(dynAllocRegs,markRegFree);
+ applyToSet(dynStackRegs,markRegFree);
+
+/*
for (i = 0; i < pic14_nRegs; i++)
regspic14[i].isFree = 1;
+*/
}
/*-----------------------------------------------------------------*/
void
pic14_deallocateAllRegs ()
{
- int i;
+ // int i;
debugLog ("%s\n", __FUNCTION__);
+
+ applyToSet(dynAllocRegs,deallocReg);
+
+/*
for (i = 0; i < pic14_nRegs; i++) {
- regspic14[i].isFree = 1;
- regspic14[i].wasUsed = 0;
+ if(regspic14[i].pc_type == PO_GPR_TEMP) {
+ regspic14[i].isFree = 1;
+ regspic14[i].wasUsed = 0;
+ }
}
+*/
}
debugAopGet (" left:", IC_LEFT (ic));
debugAopGet (" right:", IC_RIGHT (ic));
- if (!IS_ITEMP (IC_RIGHT (ic)) ||
- OP_SYMBOL (IC_RIGHT (ic))->isind ||
+ /* if this is at an absolute address, then get the address. */
+ if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
+ if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
+ debugLog (" %d - found config word declaration\n", __LINE__);
+ if(IS_VALOP(IC_RIGHT(ic))) {
+ debugLog (" setting config word to %x\n",
+ (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+ assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
+ (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+ }
+
+ /* remove the assignment from the iCode chain. */
+
+ remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+
+ return 1;
+
+ }
+ }
+
+ if (!IS_ITEMP (IC_RESULT (ic))) {
+ allocDirReg(IC_RESULT (ic));
+ debugLog (" %d - result is not temp\n", __LINE__);
+ }
+/*
+ if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
+ debugLog (" %d - left is not temp, allocating\n", __LINE__);
+ allocDirReg(IC_LEFT (ic));
+ }
+*/
+
+ if (!IS_ITEMP (IC_RIGHT (ic))) {
+ debugLog (" %d - not packing - right is not temp\n", __LINE__);
+ allocDirReg(IC_RIGHT (ic));
+ return 0;
+ }
+
+ if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
{
debugLog (" %d - not packing - right side fails \n", __LINE__);
if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
IS_OP_VOLATILE (IC_RESULT (dic)))
{
- debugLog (" %d - \n", __LINE__);
+ debugLog (" %d - dic is VOLATILE \n", __LINE__);
dic = NULL;
break;
}
if (IS_SYMOP (IC_RESULT (dic)) &&
IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
{
- debugLog (" %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
+ /* A previous result was assigned to the same register - we'll our definition */
+ debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
+ __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
if (POINTER_SET (dic))
dic = NULL;
(IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
{
- debugLog (" %d - \n", __LINE__);
+ debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
dic = NULL;
break;
}
(IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
{
- debugLog (" %d - \n", __LINE__);
+ debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
dic = NULL;
break;
}
if (POINTER_SET (dic) &&
IC_RESULT (dic)->key == IC_RESULT (ic)->key)
{
- debugLog (" %d - \n", __LINE__);
+ debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
+ __LINE__);
dic = NULL;
break;
}
}
pack:
debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
+ debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
/* found the definition */
/* replace the result with the result of */
/* this assignment and remove this assignment */
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
IC_RESULT (dic) = IC_RESULT (ic);
if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
}
remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
return 1;
IC_RIGHT (dic)->operand.symOperand;
IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
remiCodeFromeBBlock (ebp, dic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
change++;
}
IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
remiCodeFromeBBlock (ebp, dic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
change++;
}
a function call */
if (dic->op == CALL || dic->op == PCALL)
{
- if (ic->op != SEND && ic->op != RETURN)
+ if (ic->op != SEND && ic->op != RETURN &&
+ !POINTER_SET(ic) && !POINTER_GET(ic))
{
OP_SYMBOL (op)->ruonly = 1;
return dic;
iCode *uic;
debugLog ("%s\n", __FUNCTION__);
+
+ /* if this is an aggregate, e.g. a one byte char array */
+ if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
+ return;
+ }
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+
/* if + or - then it has to be one byte result */
if ((ic->op == '+' || ic->op == '-')
&& getSize (operandType (IC_RESULT (ic))) > 1)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* if shift operation make sure right side is not a literal */
if (ic->op == RIGHT_OP &&
(isOperandLiteral (IC_RIGHT (ic)) ||
bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
if (ic->next != uic)
return;
getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
if (uic->op != '=' &&
!IS_ARITHMETIC_OP (uic) &&
!IS_BITWISE_OP (uic) &&
uic->op != RIGHT_OP)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* if used in ^ operation then make sure right is not a
literl */
if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
IC_LEFT (uic)->key != IC_RESULT (ic)->key)
return;
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* if one of them is a literal then we can */
- if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
- (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
+ if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
+ (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
+ (getSize (operandType (IC_RESULT (uic))) <= 1))
{
OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
return;
}
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
/* if the other one is not on stack then we can */
if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
(IS_ITEMP (IC_RIGHT (uic)) ||
return;
accuse:
+ debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
IC_LEFT (ic) = IC_RIGHT (dic);
remiCodeFromeBBlock (ebp, dic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
}
+void printSymType(char * str, sym_link *sl)
+{
+ debugLog (" %s Symbol type: ",str);
+ printTypeChain( sl, debugF);
+ debugLog ("\n");
+
+}
+
+/*-----------------------------------------------------------------*/
+/* some debug code to print the symbol S_TYPE. Note that
+ * the function checkSClass in src/SDCCsymt.c dinks with
+ * the S_TYPE in ways the PIC port doesn't fully like...*/
+/*-----------------------------------------------------------------*/
+void isData(sym_link *sl)
+{
+ FILE *of = stderr;
+
+ if(!sl)
+ return;
+
+ if(debugF)
+ of = debugF;
+
+ for ( ; sl; sl=sl->next) {
+ if(!IS_DECL(sl) ) {
+ switch (SPEC_SCLS(sl)) {
+
+ case S_DATA: fprintf (of, "data "); break;
+ case S_XDATA: fprintf (of, "xdata "); break;
+ case S_SFR: fprintf (of, "sfr "); break;
+ case S_SBIT: fprintf (of, "sbit "); break;
+ case S_CODE: fprintf (of, "code "); break;
+ case S_IDATA: fprintf (of, "idata "); break;
+ case S_PDATA: fprintf (of, "pdata "); break;
+ case S_LITERAL: fprintf (of, "literal "); break;
+ case S_STACK: fprintf (of, "stack "); break;
+ case S_XSTACK: fprintf (of, "xstack "); break;
+ case S_BIT: fprintf (of, "bit "); break;
+ case S_EEPROM: fprintf (of, "eeprom "); break;
+ default: break;
+ }
+
+ }
+
+ }
+
+}
/*-----------------------------------------------------------------*/
/* packRegisters - does some transformations to reduce register */
/* pressure */
debugLog ("%s\n", __FUNCTION__);
- while (1)
- {
+ while (1) {
- change = 0;
+ change = 0;
- /* look for assignments of the form */
- /* iTempNN = TRueSym (someoperation) SomeOperand */
- /* .... */
- /* TrueSym := iTempNN:1 */
- for (ic = ebp->sch; ic; ic = ic->next)
- {
+ /* look for assignments of the form */
+ /* iTempNN = TRueSym (someoperation) SomeOperand */
+ /* .... */
+ /* TrueSym := iTempNN:1 */
+ for (ic = ebp->sch; ic; ic = ic->next)
+ {
- /* find assignment of the form TrueSym := iTempNN:1 */
- if (ic->op == '=' && !POINTER_SET (ic))
- change += packRegsForAssign (ic, ebp);
- /* debug stuff */
- if (ic->op == '=')
- {
- if (POINTER_SET (ic))
- debugLog ("pointer is set\n");
- debugAopGet (" result:", IC_RESULT (ic));
- debugAopGet (" left:", IC_LEFT (ic));
- debugAopGet (" right:", IC_RIGHT (ic));
- }
+ /* find assignment of the form TrueSym := iTempNN:1 */
+ if (ic->op == '=' && !POINTER_SET (ic))
+ change += packRegsForAssign (ic, ebp);
+ /* debug stuff */
+ if (ic->op == '=')
+ {
+ if (POINTER_SET (ic))
+ debugLog ("pointer is set\n");
+ debugAopGet (" result:", IC_RESULT (ic));
+ debugAopGet (" left:", IC_LEFT (ic));
+ debugAopGet (" right:", IC_RIGHT (ic));
+ }
- }
+ }
+
+ if (!change)
+ break;
+ }
+
+ for (ic = ebp->sch; ic; ic = ic->next) {
+
+ if(IS_SYMOP ( IC_LEFT(ic))) {
+ sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
+
+ debugAopGet (" left:", IC_LEFT (ic));
+ if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
+ debugLog (" is a pointer\n");
- if (!change)
- break;
+ if(IS_OP_VOLATILE(IC_LEFT(ic)))
+ debugLog (" is volatile\n");
+
+ isData(etype);
+
+ printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
}
- for (ic = ebp->sch; ic; ic = ic->next)
- {
+ if(IS_SYMOP ( IC_RIGHT(ic))) {
+ debugAopGet (" right:", IC_RIGHT (ic));
+ printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
+ }
- /* if this is an itemp & result of a address of a true sym
- then mark this as rematerialisable */
- if (ic->op == ADDRESS_OF &&
- IS_ITEMP (IC_RESULT (ic)) &&
- IS_TRUE_SYMOP (IC_LEFT (ic)) &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- !OP_SYMBOL (IC_LEFT (ic))->onStack)
- {
+ if(IS_SYMOP ( IC_RESULT(ic))) {
+ debugAopGet (" result:", IC_RESULT (ic));
+ printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
+ }
- debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
+ if (POINTER_SET (ic))
+ debugLog (" %d - Pointer set\n", __LINE__);
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
- }
+ /* if this is an itemp & result of a address of a true sym
+ then mark this as rematerialisable */
+ if (ic->op == ADDRESS_OF &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ !OP_SYMBOL (IC_LEFT (ic))->onStack)
+ {
- /* if straight assignment then carry remat flag if
- this is the only definition */
- if (ic->op == '=' &&
- !POINTER_SET (ic) &&
- IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->remat &&
- bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
- {
- debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
+ debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
- OP_SYMBOL (IC_RESULT (ic))->remat =
- OP_SYMBOL (IC_RIGHT (ic))->remat;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode =
- OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
- }
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
- /* if this is a +/- operation with a rematerizable
- then mark this as rematerializable as well */
- if ((ic->op == '+' || ic->op == '-') &&
- (IS_SYMOP (IC_LEFT (ic)) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- IS_OP_LITERAL (IC_RIGHT (ic))))
- {
- debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
- //int i =
- operandLitValue (IC_RIGHT (ic));
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
- }
+ }
- /* mark the pointer usages */
- if (POINTER_SET (ic))
- {
- OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
- debugLog (" marking as a pointer (set) =>");
- debugAopGet (" result:", IC_RESULT (ic));
- }
- if (POINTER_GET (ic))
- {
- OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
- debugLog (" marking as a pointer (get) =>");
- debugAopGet (" left:", IC_LEFT (ic));
- }
+ /* if straight assignment then carry remat flag if
+ this is the only definition */
+ if (ic->op == '=' &&
+ !POINTER_SET (ic) &&
+ IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->remat &&
+ bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+ {
+ debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
- if (!SKIP_IC2 (ic))
- {
- /* if we are using a symbol on the stack
- then we should say pic14_ptrRegReq */
- if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
- OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
- else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
- OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
- else
- {
- if (IS_SYMOP (IC_LEFT (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
- OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
- if (IS_SYMOP (IC_RIGHT (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
- OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
- if (IS_SYMOP (IC_RESULT (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
- OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
- }
- }
+ OP_SYMBOL (IC_RESULT (ic))->remat =
+ OP_SYMBOL (IC_RIGHT (ic))->remat;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+ OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ }
- /* if the condition of an if instruction
- is defined in the previous instruction then
- mark the itemp as a conditional */
- if ((IS_CONDITIONAL (ic) ||
- ((ic->op == BITWISEAND ||
- ic->op == '|' ||
- ic->op == '^') &&
- isBitwiseOptimizable (ic))) &&
- ic->next && ic->next->op == IFX &&
- isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
- OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
- {
+ /* if this is a +/- operation with a rematerizable
+ then mark this as rematerializable as well */
+ if ((ic->op == '+' || ic->op == '-') &&
+ (IS_SYMOP (IC_LEFT (ic)) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->remat &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ IS_OP_LITERAL (IC_RIGHT (ic))))
+ {
+ debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
+ //int i =
+ operandLitValue (IC_RIGHT (ic));
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ }
- OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
- continue;
- }
+ /* mark the pointer usages */
+ if (POINTER_SET (ic))
+ {
+ OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
+ debugLog (" marking as a pointer (set) =>");
+ debugAopGet (" result:", IC_RESULT (ic));
+ }
+ if (POINTER_GET (ic))
+ {
+ OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+ debugLog (" marking as a pointer (get) =>");
+ debugAopGet (" left:", IC_LEFT (ic));
+ }
- /* reduce for support function calls */
- if (ic->supportRtn || ic->op == '+' || ic->op == '-')
- packRegsForSupport (ic, ebp);
-
- /* if a parameter is passed, it's in W, so we may not
- need to place a copy in a register */
- if (ic->op == RECEIVE)
- packForReceive (ic, ebp);
-
- /* some cases the redundant moves can
- can be eliminated for return statements */
- if ((ic->op == RETURN || ic->op == SEND) &&
- !isOperandInFarSpace (IC_LEFT (ic)) &&
- !options.model)
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
- /* if pointer set & left has a size more than
- one and right is not in far space */
- if (POINTER_SET (ic) &&
- !isOperandInFarSpace (IC_RIGHT (ic)) &&
- !OP_SYMBOL (IC_RESULT (ic))->remat &&
- !IS_OP_RUONLY (IC_RIGHT (ic)) &&
- getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
-
- packRegsForOneuse (ic, IC_RESULT (ic), ebp);
-
- /* if pointer get */
- if (POINTER_GET (ic) &&
- !isOperandInFarSpace (IC_RESULT (ic)) &&
- !OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_OP_RUONLY (IC_RESULT (ic)) &&
- getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
-
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-
- /* if this is cast for intergral promotion then
- check if only use of the definition of the
- operand being casted/ if yes then replace
- the result of that arithmetic operation with
- this result and get rid of the cast */
- if (ic->op == CAST)
- {
- sym_link *fromType = operandType (IC_RIGHT (ic));
- sym_link *toType = operandType (IC_LEFT (ic));
+ if (!SKIP_IC2 (ic))
+ {
+ /* if we are using a symbol on the stack
+ then we should say pic14_ptrRegReq */
+ if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
+ OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+ else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
+ OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+ else
+ {
+ if (IS_SYMOP (IC_LEFT (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
+ OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP (IC_RIGHT (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
+ OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP (IC_RESULT (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
+ OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+ }
- if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
- getSize (fromType) != getSize (toType))
- {
+ debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
- iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
- if (dic)
- {
- if (IS_ARITHMETIC_OP (dic))
- {
- IC_RESULT (dic) = IC_RESULT (ic);
- remiCodeFromeBBlock (ebp, ic);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- ic = ic->prev;
- }
- else
- OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
- }
- }
- else
- {
+ }
- /* if the type from and type to are the same
- then if this is the only use then packit */
- if (compareType (operandType (IC_RIGHT (ic)),
- operandType (IC_LEFT (ic))) == 1)
- {
- iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
- if (dic)
- {
- IC_RESULT (dic) = IC_RESULT (ic);
- remiCodeFromeBBlock (ebp, ic);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- ic = ic->prev;
- }
- }
- }
- }
+ /* if the condition of an if instruction
+ is defined in the previous instruction then
+ mark the itemp as a conditional */
+ if ((IS_CONDITIONAL (ic) ||
+ ((ic->op == BITWISEAND ||
+ ic->op == '|' ||
+ ic->op == '^') &&
+ isBitwiseOptimizable (ic))) &&
+ ic->next && ic->next->op == IFX &&
+ isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+ OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+ {
- /* pack for PUSH
- iTempNN := (some variable in farspace) V1
- push iTempNN ;
- -------------
- push V1
- */
- if (ic->op == IPUSH)
- {
- packForPush (ic, ebp);
+ debugLog (" %d\n", __LINE__);
+ OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+ continue;
+ }
+
+ /* reduce for support function calls */
+ if (ic->supportRtn || ic->op == '+' || ic->op == '-')
+ packRegsForSupport (ic, ebp);
+
+ /* if a parameter is passed, it's in W, so we may not
+ need to place a copy in a register */
+ if (ic->op == RECEIVE)
+ packForReceive (ic, ebp);
+
+ /* some cases the redundant moves can
+ can be eliminated for return statements */
+ if ((ic->op == RETURN || ic->op == SEND) &&
+ !isOperandInFarSpace (IC_LEFT (ic)) &&
+ !options.model)
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+ /* if pointer set & left has a size more than
+ one and right is not in far space */
+ if (POINTER_SET (ic) &&
+ !isOperandInFarSpace (IC_RIGHT (ic)) &&
+ !OP_SYMBOL (IC_RESULT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+
+ packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+
+ /* if pointer get */
+ if (POINTER_GET (ic) &&
+ !isOperandInFarSpace (IC_RESULT (ic)) &&
+ !OP_SYMBOL (IC_LEFT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RESULT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+
+ /* if this is cast for intergral promotion then
+ check if only use of the definition of the
+ operand being casted/ if yes then replace
+ the result of that arithmetic operation with
+ this result and get rid of the cast */
+ if (ic->op == CAST) {
+
+ sym_link *fromType = operandType (IC_RIGHT (ic));
+ sym_link *toType = operandType (IC_LEFT (ic));
+
+ debugLog (" %d - casting\n", __LINE__);
+
+ if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
+ getSize (fromType) != getSize (toType)) {
+
+
+ iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+ if (dic) {
+
+ if (IS_ARITHMETIC_OP (dic)) {
+
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+ remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ ic = ic->prev;
+ } else
+
+ OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+ }
+ } else {
+
+ /* if the type from and type to are the same
+ then if this is the only use then packit */
+ if (compareType (operandType (IC_RIGHT (ic)),
+ operandType (IC_LEFT (ic))) == 1) {
+
+ iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+ if (dic) {
+
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ remiCodeFromeBBlock (ebp, ic);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ ic = ic->prev;
+ }
}
+ }
+ }
+ /* pack for PUSH
+ iTempNN := (some variable in farspace) V1
+ push iTempNN ;
+ -------------
+ push V1
+ */
+ if (ic->op == IPUSH)
+ {
+ packForPush (ic, ebp);
+ }
- /* pack registers for accumulator use, when the
- result of an arithmetic or bit wise operation
- has only one use, that use is immediately following
- the defintion and the using iCode has only one
- operand or has two operands but one is literal &
- the result of that operation is not on stack then
- we can leave the result of this operation in acc:b
- combination */
- if ((IS_ARITHMETIC_OP (ic)
- || IS_BITWISE_OP (ic)
+ /* pack registers for accumulator use, when the
+ result of an arithmetic or bit wise operation
+ has only one use, that use is immediately following
+ the defintion and the using iCode has only one
+ operand or has two operands but one is literal &
+ the result of that operation is not on stack then
+ we can leave the result of this operation in acc:b
+ combination */
+ if ((IS_ARITHMETIC_OP (ic)
- || ic->op == LEFT_OP || ic->op == RIGHT_OP
+ || IS_BITWISE_OP (ic)
- ) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- getSize (operandType (IC_RESULT (ic))) <= 2)
+ || ic->op == LEFT_OP || ic->op == RIGHT_OP
- packRegsForAccUse (ic);
+ ) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ getSize (operandType (IC_RESULT (ic))) <= 2)
- }
+ packRegsForAccUse (ic);
+
+ }
}
static void
int i;
debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
- debugLog ("ebbs before optimizing:\n");
+ debugLog ("\nebbs before optimizing:\n");
dumpEbbsToDebug (ebbs, count);
setToNull ((void *) &_G.funcrUsed);
for (i = 0; i < count; i++)
packRegisters (ebbs[i]);
+ {
+ regs *reg;
+ int hkey;
+ int i=0;
+
+ debugLog("dir registers allocated so far:\n");
+ reg = hTabFirstItem(dynDirectRegNames, &hkey);
+
+ while(reg) {
+ debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
+ reg = hTabNextItem(dynDirectRegNames, &hkey);
+ }
+
+ }
+
if (options.dump_pack)
dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
setToNull ((void **) &_G.stackSpil);
setToNull ((void **) &_G.spiltSet);
/* mark all registers as free */
- pic14_freeAllRegs ();
+ //pic14_freeAllRegs ();
debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
debugLogClose ();