-
- 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;
+
+ 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 0
+ 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);
+
+ if (!IS_STATIC (OP_SYM_ETYPE(op))) {
+ reg->isPublic = 1;
+ }
+ if (IS_EXTERN (OP_SYM_ETYPE(op))) {
+ reg->isExtern = 1;
+ }
+
+
+ } 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);
+ }
+#endif
+
+ if(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);
+ }
+ } else {
+ allocNewDirReg (OP_SYM_ETYPE(op),name);
+ }
+
+ return reg;
- 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++;
- }
- }
-
+ 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);
+ sprintf (buffer, "0x%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);
+ addSet(&dynInternalRegs,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);
+ addSet(&dynInternalRegs,relocbitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+
+ }
+
+ breg->reg_alias = relocbitfield;
+ breg->address = rDirectIdx; /* byte_no; */
+ breg->rIdx = bit_no++;
+ }
+ }
+
- symbol *sloc = NULL;
- int useXstack, model, noOverlay;
-
- char slocBuffer[30];
- debugLog ("%s\n", __FUNCTION__);
-
- /* first go try and find a free one that is already
- existing on the stack */
- if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
- {
- /* found a free one : just update & return */
- sym->usl.spillLoc = sloc;
- sym->stackSpil = 1;
- sloc->isFree = 0;
- addSetHead (&sloc->usl.itmpStack, sym);
- return sym;
- }
-
- /* could not then have to create one , this is the hard part
- we need to allocate this on the stack : this is really a
- hack!! but cannot think of anything better at this time */
-
- if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
- {
- fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
- __FILE__, __LINE__);
- exit (1);
- }
-
- sloc = newiTemp (slocBuffer);
-
- /* set the type to the spilling symbol */
- sloc->type = copyLinkChain (sym->type);
- sloc->etype = getSpec (sloc->type);
- SPEC_SCLS (sloc->etype) = S_DATA;
- SPEC_EXTR (sloc->etype) = 0;
- SPEC_STAT (sloc->etype) = 0;
-
- /* we don't allow it to be allocated`
- onto the external stack since : so we
- temporarily turn it off ; we also
- turn off memory model to prevent
- the spil from going to the external storage
- and turn off overlaying
- */
-
- useXstack = options.useXstack;
- model = options.model;
- noOverlay = options.noOverlay;
- options.noOverlay = 1;
- options.model = options.useXstack = 0;
-
- allocLocal (sloc);
-
- options.useXstack = useXstack;
- options.model = model;
- options.noOverlay = noOverlay;
- sloc->isref = 1; /* to prevent compiler warning */
-
- /* if it is on the stack then update the stack */
- if (IN_STACK (sloc->etype))
- {
- currFunc->stack += getSize (sloc->type);
- _G.stackExtend += getSize (sloc->type);
- }
- else
- _G.dataExtend += getSize (sloc->type);
-
- /* add it to the _G.stackSpil set */
- addSetHead (&_G.stackSpil, sloc);
- sym->usl.spillLoc = sloc;
- sym->stackSpil = 1;
-
- /* add it to the set of itempStack set
- of the spill location */
- addSetHead (&sloc->usl.itmpStack, sym);
- return sym;
+ symbol *sloc = NULL;
+ int useXstack, model, noOverlay;
+
+ char slocBuffer[30];
+ debugLog ("%s\n", __FUNCTION__);
+
+ /* first go try and find a free one that is already
+ existing on the stack */
+ if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
+ {
+ /* found a free one : just update & return */
+ sym->usl.spillLoc = sloc;
+ sym->stackSpil = 1;
+ sloc->isFree = 0;
+ addSetHead (&sloc->usl.itmpStack, sym);
+ return sym;
+ }
+
+ /* could not then have to create one , this is the hard part
+ we need to allocate this on the stack : this is really a
+ hack!! but cannot think of anything better at this time */
+
+ if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
+ {
+ fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
+ __FILE__, __LINE__);
+ exit (1);
+ }
+
+ sloc = newiTemp (slocBuffer);
+
+ /* set the type to the spilling symbol */
+ sloc->type = copyLinkChain (sym->type);
+ sloc->etype = getSpec (sloc->type);
+ SPEC_SCLS (sloc->etype) = S_DATA;
+ SPEC_EXTR (sloc->etype) = 0;
+ SPEC_STAT (sloc->etype) = 0;
+
+ /* we don't allow it to be allocated`
+ onto the external stack since : so we
+ temporarily turn it off ; we also
+ turn off memory model to prevent
+ the spil from going to the external storage
+ and turn off overlaying
+ */
+
+ useXstack = options.useXstack;
+ model = options.model;
+ noOverlay = options.noOverlay;
+ options.noOverlay = 1;
+ options.model = options.useXstack = 0;
+
+ allocLocal (sloc);
+
+ options.useXstack = useXstack;
+ options.model = model;
+ options.noOverlay = noOverlay;
+ sloc->isref = 1; /* to prevent compiler warning */
+
+ /* if it is on the stack then update the stack */
+ if (IN_STACK (sloc->etype))
+ {
+ currFunc->stack += getSize (sloc->type);
+ _G.stackExtend += getSize (sloc->type);
+ }
+ else
+ _G.dataExtend += getSize (sloc->type);
+
+ /* add it to the _G.stackSpil set */
+ addSetHead (&_G.stackSpil, sloc);
+ sym->usl.spillLoc = sloc;
+ sym->stackSpil = 1;
+
+ /* add it to the set of itempStack set
+ of the spill location */
+ addSetHead (&sloc->usl.itmpStack, sym);
+ return sym;
- symbol *ssym;
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- /* get something we can spil */
- ssym = selectSpil (ic, ebp, forSym);
-
- /* mark it as spilt */
- ssym->isspilt = 1;
- _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
-
- /* mark it as not register assigned &
- take it away from the set */
- bitVectUnSetBit (_G.regAssigned, ssym->key);
-
- /* mark the registers as free */
- for (i = 0; i < ssym->nRegs; i++)
- if (ssym->regs[i])
- freeReg (ssym->regs[i]);
-
- /* if spilt on stack then free up r0 & r1
- if they could have been assigned to as gprs */
- if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
- {
- pic14_ptrRegReq++;
- spillLRWithPtrReg (ssym);
- }
-
- /* if this was a block level spil then insert push & pop
- at the start & end of block respectively */
- if (ssym->blockSpil)
- {
- iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
- /* add push to the start of the block */
- addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
- ebp->sch->next : ebp->sch));
- nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
- /* add pop to the end of the block */
- addiCodeToeBBlock (ebp, nic, NULL);
- }
-
- /* if spilt because not used in the remainder of the
- block then add a push before this instruction and
- a pop at the end of the block */
- if (ssym->remainSpil)
- {
-
- iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
- /* add push just before this instruction */
- addiCodeToeBBlock (ebp, nic, ic);
-
- nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
- /* add pop to the end of the block */
- addiCodeToeBBlock (ebp, nic, NULL);
- }
-
- if (ssym == forSym)
- return FALSE;
- else
- return TRUE;
+ symbol *ssym;
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* get something we can spil */
+ ssym = selectSpil (ic, ebp, forSym);
+
+ /* mark it as spilt */
+ ssym->isspilt = 1;
+ _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
+
+ /* mark it as not register assigned &
+ take it away from the set */
+ bitVectUnSetBit (_G.regAssigned, ssym->key);
+
+ /* mark the registers as free */
+ for (i = 0; i < ssym->nRegs; i++)
+ if (ssym->regs[i])
+ freeReg (ssym->regs[i]);
+
+ /* if spilt on stack then free up r0 & r1
+ if they could have been assigned to as gprs */
+ if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
+ {
+ pic14_ptrRegReq++;
+ spillLRWithPtrReg (ssym);
+ }
+
+ /* if this was a block level spil then insert push & pop
+ at the start & end of block respectively */
+ if (ssym->blockSpil)
+ {
+ iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
+ /* add push to the start of the block */
+ addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
+ ebp->sch->next : ebp->sch));
+ nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
+ /* add pop to the end of the block */
+ addiCodeToeBBlock (ebp, nic, NULL);
+ }
+
+ /* if spilt because not used in the remainder of the
+ block then add a push before this instruction and
+ a pop at the end of the block */
+ if (ssym->remainSpil)
+ {
+
+ iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
+ /* add push just before this instruction */
+ addiCodeToeBBlock (ebp, nic, ic);
+
+ nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
+ /* add pop to the end of the block */
+ addiCodeToeBBlock (ebp, nic, NULL);
+ }
+
+ if (ssym == forSym)
+ return FALSE;
+ else
+ return TRUE;
-
- debugLog (" %d - \n", __LINE__);
-
- /* if remat in data space */
- if (OP_SYMBOL (IC_LEFT (ic))->remat &&
- DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
-
- /* create a psuedo symbol & force a spil */
- //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);
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
- continue;
- }
-
- /* if in data space or idata space then try to
- allocate pointer register */
-
- }
-
- /* if not then we require registers */
- sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
- 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);
- fprintf (stderr, "\n");
- }
-
- /* determine the type of register required */
- if (sym->nRegs == 1 &&
- IS_PTR (sym->type) &&
- sym->uptr)
- sym->regType = REG_PTR;
- else
- sym->regType = REG_GPR;
-
-
- debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
-
- }
- else
- /* for the first run we don't provide */
- /* registers for true symbols we will */
- /* see how things go */
- sym->nRegs = 0;
+ debugLog ("%s\n", __FUNCTION__);
+ /* for each live range do */
+ for (sym = hTabFirstItem (liveRanges, &k); sym;
+ sym = hTabNextItem (liveRanges, &k)) {
+
+ debugLog (" %d - %s\n", __LINE__, sym->rname);
+
+ /* if used zero times then no registers needed */
+ if ((sym->liveTo - sym->liveFrom) == 0)
+ continue;
+
+
+ /* if the live range is a temporary */
+ if (sym->isitmp) {
+
+ debugLog (" %d - itemp register\n", __LINE__);
+
+ /* if the type is marked as a conditional */
+ if (sym->regType == REG_CND)
+ continue;
+
+ /* if used in return only then we don't
+ need registers */
+ if (sym->accuse) {
+ if (IS_AGGREGATE (sym->type) || sym->isptr)
+ sym->type = aggrToPtr (sym->type, FALSE);
+ debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
+
+ continue;
+ }
+
+ if (sym->ruonly) {
+ //if (IS_AGGREGATE (sym->type) || sym->isptr)
+ // sym->type = aggrToPtr (sym->type, FALSE);
+ debugLog (" %d - used as a return\n", __LINE__);
+
+ //continue;
+ }
+
+ /* if the symbol has only one definition &
+ that definition is a get_pointer and the
+ pointer we are getting is rematerializable and
+ in "data" space */
+
+ if (bitVectnBitsOn (sym->defs) == 1 &&
+ (ic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (sym->defs))) &&
+ POINTER_GET (ic) &&
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
+
+ if (ptrPseudoSymSafe (sym, ic)) {
+
+ symbol *psym;
+
+ debugLog (" %d - \n", __LINE__);
+
+ /* create a psuedo symbol & force a spil */
+ //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
+ psym->type = sym->type;
+ psym->etype = sym->etype;
+ psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
+ strcpy (psym->rname, psym->name);
+ sym->isspilt = 1;
+ sym->usl.spillLoc = psym;
+ continue;
+ }
+
+ /* if in data space or idata space then try to
+ allocate pointer register */
+
+ }
+
+ /* if not then we require registers */
+ sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
+ 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);
+ fprintf (stderr, "\n");
+ }
+
+ /* determine the type of register required */
+ if (sym->nRegs == 1 &&
+ IS_PTR (sym->type) &&
+ sym->uptr)
+ sym->regType = REG_PTR;
+ else
+ sym->regType = REG_GPR;
+
+
+ debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
+
+ }
+ else
+ /* for the first run we don't provide */
+ /* registers for true symbols we will */
+ /* see how things go */
+ sym->nRegs = 0;
-
- iCode *dic, *sic;
-
- debugLog ("%s\n", __FUNCTION__);
-
- debugAopGet (" result:", IC_RESULT (ic));
- debugAopGet (" left:", IC_LEFT (ic));
- debugAopGet (" right:", IC_RIGHT (ic));
-
- /* 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__);
-
- /* only pack if this is not a function pointer */
- if (!IS_REF (IC_RIGHT (ic)))
- 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__);
- return 0;
- }
-
- /* if the true symbol is defined in far space or on stack
- then we should not since this will increase register pressure */
- if (isOperandInFarSpace (IC_RESULT (ic)))
- {
- if ((dic = farSpacePackable (ic)))
- goto pack;
- else
- return 0;
-
- }
- /* find the definition of iTempNN scanning backwards if we find a
- a use of the true symbol before we find the definition then
- we cannot pack */
- for (dic = ic->prev; dic; dic = dic->prev)
- {
-
- /* if there is a function call and this is
- a parameter & not my parameter then don't pack it */
- if ((dic->op == CALL || dic->op == PCALL) &&
- (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
- !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
+
+ iCode *dic, *sic;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ debugAopGet (" result:", IC_RESULT (ic));
+ debugAopGet (" left:", IC_LEFT (ic));
+ debugAopGet (" right:", IC_RIGHT (ic));
+
+ /* 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__);
+
+ /* only pack if this is not a function pointer */
+ if (!IS_REF (IC_RIGHT (ic)))
+ allocDirReg(IC_RIGHT (ic));
+ return 0;
+ }
+
+ if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
+ OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
- 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)) ||
- getSize (operandType (IC_RESULT (ic))) > 1))
- return;
-
- if (ic->op == LEFT_OP &&
- (isOperandLiteral (IC_RIGHT (ic)) ||
- getSize (operandType (IC_RESULT (ic))) > 1))
- return;
-
- if (IS_BITWISE_OP (ic) &&
- getSize (operandType (IC_RESULT (ic))) > 1)
- return;
-
-
- /* has only one definition */
- if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
- return;
-
- /* has only one use */
- if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
- return;
-
- /* and the usage immediately follows this iCode */
- if (!(uic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
- return;
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- if (ic->next != uic)
- return;
-
- /* if it is a conditional branch then we definitely can */
- if (uic->op == IFX)
- goto accuse;
-
- if (uic->op == JUMPTABLE)
- return;
-
- /* if the usage is not is an assignment
- or an arithmetic / bitwise / shift operation then not */
- if (POINTER_SET (uic) &&
- 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 != LEFT_OP &&
- 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)))
- return;
-
- /* if shift operation make sure right side is not a literal */
- if (uic->op == RIGHT_OP &&
- (isOperandLiteral (IC_RIGHT (uic)) ||
- getSize (operandType (IC_RESULT (uic))) > 1))
- return;
-
- if (uic->op == LEFT_OP &&
- (isOperandLiteral (IC_RIGHT (uic)) ||
- getSize (operandType (IC_RESULT (uic))) > 1))
- return;
-
- /* make sure that the result of this icode is not on the
- stack, since acc is used to compute stack offset */
- if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
- OP_SYMBOL (IC_RESULT (uic))->onStack)
- return;
-
- /* if either one of them in far space then we cannot */
- if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
- isOperandInFarSpace (IC_LEFT (uic))) ||
- (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
- isOperandInFarSpace (IC_RIGHT (uic))))
- return;
-
- /* if the usage has only one operand then we can */
- if (IC_LEFT (uic) == NULL ||
- IC_RIGHT (uic) == NULL)
- goto accuse;
-
- /* make sure this is on the left side if not
- a '+' since '+' is commutative */
- if (ic->op != '+' &&
- 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)))) &&
- (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)) ||
- (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
- !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
- goto accuse;
-
- if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
- (IS_ITEMP (IC_LEFT (uic)) ||
- (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
- !OP_SYMBOL (IC_LEFT (uic))->onStack)))
- goto accuse;
-
- return;
-
+ 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)) ||
+ getSize (operandType (IC_RESULT (ic))) > 1))
+ return;
+
+ if (ic->op == LEFT_OP &&
+ (isOperandLiteral (IC_RIGHT (ic)) ||
+ getSize (operandType (IC_RESULT (ic))) > 1))
+ return;
+
+ if (IS_BITWISE_OP (ic) &&
+ getSize (operandType (IC_RESULT (ic))) > 1)
+ return;
+
+
+ /* has only one definition */
+ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
+ return;
+
+ /* has only one use */
+ if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
+ return;
+
+ /* and the usage immediately follows this iCode */
+ if (!(uic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+ return;
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ if (ic->next != uic)
+ return;
+
+ /* if it is a conditional branch then we definitely can */
+ if (uic->op == IFX)
+ goto accuse;
+
+ if (uic->op == JUMPTABLE)
+ return;
+
+ /* if the usage is not is an assignment
+ or an arithmetic / bitwise / shift operation then not */
+ if (POINTER_SET (uic) &&
+ 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 != LEFT_OP &&
+ 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)))
+ return;
+
+ /* if shift operation make sure right side is not a literal */
+ if (uic->op == RIGHT_OP &&
+ (isOperandLiteral (IC_RIGHT (uic)) ||
+ getSize (operandType (IC_RESULT (uic))) > 1))
+ return;
+
+ if (uic->op == LEFT_OP &&
+ (isOperandLiteral (IC_RIGHT (uic)) ||
+ getSize (operandType (IC_RESULT (uic))) > 1))
+ return;
+
+ /* make sure that the result of this icode is not on the
+ stack, since acc is used to compute stack offset */
+ if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
+ OP_SYMBOL (IC_RESULT (uic))->onStack)
+ return;
+
+ /* if either one of them in far space then we cannot */
+ if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
+ isOperandInFarSpace (IC_LEFT (uic))) ||
+ (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
+ isOperandInFarSpace (IC_RIGHT (uic))))
+ return;
+
+ /* if the usage has only one operand then we can */
+ if (IC_LEFT (uic) == NULL ||
+ IC_RIGHT (uic) == NULL)
+ goto accuse;
+
+ /* make sure this is on the left side if not
+ a '+' since '+' is commutative */
+ if (ic->op != '+' &&
+ 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)))) &&
+ (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)) ||
+ (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
+ !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
+ goto accuse;
+
+ if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
+ (IS_ITEMP (IC_LEFT (uic)) ||
+ (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
+ !OP_SYMBOL (IC_LEFT (uic))->onStack)))
+ goto accuse;
+
+ return;
+
- iCode *ic;
- int change = 0;
-
- debugLog ("%s\n", __FUNCTION__);
-
- while (1) {
-
- change = 0;
-
- /* 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));
- }
-
- }
-
- 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(IS_OP_VOLATILE(IC_LEFT(ic)))
- debugLog (" is volatile\n");
-
- isData(etype);
-
- printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
- }
-
- if(IS_SYMOP ( IC_RIGHT(ic))) {
- debugAopGet (" right:", IC_RIGHT (ic));
- printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
- }
-
- if(IS_SYMOP ( IC_RESULT(ic))) {
- debugAopGet (" result:", IC_RESULT (ic));
- printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
- }
-
- if (POINTER_SET (ic))
- debugLog (" %d - Pointer set\n", __LINE__);
-
-
- /* 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)
- {
-
- debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
-
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-
- }
-
- /* 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__);
-
- 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 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 (!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);
- }
-
- debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
-
- }
-
- /* 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)
- {
-
- 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)
-
- || ic->op == LEFT_OP || ic->op == RIGHT_OP
-
- ) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- getSize (operandType (IC_RESULT (ic))) <= 2)
-
- packRegsForAccUse (ic);
-
+ iCode *ic;
+ int change = 0;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ while (1) {
+
+ change = 0;
+
+ /* 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));
+ }
+
+ }
+
+ 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(IS_OP_VOLATILE(IC_LEFT(ic)))
+ debugLog (" is volatile\n");
+
+ isData(etype);
+
+ printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
+ }
+
+ if(IS_SYMOP ( IC_RIGHT(ic))) {
+ debugAopGet (" right:", IC_RIGHT (ic));
+ printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
+ }
+
+ if(IS_SYMOP ( IC_RESULT(ic))) {
+ debugAopGet (" result:", IC_RESULT (ic));
+ printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
+ }
+
+ if (POINTER_SET (ic))
+ debugLog (" %d - Pointer set\n", __LINE__);
+
+
+ /* 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)
+ {
+
+ debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
+
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+
+ }
+
+ /* 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__);
+
+ 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 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 (!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);
+ }
+
+ debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
+
+ }
+
+ /* 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)
+ {
+
+ 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)
+
+ || ic->op == LEFT_OP || ic->op == RIGHT_OP
+
+ ) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ getSize (operandType (IC_RESULT (ic))) <= 2)
+
+ packRegsForAccUse (ic);
+
- iCode *ic;
- int i;
-
- debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
- debugLog ("\nebbs before optimizing:\n");
- dumpEbbsToDebug (ebbs, count);
-
- setToNull ((void *) &_G.funcrUsed);
- pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-
-
- /* change assignments this will remove some
- live ranges reducing some register pressure */
- 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);
-
- /* first determine for each live range the number of
- registers & the type of registers required for each */
- regTypeNum ();
-
- /* and serially allocate registers */
- serialRegAssign (ebbs, count);
-
- /* if stack was extended then tell the user */
- if (_G.stackExtend)
- {
-/* werror(W_TOOMANY_SPILS,"stack", */
-/* _G.stackExtend,currFunc->name,""); */
- _G.stackExtend = 0;
- }
-
- if (_G.dataExtend)
- {
-/* werror(W_TOOMANY_SPILS,"data space", */
-/* _G.dataExtend,currFunc->name,""); */
- _G.dataExtend = 0;
- }
-
- /* after that create the register mask
- for each of the instruction */
- createRegMask (ebbs, count);
-
- /* redo that offsets for stacked automatic variables */
- redoStackOffsets ();
-
- if (options.dump_rassgn)
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
-
- /* now get back the chain */
- ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
-
- debugLog ("ebbs after optimizing:\n");
- dumpEbbsToDebug (ebbs, count);
-
-
- genpic14Code (ic);
-
- /* free up any _G.stackSpil locations allocated */
- applyToSet (_G.stackSpil, deallocStackSpil);
- _G.slocNum = 0;
- setToNull ((void **) &_G.stackSpil);
- setToNull ((void **) &_G.spiltSet);
- /* mark all registers as free */
- //pic14_freeAllRegs ();
-
- debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
- debugLogClose ();
- return;
+ iCode *ic;
+ int i;
+
+ debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
+ debugLog ("\nebbs before optimizing:\n");
+ dumpEbbsToDebug (ebbs, count);
+
+ setToNull ((void *) &_G.funcrUsed);
+ pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
+
+
+ /* change assignments this will remove some
+ live ranges reducing some register pressure */
+ 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);
+
+ /* first determine for each live range the number of
+ registers & the type of registers required for each */
+ regTypeNum ();
+
+ /* and serially allocate registers */
+ serialRegAssign (ebbs, count);
+
+ /* if stack was extended then tell the user */
+ if (_G.stackExtend)
+ {
+ /* werror(W_TOOMANY_SPILS,"stack", */
+ /* _G.stackExtend,currFunc->name,""); */
+ _G.stackExtend = 0;
+ }
+
+ if (_G.dataExtend)
+ {
+ /* werror(W_TOOMANY_SPILS,"data space", */
+ /* _G.dataExtend,currFunc->name,""); */
+ _G.dataExtend = 0;
+ }
+
+ /* after that create the register mask
+ for each of the instruction */
+ createRegMask (ebbs, count);
+
+ /* redo that offsets for stacked automatic variables */
+ redoStackOffsets ();
+
+ if (options.dump_rassgn)
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+
+ /* now get back the chain */
+ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
+
+ debugLog ("ebbs after optimizing:\n");
+ dumpEbbsToDebug (ebbs, count);
+
+
+ genpic14Code (ic);
+
+ /* free up any _G.stackSpil locations allocated */
+ applyToSet (_G.stackSpil, deallocStackSpil);
+ _G.slocNum = 0;
+ setToNull ((void *) &_G.stackSpil);
+ setToNull ((void *) &_G.spiltSet);
+ /* mark all registers as free */
+ //pic14_freeAllRegs ();
+
+ debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
+ debugLogClose ();
+ return;