1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
40 /*-----------------------------------------------------------------*/
41 /* At this point we start getting processor specific although */
42 /* some routines are non-processor specific & can be reused when */
43 /* targetting other processors. The decision for this will have */
44 /* to be made on a routine by routine basis */
45 /* routines used to pack registers are most definitely not reusable */
46 /* since the pack the registers depending strictly on the MCU */
47 /*-----------------------------------------------------------------*/
49 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
50 extern void genpic16Code (iCode *);
60 bitVect *funcrUsed; /* registers used in a function */
66 /* Shared with gen.c */
67 int pic16_ptrRegReq; /* one byte pointer register required */
70 set *pic16_dynAllocRegs=NULL;
71 set *pic16_dynStackRegs=NULL;
72 set *pic16_dynProcessorRegs=NULL;
73 set *pic16_dynDirectRegs=NULL;
74 set *pic16_dynDirectBitRegs=NULL;
75 set *pic16_dynInternalRegs=NULL;
77 static hTab *dynDirectRegNames= NULL;
78 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
80 extern set *sectNames;
82 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
83 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
84 set *pic16_equ_data=NULL; /* registers used by equates */
85 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
87 set *pic16_builtin_functions=NULL;
89 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
90 static int rDirectIdx=0;
92 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
94 int pic16_Gstack_base_addr=0; /* The starting address of registers that
95 * are used to pass and return parameters */
100 static void spillThis (symbol *);
101 int pic16_ralloc_debug = 0;
102 static FILE *debugF = NULL;
103 /*-----------------------------------------------------------------*/
104 /* debugLog - open a file for debugging information */
105 /*-----------------------------------------------------------------*/
106 //static void debugLog(char *inst,char *fmt, ...)
108 debugLog (char *fmt,...)
110 static int append = 0; // First time through, open the file without append.
113 //char *bufferP=buffer;
116 if (!pic16_ralloc_debug || !dstFileName)
122 /* create the file name */
123 strcpy (buffer, dstFileName);
124 strcat (buffer, ".d");
126 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
128 werror (E_FILE_OPEN_ERR, buffer);
131 append = 1; // Next time debubLog is called, we'll append the debug info
137 vsprintf (buffer, fmt, ap);
139 fprintf (debugF, "%s", buffer);
141 while (isspace(*bufferP)) bufferP++;
143 if (bufferP && *bufferP)
144 lineCurr = (lineCurr ?
145 connectLine(lineCurr,newLineNode(lb)) :
146 (lineHead = newLineNode(lb)));
147 lineCurr->isInline = _G.inLine;
148 lineCurr->isDebug = _G.debugLine;
157 if(!pic16_ralloc_debug)return;
160 fputc ('\n', debugF);
162 /*-----------------------------------------------------------------*/
163 /* debugLogClose - closes the debug log file (if opened) */
164 /*-----------------------------------------------------------------*/
174 #define AOP(op) op->aop
177 debugAopGet (char *str, operand * op)
179 if(!pic16_ralloc_debug)return NULL;
184 printOperand (op, debugF);
191 decodeOp (unsigned int op)
193 if (op < 128 && op > ' ') {
194 buffer[0] = (op & 0xff);
200 case IDENTIFIER: return "IDENTIFIER";
201 case TYPE_NAME: return "TYPE_NAME";
202 case CONSTANT: return "CONSTANT";
203 case STRING_LITERAL: return "STRING_LITERAL";
204 case SIZEOF: return "SIZEOF";
205 case PTR_OP: return "PTR_OP";
206 case INC_OP: return "INC_OP";
207 case DEC_OP: return "DEC_OP";
208 case LEFT_OP: return "LEFT_OP";
209 case RIGHT_OP: return "RIGHT_OP";
210 case LE_OP: return "LE_OP";
211 case GE_OP: return "GE_OP";
212 case EQ_OP: return "EQ_OP";
213 case NE_OP: return "NE_OP";
214 case AND_OP: return "AND_OP";
215 case OR_OP: return "OR_OP";
216 case MUL_ASSIGN: return "MUL_ASSIGN";
217 case DIV_ASSIGN: return "DIV_ASSIGN";
218 case MOD_ASSIGN: return "MOD_ASSIGN";
219 case ADD_ASSIGN: return "ADD_ASSIGN";
220 case SUB_ASSIGN: return "SUB_ASSIGN";
221 case LEFT_ASSIGN: return "LEFT_ASSIGN";
222 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
223 case AND_ASSIGN: return "AND_ASSIGN";
224 case XOR_ASSIGN: return "XOR_ASSIGN";
225 case OR_ASSIGN: return "OR_ASSIGN";
226 case TYPEDEF: return "TYPEDEF";
227 case EXTERN: return "EXTERN";
228 case STATIC: return "STATIC";
229 case AUTO: return "AUTO";
230 case REGISTER: return "REGISTER";
231 case CODE: return "CODE";
232 case EEPROM: return "EEPROM";
233 case INTERRUPT: return "INTERRUPT";
234 case SFR: return "SFR";
235 case AT: return "AT";
236 case SBIT: return "SBIT";
237 case REENTRANT: return "REENTRANT";
238 case USING: return "USING";
239 case XDATA: return "XDATA";
240 case DATA: return "DATA";
241 case IDATA: return "IDATA";
242 case PDATA: return "PDATA";
243 case VAR_ARGS: return "VAR_ARGS";
244 case CRITICAL: return "CRITICAL";
245 case NONBANKED: return "NONBANKED";
246 case BANKED: return "BANKED";
247 case CHAR: return "CHAR";
248 case SHORT: return "SHORT";
249 case INT: return "INT";
250 case LONG: return "LONG";
251 case SIGNED: return "SIGNED";
252 case UNSIGNED: return "UNSIGNED";
253 case FLOAT: return "FLOAT";
254 case DOUBLE: return "DOUBLE";
255 case CONST: return "CONST";
256 case VOLATILE: return "VOLATILE";
257 case VOID: return "VOID";
258 case BIT: return "BIT";
259 case STRUCT: return "STRUCT";
260 case UNION: return "UNION";
261 case ENUM: return "ENUM";
262 case ELIPSIS: return "ELIPSIS";
263 case RANGE: return "RANGE";
264 case FAR: return "FAR";
265 case CASE: return "CASE";
266 case DEFAULT: return "DEFAULT";
267 case IF: return "IF";
268 case ELSE: return "ELSE";
269 case SWITCH: return "SWITCH";
270 case WHILE: return "WHILE";
271 case DO: return "DO";
272 case FOR: return "FOR";
273 case GOTO: return "GOTO";
274 case CONTINUE: return "CONTINUE";
275 case BREAK: return "BREAK";
276 case RETURN: return "RETURN";
277 case INLINEASM: return "INLINEASM";
278 case IFX: return "IFX";
279 case ADDRESS_OF: return "ADDRESS_OF";
280 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
281 case SPIL: return "SPIL";
282 case UNSPIL: return "UNSPIL";
283 case GETHBIT: return "GETHBIT";
284 case BITWISEAND: return "BITWISEAND";
285 case UNARYMINUS: return "UNARYMINUS";
286 case IPUSH: return "IPUSH";
287 case IPOP: return "IPOP";
288 case PCALL: return "PCALL";
289 case ENDFUNCTION: return "ENDFUNCTION";
290 case JUMPTABLE: return "JUMPTABLE";
291 case RRC: return "RRC";
292 case RLC: return "RLC";
293 case CAST: return "CAST";
294 case CALL: return "CALL";
295 case PARAM: return "PARAM ";
296 case NULLOP: return "NULLOP";
297 case BLOCK: return "BLOCK";
298 case LABEL: return "LABEL";
299 case RECEIVE: return "RECEIVE";
300 case SEND: return "SEND";
302 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
306 /*-----------------------------------------------------------------*/
307 /*-----------------------------------------------------------------*/
309 debugLogRegType (short type)
311 if(!pic16_ralloc_debug)return NULL;
313 case REG_GPR: return "REG_GPR";
314 case REG_PTR: return "REG_PTR";
315 case REG_CND: return "REG_CND";
317 sprintf (buffer, "unknown reg type %d", type);
322 /*-----------------------------------------------------------------*/
323 /*-----------------------------------------------------------------*/
324 static int regname2key(char const *name)
333 key += (*name++) + 1;
337 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
341 /*-----------------------------------------------------------------*/
342 /* newReg - allocate and init memory for a new register */
343 /*-----------------------------------------------------------------*/
344 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
349 dReg = Safe_calloc(1,sizeof(regs));
351 dReg->pc_type = pc_type;
354 dReg->name = Safe_strdup(name);
356 sprintf(buffer,"r0x%02X", dReg->rIdx);
359 dReg->name = Safe_strdup(buffer);
367 if(type == REG_SFR) {
369 dReg->address = rIdx;
370 dReg->accessBank = 1;
374 dReg->accessBank = 0;
377 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
381 dReg->reg_alias = NULL;
382 dReg->reglives.usedpFlows = newSet();
383 dReg->reglives.assignedpFlows = newSet();
386 if(!(type == REG_SFR && alias == 0x80))
387 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
392 /*-----------------------------------------------------------------*/
393 /* regWithIdx - Search through a set of registers that matches idx */
394 /*-----------------------------------------------------------------*/
396 regWithIdx (set *dRegs, int idx, int fixed)
400 for (dReg = setFirstItem(dRegs) ; dReg ;
401 dReg = setNextItem(dRegs)) {
403 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
411 /*-----------------------------------------------------------------*/
412 /* regFindFree - Search for a free register in a set of registers */
413 /*-----------------------------------------------------------------*/
415 regFindFree (set *dRegs)
419 for (dReg = setFirstItem(dRegs) ; dReg ;
420 dReg = setNextItem(dRegs)) {
422 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
423 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
432 /*-----------------------------------------------------------------*/
433 /* pic16_initStack - allocate registers for a pseudo stack */
434 /*-----------------------------------------------------------------*/
435 void pic16_initStack(int base_address, int size)
440 pic16_Gstack_base_addr = base_address;
441 //fprintf(stderr,"initStack");
443 for(i = 0; i<size; i++)
444 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
447 /*-----------------------------------------------------------------*
448 *-----------------------------------------------------------------*/
450 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
452 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
454 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
456 reg->wasUsed = 0; // we do not know if they are going to be used at all
457 reg->accessBank = 1; // implicit add access Bank
459 return addSet(&pic16_dynProcessorRegs, reg);
462 /*-----------------------------------------------------------------*
463 *-----------------------------------------------------------------*/
466 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
468 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
470 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
474 return addSet(&pic16_dynInternalRegs,reg);
479 /*-----------------------------------------------------------------*/
480 /* allocReg - allocates register of given type */
481 /*-----------------------------------------------------------------*/
483 allocReg (short type)
488 if(dynrIdx > pic16_nRegs)
492 /* try to reuse some unused registers */
493 reg = regFindFree( pic16_dynAllocRegs );
496 // fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
500 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
501 // addSet(&pic16_dynAllocRegs, reg);
504 addSet(&pic16_dynAllocRegs, reg);
508 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
510 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
511 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
514 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
515 reg->isLocal = 1; /* this is a local frame register */
519 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
520 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
523 return (reg); // addSet(&pic16_dynAllocRegs,reg);
528 /*-----------------------------------------------------------------*/
529 /* pic16_dirregWithName - search for register by name */
530 /*-----------------------------------------------------------------*/
532 pic16_dirregWithName (char *name)
540 /* hash the name to get a key */
542 hkey = regname2key(name);
544 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
546 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
550 if(STRCASECMP(reg->name, name) == 0) {
554 reg = hTabNextItemWK (dynDirectRegNames);
558 return NULL; // name wasn't found in the hash table
562 /*-----------------------------------------------------------------*/
563 /* pic16_allocDirReg - allocates register of given type */
564 /*-----------------------------------------------------------------*/
566 pic16_allocDirReg (operand *op )
572 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
573 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
577 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
579 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
580 if(pic16_debug_verbose)
582 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
583 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
588 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
589 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
592 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
593 debugLog(" %d const char\n",__LINE__);
594 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
595 // fprintf(stderr, " %d const char\n",__LINE__);
596 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
600 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
601 if (IS_CODE ( OP_SYM_ETYPE(op)) )
602 debugLog(" %d code space\n",__LINE__);
604 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
605 debugLog(" %d integral\n",__LINE__);
607 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
608 debugLog(" %d literal\n",__LINE__);
610 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
611 debugLog(" %d specifier\n",__LINE__);
613 debugAopGet(NULL, op);
616 if (IS_CODE ( OP_SYM_ETYPE(op)) )
619 /* First, search the hash table to see if there is a register with this name */
620 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
622 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
626 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
627 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
629 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
630 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
633 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
635 reg = pic16_dirregWithName(name);
640 int regtype = REG_GPR;
642 /* if this is at an absolute address, then get the address. */
643 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
644 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
645 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
648 /* Register wasn't found in hash, so let's create
649 * a new one and put it in the hash table AND in the
650 * dynDirectRegNames set */
651 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
653 // if(pic16_debug_verbose)
654 // fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
655 // OP_SYMBOL(op)->name);
657 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
661 if(1) { //!PIC16_IS_CONFIG_ADDRESS(address))
662 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
664 /* this is an error, why added? -- VR */
665 // if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
667 if(OP_SYMBOL(op)->onStack) {
668 fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
669 // OP_SYMBOL(op)->onStack = 0;
670 SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
674 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13
675 if(pic16_debug_verbose) //
677 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
678 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
679 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
680 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
681 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
682 IN_STACK( OP_SYM_ETYPE(op)),
683 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
685 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
686 OP_SYMBOL(op)->name); //
690 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
691 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
694 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
695 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
696 // reg->type = REG_SFR;
699 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
700 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
701 addSet(&pic16_dynDirectBitRegs, reg);
704 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
705 // addSet(&pic16_dynDirectRegs, reg);
706 checkAddReg(&pic16_dynDirectRegs, reg);
710 debugLog (" -- %s is declared at address 0x30000x\n",name);
716 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
718 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
720 /* work around for user defined registers in access bank */
721 if((reg->address>= 0x00 && reg->address < 0x80)
722 || (reg->address >= 0xf80 && reg->address <= 0xfff))
725 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
731 /*-----------------------------------------------------------------*/
732 /* pic16_allocRegByName - allocates register of given type */
733 /*-----------------------------------------------------------------*/
735 pic16_allocRegByName (char *name, int size, operand *op)
741 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
745 /* First, search the hash table to see if there is a register with this name */
746 reg = pic16_dirregWithName(name);
750 /* Register wasn't found in hash, so let's create
751 * a new one and put it in the hash table AND in the
752 * dynDirectRegNames set */
754 // fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
756 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
758 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
759 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
761 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
762 addSet(&pic16_dynDirectRegs, reg);
768 /*-----------------------------------------------------------------*/
769 /* RegWithIdx - returns pointer to register with index number */
770 /*-----------------------------------------------------------------*/
771 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
776 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
777 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
782 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
784 debugLog ("Found a Dynamic Register!\n");
787 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
788 debugLog ("Found a Direct Register!\n");
794 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
795 debugLog ("Found a Stack Register!\n");
800 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
801 debugLog ("Found a Processor Register!\n");
815 /*-----------------------------------------------------------------*/
816 /* pic16_regWithIdx - returns pointer to register with index number*/
817 /*-----------------------------------------------------------------*/
819 pic16_regWithIdx (int idx)
823 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
826 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
829 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
835 /*-----------------------------------------------------------------*/
836 /* pic16_regWithIdx - returns pointer to register with index number */
837 /*-----------------------------------------------------------------*/
839 pic16_allocWithIdx (int idx)
844 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
845 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
847 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
849 debugLog ("Found a Dynamic Register!\n");
850 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
851 debugLog ("Found a Stack Register!\n");
852 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
853 debugLog ("Found a Processor Register!\n");
854 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
855 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
856 debugLog ("Found an Internal Register!\n");
859 debugLog ("Dynamic Register not found\n");
862 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
863 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
864 "regWithIdx not found");
874 /*-----------------------------------------------------------------*/
875 /*-----------------------------------------------------------------*/
877 pic16_findFreeReg(short type)
884 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
886 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
890 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
902 /*-----------------------------------------------------------------*/
903 /* freeReg - frees a register */
904 /*-----------------------------------------------------------------*/
908 debugLog ("%s\n", __FUNCTION__);
909 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
914 /*-----------------------------------------------------------------*/
915 /* nFreeRegs - returns number of free registers */
916 /*-----------------------------------------------------------------*/
924 /* although I fixed the register allocation/freeing scheme
925 * the for loop below doesn't give valid results. I do not
926 * know why yet. -- VR 10-Jan-2003 */
931 /* dynamically allocate as many as we need and worry about
932 * fitting them into a PIC later */
934 debugLog ("%s\n", __FUNCTION__);
936 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
937 if((reg->type == type) && reg->isFree)nfr++;
939 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
943 /*-----------------------------------------------------------------*/
944 /* nfreeRegsType - free registers with type */
945 /*-----------------------------------------------------------------*/
947 nfreeRegsType (int type)
950 debugLog ("%s\n", __FUNCTION__);
953 if ((nfr = nFreeRegs (type)) == 0)
954 return nFreeRegs (REG_GPR);
957 return nFreeRegs (type);
960 static void writeSetUsedRegs(FILE *of, set *dRegs)
965 for (dReg = setFirstItem(dRegs) ; dReg ;
966 dReg = setNextItem(dRegs)) {
969 fprintf (of, "\t%s\n",dReg->name);
975 extern void pic16_groupRegistersInSection(set *regset);
977 extern void pic16_dump_equates(FILE *of, set *equs);
978 //extern void pic16_dump_map(void);
979 extern void pic16_dump_usection(FILE *of, set *section, int fix);
980 extern void pic16_dump_isection(FILE *of, set *section, int fix);
981 extern void pic16_dump_int_registers(FILE *of, set *section);
982 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
984 extern void pic16_dump_gsection(FILE *of, set *sections);
986 static void packBits(set *bregs)
991 regs *relocbitfield=NULL;
997 for (regset = bregs ; regset ;
998 regset = regset->next) {
1000 breg = regset->item;
1001 breg->isBitField = 1;
1002 //fprintf(stderr,"bit reg: %s\n",breg->name);
1005 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1007 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1008 breg->rIdx = breg->address & 7;
1009 breg->address >>= 3;
1012 sprintf (buffer, "fbitfield%02x", breg->address);
1013 //fprintf(stderr,"new bit field\n");
1014 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1015 bitfield->isBitField = 1;
1016 bitfield->isFixed = 1;
1017 bitfield->address = breg->address;
1018 addSet(&pic16_dynDirectRegs,bitfield);
1019 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1021 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1024 breg->reg_alias = bitfield;
1028 if(!relocbitfield || bit_no >7) {
1031 sprintf (buffer, "bitfield%d", byte_no);
1032 //fprintf(stderr,"new relocatable bit field\n");
1033 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1034 relocbitfield->isBitField = 1;
1035 addSet(&pic16_dynDirectRegs,relocbitfield);
1036 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1040 breg->reg_alias = relocbitfield;
1041 breg->address = rDirectIdx; /* byte_no; */
1042 breg->rIdx = bit_no++;
1048 void pic16_writeUsedRegs(FILE *of)
1050 packBits(pic16_dynDirectBitRegs);
1052 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1053 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1054 pic16_groupRegistersInSection(pic16_dynStackRegs);
1055 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1056 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1057 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1061 pic16_dump_equates(of, pic16_equ_data);
1063 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1064 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1066 /* dump initialised data */
1067 pic16_dump_isection(of, rel_idataSymSet, 0);
1068 pic16_dump_isection(of, fix_idataSymSet, 1);
1070 /* dump internal registers */
1071 pic16_dump_int_registers(of, pic16_int_regs);
1073 /* dump generic section variables */
1074 pic16_dump_gsection(of, sectNames);
1076 /* dump other variables */
1077 pic16_dump_usection(of, pic16_rel_udata, 0);
1078 pic16_dump_usection(of, pic16_fix_udata, 1);
1083 /*-----------------------------------------------------------------*/
1084 /* computeSpillable - given a point find the spillable live ranges */
1085 /*-----------------------------------------------------------------*/
1087 computeSpillable (iCode * ic)
1091 debugLog ("%s\n", __FUNCTION__);
1092 /* spillable live ranges are those that are live at this
1093 point . the following categories need to be subtracted
1095 a) - those that are already spilt
1096 b) - if being used by this one
1097 c) - defined by this one */
1099 spillable = bitVectCopy (ic->rlive);
1101 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1103 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1104 bitVectUnSetBit (spillable, ic->defKey);
1105 spillable = bitVectIntersect (spillable, _G.regAssigned);
1110 /*-----------------------------------------------------------------*/
1111 /* noSpilLoc - return true if a variable has no spil location */
1112 /*-----------------------------------------------------------------*/
1114 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1116 debugLog ("%s\n", __FUNCTION__);
1117 return (sym->usl.spillLoc ? 0 : 1);
1120 /*-----------------------------------------------------------------*/
1121 /* hasSpilLoc - will return 1 if the symbol has spil location */
1122 /*-----------------------------------------------------------------*/
1124 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1126 debugLog ("%s\n", __FUNCTION__);
1127 return (sym->usl.spillLoc ? 1 : 0);
1130 /*-----------------------------------------------------------------*/
1131 /* directSpilLoc - will return 1 if the splilocation is in direct */
1132 /*-----------------------------------------------------------------*/
1134 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1136 debugLog ("%s\n", __FUNCTION__);
1137 if (sym->usl.spillLoc &&
1138 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1144 /*-----------------------------------------------------------------*/
1145 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1146 /* but is not used as a pointer */
1147 /*-----------------------------------------------------------------*/
1149 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1151 debugLog ("%s\n", __FUNCTION__);
1152 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1155 /*-----------------------------------------------------------------*/
1156 /* rematable - will return 1 if the remat flag is set */
1157 /*-----------------------------------------------------------------*/
1159 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1161 debugLog ("%s\n", __FUNCTION__);
1165 /*-----------------------------------------------------------------*/
1166 /* notUsedInRemaining - not used or defined in remain of the block */
1167 /*-----------------------------------------------------------------*/
1169 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1171 debugLog ("%s\n", __FUNCTION__);
1172 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1173 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1176 /*-----------------------------------------------------------------*/
1177 /* allLRs - return true for all */
1178 /*-----------------------------------------------------------------*/
1180 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1182 debugLog ("%s\n", __FUNCTION__);
1186 /*-----------------------------------------------------------------*/
1187 /* liveRangesWith - applies function to a given set of live range */
1188 /*-----------------------------------------------------------------*/
1190 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1191 eBBlock * ebp, iCode * ic)
1196 debugLog ("%s\n", __FUNCTION__);
1197 if (!lrs || !lrs->size)
1200 for (i = 1; i < lrs->size; i++)
1203 if (!bitVectBitValue (lrs, i))
1206 /* if we don't find it in the live range
1207 hash table we are in serious trouble */
1208 if (!(sym = hTabItemWithKey (liveRanges, i)))
1210 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1211 "liveRangesWith could not find liveRange");
1215 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1216 addSetHead (&rset, sym);
1223 /*-----------------------------------------------------------------*/
1224 /* leastUsedLR - given a set determines which is the least used */
1225 /*-----------------------------------------------------------------*/
1227 leastUsedLR (set * sset)
1229 symbol *sym = NULL, *lsym = NULL;
1231 debugLog ("%s\n", __FUNCTION__);
1232 sym = lsym = setFirstItem (sset);
1237 for (; lsym; lsym = setNextItem (sset))
1240 /* if usage is the same then prefer
1241 the spill the smaller of the two */
1242 if (lsym->used == sym->used)
1243 if (getSize (lsym->type) < getSize (sym->type))
1247 if (lsym->used < sym->used)
1252 setToNull ((void *) &sset);
1257 /*-----------------------------------------------------------------*/
1258 /* noOverLap - will iterate through the list looking for over lap */
1259 /*-----------------------------------------------------------------*/
1261 noOverLap (set * itmpStack, symbol * fsym)
1264 debugLog ("%s\n", __FUNCTION__);
1267 for (sym = setFirstItem (itmpStack); sym;
1268 sym = setNextItem (itmpStack))
1270 if (sym->liveTo > fsym->liveFrom)
1278 /*-----------------------------------------------------------------*/
1279 /* isFree - will return 1 if the a free spil location is found */
1280 /*-----------------------------------------------------------------*/
1285 V_ARG (symbol **, sloc);
1286 V_ARG (symbol *, fsym);
1288 debugLog ("%s\n", __FUNCTION__);
1289 /* if already found */
1293 /* if it is free && and the itmp assigned to
1294 this does not have any overlapping live ranges
1295 with the one currently being assigned and
1296 the size can be accomodated */
1298 noOverLap (sym->usl.itmpStack, fsym) &&
1299 getSize (sym->type) >= getSize (fsym->type))
1308 /*-----------------------------------------------------------------*/
1309 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1310 /*-----------------------------------------------------------------*/
1312 spillLRWithPtrReg (symbol * forSym)
1318 debugLog ("%s\n", __FUNCTION__);
1319 if (!_G.regAssigned ||
1320 bitVectIsZero (_G.regAssigned))
1323 r0 = pic16_regWithIdx (R0_IDX);
1324 r1 = pic16_regWithIdx (R1_IDX);
1326 /* for all live ranges */
1327 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1328 lrsym = hTabNextItem (liveRanges, &k))
1332 /* if no registers assigned to it or
1334 /* if it does not overlap with this then
1335 not need to spill it */
1337 if (lrsym->isspilt || !lrsym->nRegs ||
1338 (lrsym->liveTo < forSym->liveFrom))
1341 /* go thru the registers : if it is either
1342 r0 or r1 then spil it */
1343 for (j = 0; j < lrsym->nRegs; j++)
1344 if (lrsym->regs[j] == r0 ||
1345 lrsym->regs[j] == r1)
1354 /*-----------------------------------------------------------------*/
1355 /* createStackSpil - create a location on the stack to spil */
1356 /*-----------------------------------------------------------------*/
1358 createStackSpil (symbol * sym)
1360 symbol *sloc = NULL;
1361 int useXstack, model, noOverlay;
1363 char slocBuffer[30];
1364 debugLog ("%s\n", __FUNCTION__);
1366 /* first go try and find a free one that is already
1367 existing on the stack */
1368 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1370 /* found a free one : just update & return */
1371 sym->usl.spillLoc = sloc;
1374 addSetHead (&sloc->usl.itmpStack, sym);
1378 /* could not then have to create one , this is the hard part
1379 we need to allocate this on the stack : this is really a
1380 hack!! but cannot think of anything better at this time */
1382 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1384 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1385 __FILE__, __LINE__);
1389 sloc = newiTemp (slocBuffer);
1391 /* set the type to the spilling symbol */
1392 sloc->type = copyLinkChain (sym->type);
1393 sloc->etype = getSpec (sloc->type);
1394 SPEC_SCLS (sloc->etype) = S_DATA;
1395 SPEC_EXTR (sloc->etype) = 0;
1396 SPEC_STAT (sloc->etype) = 0;
1398 /* we don't allow it to be allocated`
1399 onto the external stack since : so we
1400 temporarily turn it off ; we also
1401 turn off memory model to prevent
1402 the spil from going to the external storage
1403 and turn off overlaying
1406 useXstack = options.useXstack;
1407 model = options.model;
1408 noOverlay = options.noOverlay;
1409 options.noOverlay = 1;
1410 options.model = options.useXstack = 0;
1414 options.useXstack = useXstack;
1415 options.model = model;
1416 options.noOverlay = noOverlay;
1417 sloc->isref = 1; /* to prevent compiler warning */
1419 /* if it is on the stack then update the stack */
1420 if (IN_STACK (sloc->etype))
1422 currFunc->stack += getSize (sloc->type);
1423 _G.stackExtend += getSize (sloc->type);
1426 _G.dataExtend += getSize (sloc->type);
1428 /* add it to the _G.stackSpil set */
1429 addSetHead (&_G.stackSpil, sloc);
1430 sym->usl.spillLoc = sloc;
1433 /* add it to the set of itempStack set
1434 of the spill location */
1435 addSetHead (&sloc->usl.itmpStack, sym);
1439 /*-----------------------------------------------------------------*/
1440 /* isSpiltOnStack - returns true if the spil location is on stack */
1441 /*-----------------------------------------------------------------*/
1443 isSpiltOnStack (symbol * sym)
1447 debugLog ("%s\n", __FUNCTION__);
1454 /* if (sym->_G.stackSpil) */
1457 if (!sym->usl.spillLoc)
1460 etype = getSpec (sym->usl.spillLoc->type);
1461 if (IN_STACK (etype))
1467 /*-----------------------------------------------------------------*/
1468 /* spillThis - spils a specific operand */
1469 /*-----------------------------------------------------------------*/
1471 spillThis (symbol * sym)
1474 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1476 /* if this is rematerializable or has a spillLocation
1477 we are okay, else we need to create a spillLocation
1479 if (!(sym->remat || sym->usl.spillLoc))
1480 createStackSpil (sym);
1483 /* mark it has spilt & put it in the spilt set */
1485 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1487 bitVectUnSetBit (_G.regAssigned, sym->key);
1489 for (i = 0; i < sym->nRegs; i++)
1493 freeReg (sym->regs[i]);
1494 sym->regs[i] = NULL;
1497 /* if spilt on stack then free up r0 & r1
1498 if they could have been assigned to some
1500 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1503 spillLRWithPtrReg (sym);
1506 if (sym->usl.spillLoc && !sym->remat)
1507 sym->usl.spillLoc->allocreq = 1;
1511 /*-----------------------------------------------------------------*/
1512 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1513 /*-----------------------------------------------------------------*/
1515 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1517 bitVect *lrcs = NULL;
1521 debugLog ("%s\n", __FUNCTION__);
1522 /* get the spillable live ranges */
1523 lrcs = computeSpillable (ic);
1525 /* get all live ranges that are rematerizable */
1526 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1529 /* return the least used of these */
1530 return leastUsedLR (selectS);
1533 /* get live ranges with spillLocations in direct space */
1534 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1536 sym = leastUsedLR (selectS);
1537 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1538 sym->usl.spillLoc->rname :
1539 sym->usl.spillLoc->name));
1541 /* mark it as allocation required */
1542 sym->usl.spillLoc->allocreq = 1;
1546 /* if the symbol is local to the block then */
1547 if (forSym->liveTo < ebp->lSeq)
1550 /* check if there are any live ranges allocated
1551 to registers that are not used in this block */
1552 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1554 sym = leastUsedLR (selectS);
1555 /* if this is not rematerializable */
1564 /* check if there are any live ranges that not
1565 used in the remainder of the block */
1566 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1568 sym = leastUsedLR (selectS);
1571 sym->remainSpil = 1;
1578 /* find live ranges with spillocation && not used as pointers */
1579 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1582 sym = leastUsedLR (selectS);
1583 /* mark this as allocation required */
1584 sym->usl.spillLoc->allocreq = 1;
1588 /* find live ranges with spillocation */
1589 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1592 sym = leastUsedLR (selectS);
1593 sym->usl.spillLoc->allocreq = 1;
1597 /* couldn't find then we need to create a spil
1598 location on the stack , for which one? the least
1600 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1603 /* return a created spil location */
1604 sym = createStackSpil (leastUsedLR (selectS));
1605 sym->usl.spillLoc->allocreq = 1;
1609 /* this is an extreme situation we will spill
1610 this one : happens very rarely but it does happen */
1616 /*-----------------------------------------------------------------*/
1617 /* spilSomething - spil some variable & mark registers as free */
1618 /*-----------------------------------------------------------------*/
1620 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1625 debugLog ("%s\n", __FUNCTION__);
1626 /* get something we can spil */
1627 ssym = selectSpil (ic, ebp, forSym);
1629 /* mark it as spilt */
1631 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1633 /* mark it as not register assigned &
1634 take it away from the set */
1635 bitVectUnSetBit (_G.regAssigned, ssym->key);
1637 /* mark the registers as free */
1638 for (i = 0; i < ssym->nRegs; i++)
1640 freeReg (ssym->regs[i]);
1642 /* if spilt on stack then free up r0 & r1
1643 if they could have been assigned to as gprs */
1644 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1647 spillLRWithPtrReg (ssym);
1650 /* if this was a block level spil then insert push & pop
1651 at the start & end of block respectively */
1652 if (ssym->blockSpil)
1654 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1655 /* add push to the start of the block */
1656 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1657 ebp->sch->next : ebp->sch));
1658 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1659 /* add pop to the end of the block */
1660 addiCodeToeBBlock (ebp, nic, NULL);
1663 /* if spilt because not used in the remainder of the
1664 block then add a push before this instruction and
1665 a pop at the end of the block */
1666 if (ssym->remainSpil)
1669 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1670 /* add push just before this instruction */
1671 addiCodeToeBBlock (ebp, nic, ic);
1673 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1674 /* add pop to the end of the block */
1675 addiCodeToeBBlock (ebp, nic, NULL);
1684 /*-----------------------------------------------------------------*/
1685 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1686 /*-----------------------------------------------------------------*/
1688 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1693 debugLog ("%s\n", __FUNCTION__);
1695 /* try for a ptr type */
1696 if ((reg = allocReg (REG_PTR)))
1699 /* try for gpr type */
1700 if ((reg = allocReg (REG_GPR)))
1703 /* we have to spil */
1704 if (!spilSomething (ic, ebp, sym))
1707 /* make sure partially assigned registers aren't reused */
1708 for (j=0; j<=sym->nRegs; j++)
1710 sym->regs[j]->isFree = 0;
1712 /* this looks like an infinite loop but
1713 in really selectSpil will abort */
1717 /*-----------------------------------------------------------------*/
1718 /* getRegGpr - will try for GPR if not spil */
1719 /*-----------------------------------------------------------------*/
1721 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1726 debugLog ("%s\n", __FUNCTION__);
1728 /* try for gpr type */
1729 if ((reg = allocReg (REG_GPR)))
1732 if (!pic16_ptrRegReq)
1733 if ((reg = allocReg (REG_PTR)))
1736 /* we have to spil */
1737 if (!spilSomething (ic, ebp, sym))
1740 /* make sure partially assigned registers aren't reused */
1741 for (j=0; j<=sym->nRegs; j++)
1743 sym->regs[j]->isFree = 0;
1745 /* this looks like an infinite loop but
1746 in really selectSpil will abort */
1750 /*-----------------------------------------------------------------*/
1751 /* symHasReg - symbol has a given register */
1752 /*-----------------------------------------------------------------*/
1754 symHasReg (symbol * sym, regs * reg)
1758 debugLog ("%s\n", __FUNCTION__);
1759 for (i = 0; i < sym->nRegs; i++)
1760 if (sym->regs[i] == reg)
1766 /*-----------------------------------------------------------------*/
1767 /* deassignLRs - check the live to and if they have registers & are */
1768 /* not spilt then free up the registers */
1769 /*-----------------------------------------------------------------*/
1771 deassignLRs (iCode * ic, eBBlock * ebp)
1777 debugLog ("%s\n", __FUNCTION__);
1778 for (sym = hTabFirstItem (liveRanges, &k); sym;
1779 sym = hTabNextItem (liveRanges, &k))
1782 symbol *psym = NULL;
1783 /* if it does not end here */
1784 if (sym->liveTo > ic->seq)
1787 /* if it was spilt on stack then we can
1788 mark the stack spil location as free */
1793 sym->usl.spillLoc->isFree = 1;
1799 if (!bitVectBitValue (_G.regAssigned, sym->key))
1802 /* special case check if this is an IFX &
1803 the privious one was a pop and the
1804 previous one was not spilt then keep track
1806 if (ic->op == IFX && ic->prev &&
1807 ic->prev->op == IPOP &&
1808 !ic->prev->parmPush &&
1809 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1810 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1816 bitVectUnSetBit (_G.regAssigned, sym->key);
1818 /* if the result of this one needs registers
1819 and does not have it then assign it right
1821 if (IC_RESULT (ic) &&
1822 !(SKIP_IC2 (ic) || /* not a special icode */
1823 ic->op == JUMPTABLE ||
1828 POINTER_SET (ic)) &&
1829 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1830 result->liveTo > ic->seq && /* and will live beyond this */
1831 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1832 result->regType == sym->regType && /* same register types */
1833 result->nRegs && /* which needs registers */
1834 !result->isspilt && /* and does not already have them */
1836 !bitVectBitValue (_G.regAssigned, result->key) &&
1837 /* the number of free regs + number of regs in this LR
1838 can accomodate the what result Needs */
1839 ((nfreeRegsType (result->regType) +
1840 sym->nRegs) >= result->nRegs)
1844 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1846 result->regs[i] = sym->regs[i];
1848 result->regs[i] = getRegGpr (ic, ebp, result);
1850 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1854 /* free the remaining */
1855 for (; i < sym->nRegs; i++)
1859 if (!symHasReg (psym, sym->regs[i]))
1860 freeReg (sym->regs[i]);
1863 freeReg (sym->regs[i]);
1870 /*-----------------------------------------------------------------*/
1871 /* reassignLR - reassign this to registers */
1872 /*-----------------------------------------------------------------*/
1874 reassignLR (operand * op)
1876 symbol *sym = OP_SYMBOL (op);
1879 debugLog ("%s\n", __FUNCTION__);
1880 /* not spilt any more */
1881 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1882 bitVectUnSetBit (_G.spiltSet, sym->key);
1884 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1888 for (i = 0; i < sym->nRegs; i++)
1889 sym->regs[i]->isFree = 0;
1892 /*-----------------------------------------------------------------*/
1893 /* willCauseSpill - determines if allocating will cause a spill */
1894 /*-----------------------------------------------------------------*/
1896 willCauseSpill (int nr, int rt)
1898 debugLog ("%s\n", __FUNCTION__);
1899 /* first check if there are any avlb registers
1900 of te type required */
1903 /* special case for pointer type
1904 if pointer type not avlb then
1905 check for type gpr */
1906 if (nFreeRegs (rt) >= nr)
1908 if (nFreeRegs (REG_GPR) >= nr)
1913 if (pic16_ptrRegReq)
1915 if (nFreeRegs (rt) >= nr)
1920 if (nFreeRegs (REG_PTR) +
1921 nFreeRegs (REG_GPR) >= nr)
1926 debugLog (" ... yep it will (cause a spill)\n");
1927 /* it will cause a spil */
1931 /*-----------------------------------------------------------------*/
1932 /* positionRegs - the allocator can allocate same registers to res- */
1933 /* ult and operand, if this happens make sure they are in the same */
1934 /* position as the operand otherwise chaos results */
1935 /*-----------------------------------------------------------------*/
1937 positionRegs (symbol * result, symbol * opsym, int lineno)
1939 int count = min (result->nRegs, opsym->nRegs);
1940 int i, j = 0, shared = 0;
1942 debugLog ("%s\n", __FUNCTION__);
1943 /* if the result has been spilt then cannot share */
1948 /* first make sure that they actually share */
1949 for (i = 0; i < count; i++)
1951 for (j = 0; j < count; j++)
1953 if (result->regs[i] == opsym->regs[j] && i != j)
1963 regs *tmp = result->regs[i];
1964 result->regs[i] = result->regs[j];
1965 result->regs[j] = tmp;
1970 /*------------------------------------------------------------------*/
1971 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
1972 /* it should either have registers or have beed spilled. Otherwise, */
1973 /* there was an uninitialized variable, so just spill this to get */
1974 /* the operand in a valid state. */
1975 /*------------------------------------------------------------------*/
1977 verifyRegsAssigned (operand *op, iCode * ic)
1982 if (!IS_ITEMP (op)) return;
1984 sym = OP_SYMBOL (op);
1985 if (sym->isspilt) return;
1986 if (!sym->nRegs) return;
1987 if (sym->regs[0]) return;
1989 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
1990 sym->prereqv ? sym->prereqv->name : sym->name);
1995 /*-----------------------------------------------------------------*/
1996 /* serialRegAssign - serially allocate registers to the variables */
1997 /*-----------------------------------------------------------------*/
1999 serialRegAssign (eBBlock ** ebbs, int count)
2003 debugLog ("%s\n", __FUNCTION__);
2004 /* for all blocks */
2005 for (i = 0; i < count; i++)
2010 if (ebbs[i]->noPath &&
2011 (ebbs[i]->entryLabel != entryLabel &&
2012 ebbs[i]->entryLabel != returnLabel))
2015 /* of all instructions do */
2016 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2019 debugLog (" op: %s\n", decodeOp (ic->op));
2021 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2022 pic16_allocDirReg(IC_RESULT(ic));
2024 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2025 pic16_allocDirReg(IC_LEFT(ic));
2027 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2028 pic16_allocDirReg(IC_RIGHT(ic));
2030 /* if this is an ipop that means some live
2031 range will have to be assigned again */
2033 reassignLR (IC_LEFT (ic));
2035 /* if result is present && is a true symbol */
2036 if (IC_RESULT (ic) && ic->op != IFX &&
2037 IS_TRUE_SYMOP (IC_RESULT (ic)))
2038 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2040 /* take away registers from live
2041 ranges that end at this instruction */
2042 deassignLRs (ic, ebbs[i]);
2044 /* some don't need registers */
2045 if (SKIP_IC2 (ic) ||
2046 ic->op == JUMPTABLE ||
2050 (IC_RESULT (ic) && POINTER_SET (ic)))
2053 /* now we need to allocate registers
2054 only for the result */
2057 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2063 /* if it does not need or is spilt
2064 or is already assigned to registers
2065 or will not live beyond this instructions */
2068 bitVectBitValue (_G.regAssigned, sym->key) ||
2069 sym->liveTo <= ic->seq)
2072 /* if some liverange has been spilt at the block level
2073 and this one live beyond this block then spil this
2075 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2080 /* if trying to allocate this will cause
2081 a spill and there is nothing to spill
2082 or this one is rematerializable then
2084 willCS = willCauseSpill (sym->nRegs, sym->regType);
2085 spillable = computeSpillable (ic);
2087 (willCS && bitVectIsZero (spillable)))
2095 /* If the live range preceeds the point of definition
2096 then ideally we must take into account registers that
2097 have been allocated after sym->liveFrom but freed
2098 before ic->seq. This is complicated, so spill this
2099 symbol instead and let fillGaps handle the allocation. */
2100 if (sym->liveFrom < ic->seq)
2106 /* if it has a spillocation & is used less than
2107 all other live ranges then spill this */
2109 if (sym->usl.spillLoc) {
2110 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2111 allLRs, ebbs[i], ic));
2112 if (leastUsed && leastUsed->used > sym->used) {
2117 /* if none of the liveRanges have a spillLocation then better
2118 to spill this one than anything else already assigned to registers */
2119 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2120 /* if this is local to this block then we might find a block spil */
2121 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2129 if (ic->op == RECEIVE)
2130 debugLog ("When I get clever, I'll optimize the receive logic\n");
2132 /* if we need ptr regs for the right side
2134 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2135 <= (unsigned) PTRSIZE)
2140 /* else we assign registers to it */
2141 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2143 debugLog (" %d - \n", __LINE__);
2145 bitVectDebugOn(_G.regAssigned, debugF);
2147 for (j = 0; j < sym->nRegs; j++)
2149 if (sym->regType == REG_PTR)
2150 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2152 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2154 /* if the allocation falied which means
2155 this was spilt then break */
2159 debugLog (" %d - \n", __LINE__);
2161 /* if it shares registers with operands make sure
2162 that they are in the same position */
2163 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2164 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2165 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2166 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2167 /* do the same for the right operand */
2168 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2169 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2170 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2171 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2173 debugLog (" %d - \n", __LINE__);
2176 debugLog (" %d - \n", __LINE__);
2185 /* Check for and fix any problems with uninitialized operands */
2186 for (i = 0; i < count; i++)
2190 if (ebbs[i]->noPath &&
2191 (ebbs[i]->entryLabel != entryLabel &&
2192 ebbs[i]->entryLabel != returnLabel))
2195 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2202 verifyRegsAssigned (IC_COND (ic), ic);
2206 if (ic->op == JUMPTABLE)
2208 verifyRegsAssigned (IC_JTCOND (ic), ic);
2212 verifyRegsAssigned (IC_RESULT (ic), ic);
2213 verifyRegsAssigned (IC_LEFT (ic), ic);
2214 verifyRegsAssigned (IC_RIGHT (ic), ic);
2220 /*-----------------------------------------------------------------*/
2221 /* rUmaskForOp :- returns register mask for an operand */
2222 /*-----------------------------------------------------------------*/
2224 rUmaskForOp (operand * op)
2230 debugLog ("%s\n", __FUNCTION__);
2231 /* only temporaries are assigned registers */
2235 sym = OP_SYMBOL (op);
2237 /* if spilt or no registers assigned to it
2239 if (sym->isspilt || !sym->nRegs)
2242 rumask = newBitVect (pic16_nRegs);
2244 for (j = 0; j < sym->nRegs; j++)
2246 rumask = bitVectSetBit (rumask,
2247 sym->regs[j]->rIdx);
2253 /*-----------------------------------------------------------------*/
2254 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2255 /*-----------------------------------------------------------------*/
2257 regsUsedIniCode (iCode * ic)
2259 bitVect *rmask = newBitVect (pic16_nRegs);
2261 debugLog ("%s\n", __FUNCTION__);
2262 /* do the special cases first */
2265 rmask = bitVectUnion (rmask,
2266 rUmaskForOp (IC_COND (ic)));
2270 /* for the jumptable */
2271 if (ic->op == JUMPTABLE)
2273 rmask = bitVectUnion (rmask,
2274 rUmaskForOp (IC_JTCOND (ic)));
2279 /* of all other cases */
2281 rmask = bitVectUnion (rmask,
2282 rUmaskForOp (IC_LEFT (ic)));
2286 rmask = bitVectUnion (rmask,
2287 rUmaskForOp (IC_RIGHT (ic)));
2290 rmask = bitVectUnion (rmask,
2291 rUmaskForOp (IC_RESULT (ic)));
2297 /*-----------------------------------------------------------------*/
2298 /* createRegMask - for each instruction will determine the regsUsed */
2299 /*-----------------------------------------------------------------*/
2301 createRegMask (eBBlock ** ebbs, int count)
2305 debugLog ("%s\n", __FUNCTION__);
2306 /* for all blocks */
2307 for (i = 0; i < count; i++)
2311 if (ebbs[i]->noPath &&
2312 (ebbs[i]->entryLabel != entryLabel &&
2313 ebbs[i]->entryLabel != returnLabel))
2316 /* for all instructions */
2317 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2322 if (SKIP_IC2 (ic) || !ic->rlive)
2325 /* first mark the registers used in this
2327 ic->rUsed = regsUsedIniCode (ic);
2328 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2330 /* now create the register mask for those
2331 registers that are in use : this is a
2332 super set of ic->rUsed */
2333 ic->rMask = newBitVect (pic16_nRegs + 1);
2335 /* for all live Ranges alive at this point */
2336 for (j = 1; j < ic->rlive->size; j++)
2341 /* if not alive then continue */
2342 if (!bitVectBitValue (ic->rlive, j))
2345 /* find the live range we are interested in */
2346 if (!(sym = hTabItemWithKey (liveRanges, j)))
2348 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2349 "createRegMask cannot find live range");
2353 /* if no register assigned to it */
2354 if (!sym->nRegs || sym->isspilt)
2357 /* for all the registers allocated to it */
2358 for (k = 0; k < sym->nRegs; k++)
2361 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2367 /*-----------------------------------------------------------------*/
2368 /* rematStr - returns the rematerialized string for a remat var */
2369 /*-----------------------------------------------------------------*/
2371 rematStr (symbol * sym)
2374 iCode *ic = sym->rematiCode;
2375 symbol *psym = NULL;
2377 debugLog ("%s\n", __FUNCTION__);
2379 //printf ("%s\n", s);
2381 /* if plus or minus print the right hand side */
2383 if (ic->op == '+' || ic->op == '-') {
2385 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2387 sprintf (s, "(%s %c 0x%04x)",
2388 OP_SYMBOL (IC_LEFT (ric))->rname,
2390 (int) operandLitValue (IC_RIGHT (ic)));
2393 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2395 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2396 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2401 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2402 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2404 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2409 /*-----------------------------------------------------------------*/
2410 /* rematStr - returns the rematerialized string for a remat var */
2411 /*-----------------------------------------------------------------*/
2413 rematStr (symbol * sym)
2416 iCode *ic = sym->rematiCode;
2418 debugLog ("%s\n", __FUNCTION__);
2423 /* if plus or minus print the right hand side */
2425 if (ic->op == '+' || ic->op == '-') {
2426 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2429 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2433 if (ic->op == '+' || ic->op == '-')
2435 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2436 sprintf (s, "(%s %c 0x%04x)",
2437 OP_SYMBOL (IC_LEFT (ric))->rname,
2439 (int) operandLitValue (IC_RIGHT (ic)));
2442 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2444 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2448 /* we reached the end */
2449 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2453 printf ("%s\n", buffer);
2458 /*-----------------------------------------------------------------*/
2459 /* regTypeNum - computes the type & number of registers required */
2460 /*-----------------------------------------------------------------*/
2468 debugLog ("%s\n", __FUNCTION__);
2469 /* for each live range do */
2470 for (sym = hTabFirstItem (liveRanges, &k); sym;
2471 sym = hTabNextItem (liveRanges, &k)) {
2473 debugLog (" %d - %s\n", __LINE__, sym->rname);
2474 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2476 /* if used zero times then no registers needed */
2477 if ((sym->liveTo - sym->liveFrom) == 0)
2481 /* if the live range is a temporary */
2484 debugLog (" %d - itemp register\n", __LINE__);
2486 /* if the type is marked as a conditional */
2487 if (sym->regType == REG_CND)
2490 /* if used in return only then we don't
2492 if (sym->ruonly || sym->accuse) {
2493 if (IS_AGGREGATE (sym->type) || sym->isptr)
2494 sym->type = aggrToPtr (sym->type, FALSE);
2495 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2500 /* if the symbol has only one definition &
2501 that definition is a get_pointer and the
2502 pointer we are getting is rematerializable and
2505 if (bitVectnBitsOn (sym->defs) == 1 &&
2506 (ic = hTabItemWithKey (iCodehTab,
2507 bitVectFirstBit (sym->defs))) &&
2509 !IS_BITVAR (sym->etype) &&
2510 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2512 if (ptrPseudoSymSafe (sym, ic)) {
2516 debugLog (" %d - \n", __LINE__);
2518 /* create a psuedo symbol & force a spil */
2519 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2520 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2521 psym->type = sym->type;
2522 psym->etype = sym->etype;
2523 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2524 strcpy (psym->rname, psym->name);
2526 sym->usl.spillLoc = psym;
2530 /* if in data space or idata space then try to
2531 allocate pointer register */
2535 /* if not then we require registers */
2536 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2537 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2538 getSize (sym->type));
2542 if(IS_PTR_CONST (sym->type)) {
2544 if(IS_CODEPTR (sym->type)) {
2546 // what IS this ???? (HJD)
2547 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2548 sym->nRegs = 3; // patch 14
2551 if (sym->nRegs > 4) {
2552 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2553 printTypeChain (sym->type, stderr);
2554 fprintf (stderr, "\n");
2557 /* determine the type of register required */
2558 if (sym->nRegs == 1 &&
2559 IS_PTR (sym->type) &&
2561 sym->regType = REG_PTR;
2563 sym->regType = REG_GPR;
2566 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2570 /* for the first run we don't provide */
2571 /* registers for true symbols we will */
2572 /* see how things go */
2577 static DEFSETFUNC (markRegFree)
2579 ((regs *)item)->isFree = 1;
2584 DEFSETFUNC (pic16_deallocReg)
2586 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2587 ((regs *)item)->isFree = 1;
2588 ((regs *)item)->wasUsed = 0;
2592 /*-----------------------------------------------------------------*/
2593 /* freeAllRegs - mark all registers as free */
2594 /*-----------------------------------------------------------------*/
2596 pic16_freeAllRegs ()
2598 debugLog ("%s\n", __FUNCTION__);
2600 applyToSet(pic16_dynAllocRegs,markRegFree);
2601 applyToSet(pic16_dynStackRegs,markRegFree);
2604 /*-----------------------------------------------------------------*/
2605 /*-----------------------------------------------------------------*/
2607 pic16_deallocateAllRegs ()
2609 debugLog ("%s\n", __FUNCTION__);
2611 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2615 /*-----------------------------------------------------------------*/
2616 /* deallocStackSpil - this will set the stack pointer back */
2617 /*-----------------------------------------------------------------*/
2619 DEFSETFUNC (deallocStackSpil)
2623 debugLog ("%s\n", __FUNCTION__);
2628 /*-----------------------------------------------------------------*/
2629 /* farSpacePackable - returns the packable icode for far variables */
2630 /*-----------------------------------------------------------------*/
2632 farSpacePackable (iCode * ic)
2636 debugLog ("%s\n", __FUNCTION__);
2637 /* go thru till we find a definition for the
2638 symbol on the right */
2639 for (dic = ic->prev; dic; dic = dic->prev)
2642 /* if the definition is a call then no */
2643 if ((dic->op == CALL || dic->op == PCALL) &&
2644 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2649 /* if shift by unknown amount then not */
2650 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2651 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2654 /* if pointer get and size > 1 */
2655 if (POINTER_GET (dic) &&
2656 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2659 if (POINTER_SET (dic) &&
2660 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2663 /* if any three is a true symbol in far space */
2664 if (IC_RESULT (dic) &&
2665 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2666 isOperandInFarSpace (IC_RESULT (dic)))
2669 if (IC_RIGHT (dic) &&
2670 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2671 isOperandInFarSpace (IC_RIGHT (dic)) &&
2672 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2675 if (IC_LEFT (dic) &&
2676 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2677 isOperandInFarSpace (IC_LEFT (dic)) &&
2678 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2681 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2683 if ((dic->op == LEFT_OP ||
2684 dic->op == RIGHT_OP ||
2686 IS_OP_LITERAL (IC_RIGHT (dic)))
2696 /*-----------------------------------------------------------------*/
2697 /* packRegsForAssign - register reduction for assignment */
2698 /*-----------------------------------------------------------------*/
2700 packRegsForAssign (iCode * ic, eBBlock * ebp)
2705 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2706 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2707 debugAopGet (" result:", IC_RESULT (ic));
2708 debugAopGet (" left:", IC_LEFT (ic));
2709 debugAopGet (" right:", IC_RIGHT (ic));
2711 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2714 /* if this is at an absolute address, then get the address. */
2715 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2716 if(PIC16_IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2717 debugLog (" %d - found config word declaration\n", __LINE__);
2718 if(IS_VALOP(IC_RIGHT(ic))) {
2719 debugLog (" setting config word to %x\n",
2720 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2722 fprintf(stderr, "%s:%d setting config word to %x\n", __FILE__, __LINE__,
2723 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2725 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2726 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2730 debugLog(" %d\n", __LINE__);
2732 /* remove the assignment from the iCode chain. */
2734 remiCodeFromeBBlock (ebp, ic);
2735 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2736 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2743 debugLog(" %d - actuall processing\n", __LINE__ );
2745 if (!IS_ITEMP (IC_RESULT (ic))) {
2746 pic16_allocDirReg(IC_RESULT (ic));
2747 debugLog (" %d - result is not temp\n", __LINE__);
2751 /* See BUGLOG0001 - VR */
2753 if (!IS_ITEMP (IC_RIGHT (ic))) {
2754 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2755 pic16_allocDirReg(IC_RIGHT (ic));
2760 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2761 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2763 debugLog (" %d - not packing - right side fails \n", __LINE__);
2767 /* if the true symbol is defined in far space or on stack
2768 then we should not since this will increase register pressure */
2769 if (isOperandInFarSpace (IC_RESULT (ic)))
2771 if ((dic = farSpacePackable (ic)))
2778 /* find the definition of iTempNN scanning backwards if we find a
2779 a use of the true symbol before we find the definition then
2781 for (dic = ic->prev; dic; dic = dic->prev)
2784 /* if there is a function call and this is
2785 a parameter & not my parameter then don't pack it */
2786 if ((dic->op == CALL || dic->op == PCALL) &&
2787 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2788 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2790 debugLog (" %d - \n", __LINE__);
2799 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2801 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2802 IS_OP_VOLATILE (IC_RESULT (dic)))
2804 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2810 if( IS_SYMOP( IC_RESULT(dic)) &&
2811 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2813 debugLog (" %d - result is bitfield\n", __LINE__);
2819 if (IS_SYMOP (IC_RESULT (dic)) &&
2820 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2822 /* A previous result was assigned to the same register - we'll our definition */
2823 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2824 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2825 if (POINTER_SET (dic))
2831 if (IS_SYMOP (IC_RIGHT (dic)) &&
2832 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2833 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2835 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2840 if (IS_SYMOP (IC_LEFT (dic)) &&
2841 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2842 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2844 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2849 if (POINTER_SET (dic) &&
2850 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2852 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2860 return 0; /* did not find */
2863 /* This code is taken from the hc08 port. Do not know
2864 * if it fits for pic16, but I leave it here just in case */
2866 /* if assignment then check that right is not a bit */
2867 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2868 sym_link *etype = operandType (IC_RIGHT (dic));
2870 if (IS_BITFIELD (etype)) {
2871 /* if result is a bit too then it's ok */
2872 etype = operandType (IC_RESULT (dic));
2873 if (!IS_BITFIELD (etype)) {
2874 debugLog(" %d bitfields\n");
2881 /* if the result is on stack or iaccess then it must be
2882 the same atleast one of the operands */
2883 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2884 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2888 /* clear the onStack flag, the port doesn't support it yet! FIXME */
2889 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2890 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2894 /* the operation has only one symbol
2895 operator then we can pack */
2896 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2897 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2900 if (!((IC_LEFT (dic) &&
2901 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2903 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2907 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2908 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2909 /* found the definition */
2910 /* replace the result with the result of */
2911 /* this assignment and remove this assignment */
2912 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2913 IC_RESULT (dic) = IC_RESULT (ic);
2915 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2917 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2919 /* delete from liverange table also
2920 delete from all the points inbetween and the new
2922 for (sic = dic; sic != ic; sic = sic->next)
2924 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2925 if (IS_ITEMP (IC_RESULT (dic)))
2926 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2929 remiCodeFromeBBlock (ebp, ic);
2930 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2932 debugLog(" %d\n", __LINE__ );
2933 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2934 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2942 #define NO_packRegsForAccUse
2943 #define NO_packRegsForSupport
2944 #define NO_packRegsForOneuse
2945 #define NO_cast_peep
2950 #ifndef NO_packRegsForSupport
2951 /*-----------------------------------------------------------------*/
2952 /* findAssignToSym : scanning backwards looks for first assig found */
2953 /*-----------------------------------------------------------------*/
2955 findAssignToSym (operand * op, iCode * ic)
2959 debugLog ("%s\n", __FUNCTION__);
2960 for (dic = ic->prev; dic; dic = dic->prev)
2963 /* if definition by assignment */
2964 if (dic->op == '=' &&
2965 !POINTER_SET (dic) &&
2966 IC_RESULT (dic)->key == op->key
2967 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2971 /* we are interested only if defined in far space */
2972 /* or in stack space in case of + & - */
2974 /* if assigned to a non-symbol then return
2976 if (!IS_SYMOP (IC_RIGHT (dic)))
2979 /* if the symbol is in far space then
2981 if (isOperandInFarSpace (IC_RIGHT (dic)))
2984 /* for + & - operations make sure that
2985 if it is on the stack it is the same
2986 as one of the three operands */
2987 if ((ic->op == '+' || ic->op == '-') &&
2988 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2992 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2993 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2996 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2997 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2998 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3006 /* if we find an usage then we cannot delete it */
3007 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3010 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3013 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3017 /* now make sure that the right side of dic
3018 is not defined between ic & dic */
3021 iCode *sic = dic->next;
3023 for (; sic != ic; sic = sic->next)
3024 if (IC_RESULT (sic) &&
3025 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3036 #ifndef NO_packRegsForSupport
3037 /*-----------------------------------------------------------------*/
3038 /* packRegsForSupport :- reduce some registers for support calls */
3039 /*-----------------------------------------------------------------*/
3041 packRegsForSupport (iCode * ic, eBBlock * ebp)
3045 debugLog ("%s\n", __FUNCTION__);
3046 /* for the left & right operand :- look to see if the
3047 left was assigned a true symbol in far space in that
3048 case replace them */
3049 if (IS_ITEMP (IC_LEFT (ic)) &&
3050 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3052 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3058 debugAopGet ("removing left:", IC_LEFT (ic));
3060 /* found it we need to remove it from the
3062 for (sic = dic; sic != ic; sic = sic->next)
3063 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3065 IC_LEFT (ic)->operand.symOperand =
3066 IC_RIGHT (dic)->operand.symOperand;
3067 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3068 remiCodeFromeBBlock (ebp, dic);
3069 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3070 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3074 /* do the same for the right operand */
3077 IS_ITEMP (IC_RIGHT (ic)) &&
3078 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3080 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3086 /* if this is a subtraction & the result
3087 is a true symbol in far space then don't pack */
3088 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3090 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3091 if (IN_FARSPACE (SPEC_OCLS (etype)))
3095 debugAopGet ("removing right:", IC_RIGHT (ic));
3097 /* found it we need to remove it from the
3099 for (sic = dic; sic != ic; sic = sic->next)
3100 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3102 IC_RIGHT (ic)->operand.symOperand =
3103 IC_RIGHT (dic)->operand.symOperand;
3104 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3106 remiCodeFromeBBlock (ebp, dic);
3107 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3108 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3117 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3119 #ifndef NO_packRegsForOneuse
3120 /*-----------------------------------------------------------------*/
3121 /* packRegsForOneuse : - will reduce some registers for single Use */
3122 /*-----------------------------------------------------------------*/
3124 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3129 debugLog ("%s\n", __FUNCTION__);
3130 /* if returning a literal then do nothing */
3134 /* only upto 2 bytes since we cannot predict
3135 the usage of b, & acc */
3136 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3141 /* this routine will mark the a symbol as used in one
3142 instruction use only && if the definition is local
3143 (ie. within the basic block) && has only one definition &&
3144 that definition is either a return value from a
3145 function or does not contain any variables in
3147 uses = bitVectCopy (OP_USES (op));
3148 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3149 if (!bitVectIsZero (uses)) /* has other uses */
3152 /* if it has only one defintion */
3153 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3154 return NULL; /* has more than one definition */
3156 /* get that definition */
3158 hTabItemWithKey (iCodehTab,
3159 bitVectFirstBit (OP_DEFS (op)))))
3162 /* found the definition now check if it is local */
3163 if (dic->seq < ebp->fSeq ||
3164 dic->seq > ebp->lSeq)
3165 return NULL; /* non-local */
3167 /* now check if it is the return from
3169 if (dic->op == CALL || dic->op == PCALL)
3171 if (ic->op != SEND && ic->op != RETURN &&
3172 !POINTER_SET(ic) && !POINTER_GET(ic))
3174 OP_SYMBOL (op)->ruonly = 1;
3181 /* otherwise check that the definition does
3182 not contain any symbols in far space */
3183 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3184 isOperandInFarSpace (IC_RIGHT (dic)) ||
3185 IS_OP_RUONLY (IC_LEFT (ic)) ||
3186 IS_OP_RUONLY (IC_RIGHT (ic)))
3191 /* if pointer set then make sure the pointer
3193 if (POINTER_SET (dic) &&
3194 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3197 if (POINTER_GET (dic) &&
3198 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3203 /* also make sure the intervenening instructions
3204 don't have any thing in far space */
3205 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3208 /* if there is an intervening function call then no */
3209 if (dic->op == CALL || dic->op == PCALL)
3211 /* if pointer set then make sure the pointer
3213 if (POINTER_SET (dic) &&
3214 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3217 if (POINTER_GET (dic) &&
3218 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3221 /* if address of & the result is remat then okay */
3222 if (dic->op == ADDRESS_OF &&
3223 OP_SYMBOL (IC_RESULT (dic))->remat)
3226 /* if operand has size of three or more & this
3227 operation is a '*','/' or '%' then 'b' may
3229 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3230 getSize (operandType (op)) >= 3)
3233 /* if left or right or result is in far space */
3234 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3235 isOperandInFarSpace (IC_RIGHT (dic)) ||
3236 isOperandInFarSpace (IC_RESULT (dic)) ||
3237 IS_OP_RUONLY (IC_LEFT (dic)) ||
3238 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3239 IS_OP_RUONLY (IC_RESULT (dic)))
3245 OP_SYMBOL (op)->ruonly = 1;
3252 /*-----------------------------------------------------------------*/
3253 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3254 /*-----------------------------------------------------------------*/
3256 isBitwiseOptimizable (iCode * ic)
3258 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3259 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3261 debugLog ("%s\n", __FUNCTION__);
3262 /* bitwise operations are considered optimizable
3263 under the following conditions (Jean-Louis VERN)
3275 if (IS_LITERAL (rtype) ||
3276 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3283 #ifndef NO_packRegsForAccUse
3285 /*-----------------------------------------------------------------*/
3286 /* packRegsForAccUse - pack registers for acc use */
3287 /*-----------------------------------------------------------------*/
3289 packRegsForAccUse (iCode * ic)
3293 debugLog ("%s\n", __FUNCTION__);
3295 /* if this is an aggregate, e.g. a one byte char array */
3296 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3299 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3301 /* if + or - then it has to be one byte result */
3302 if ((ic->op == '+' || ic->op == '-')
3303 && getSize (operandType (IC_RESULT (ic))) > 1)
3306 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3307 /* if shift operation make sure right side is not a literal */
3308 if (ic->op == RIGHT_OP &&
3309 (isOperandLiteral (IC_RIGHT (ic)) ||
3310 getSize (operandType (IC_RESULT (ic))) > 1))
3313 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3314 if (ic->op == LEFT_OP &&
3315 (isOperandLiteral (IC_RIGHT (ic)) ||
3316 getSize (operandType (IC_RESULT (ic))) > 1))
3319 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3320 if (IS_BITWISE_OP (ic) &&
3321 getSize (operandType (IC_RESULT (ic))) > 1)
3325 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3326 /* has only one definition */
3327 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3330 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3331 /* has only one use */
3332 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3335 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3336 /* and the usage immediately follows this iCode */
3337 if (!(uic = hTabItemWithKey (iCodehTab,
3338 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3341 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3342 if (ic->next != uic)
3345 /* if it is a conditional branch then we definitely can */
3349 if (uic->op == JUMPTABLE)
3352 /* if the usage is not is an assignment
3353 or an arithmetic / bitwise / shift operation then not */
3354 if (POINTER_SET (uic) &&
3355 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3358 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3359 if (uic->op != '=' &&
3360 !IS_ARITHMETIC_OP (uic) &&
3361 !IS_BITWISE_OP (uic) &&
3362 uic->op != LEFT_OP &&
3363 uic->op != RIGHT_OP)
3366 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3367 /* if used in ^ operation then make sure right is not a
3369 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3372 /* if shift operation make sure right side is not a literal */
3373 if (uic->op == RIGHT_OP &&
3374 (isOperandLiteral (IC_RIGHT (uic)) ||
3375 getSize (operandType (IC_RESULT (uic))) > 1))
3378 if (uic->op == LEFT_OP &&
3379 (isOperandLiteral (IC_RIGHT (uic)) ||
3380 getSize (operandType (IC_RESULT (uic))) > 1))
3383 /* make sure that the result of this icode is not on the
3384 stack, since acc is used to compute stack offset */
3385 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3386 OP_SYMBOL (IC_RESULT (uic))->onStack)
3389 /* if either one of them in far space then we cannot */
3390 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3391 isOperandInFarSpace (IC_LEFT (uic))) ||
3392 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3393 isOperandInFarSpace (IC_RIGHT (uic))))
3396 /* if the usage has only one operand then we can */
3397 if (IC_LEFT (uic) == NULL ||
3398 IC_RIGHT (uic) == NULL)
3401 /* make sure this is on the left side if not
3402 a '+' since '+' is commutative */
3403 if (ic->op != '+' &&
3404 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3408 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3409 /* if one of them is a literal then we can */
3410 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3411 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3412 (getSize (operandType (IC_RESULT (uic))) <= 1))
3414 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3419 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3420 /* if the other one is not on stack then we can */
3421 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3422 (IS_ITEMP (IC_RIGHT (uic)) ||
3423 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3424 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3427 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3428 (IS_ITEMP (IC_LEFT (uic)) ||
3429 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3430 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3436 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3437 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3444 /*-----------------------------------------------------------------*/
3445 /* packForPush - hueristics to reduce iCode for pushing */
3446 /*-----------------------------------------------------------------*/
3448 packForReceive (iCode * ic, eBBlock * ebp)
3452 debugLog ("%s\n", __FUNCTION__);
3453 debugAopGet (" result:", IC_RESULT (ic));
3454 debugAopGet (" left:", IC_LEFT (ic));
3455 debugAopGet (" right:", IC_RIGHT (ic));
3460 for (dic = ic->next; dic; dic = dic->next)
3465 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3466 debugLog (" used on left\n");
3467 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3468 debugLog (" used on right\n");
3469 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3470 debugLog (" used on result\n");
3472 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3473 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3478 debugLog (" hey we can remove this unnecessary assign\n");
3480 /*-----------------------------------------------------------------*/
3481 /* packForPush - hueristics to reduce iCode for pushing */
3482 /*-----------------------------------------------------------------*/
3484 packForPush (iCode * ic, eBBlock * ebp)
3488 debugLog ("%s\n", __FUNCTION__);
3489 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3492 /* must have only definition & one usage */
3493 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3494 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3497 /* find the definition */
3498 if (!(dic = hTabItemWithKey (iCodehTab,
3499 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3502 if (dic->op != '=' || POINTER_SET (dic))
3505 /* we now we know that it has one & only one def & use
3506 and the that the definition is an assignment */
3507 IC_LEFT (ic) = IC_RIGHT (dic);
3509 remiCodeFromeBBlock (ebp, dic);
3510 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3511 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3514 static void printSymType(char * str, sym_link *sl)
3516 if(!pic16_ralloc_debug)return;
3518 debugLog (" %s Symbol type: ",str);
3519 printTypeChain( sl, debugF);
3523 /*-----------------------------------------------------------------*/
3524 /* some debug code to print the symbol S_TYPE. Note that
3525 * the function checkSClass in src/SDCCsymt.c dinks with
3526 * the S_TYPE in ways the PIC port doesn't fully like...*/
3527 /*-----------------------------------------------------------------*/
3528 static void isData(sym_link *sl)
3532 if(!pic16_ralloc_debug)return;
3539 for ( ; sl; sl=sl->next) {
3541 switch (SPEC_SCLS(sl)) {
3542 case S_DATA: fprintf (of, "data "); break;
3543 case S_XDATA: fprintf (of, "xdata "); break;
3544 case S_SFR: fprintf (of, "sfr "); break;
3545 case S_SBIT: fprintf (of, "sbit "); break;
3546 case S_CODE: fprintf (of, "code "); break;
3547 case S_IDATA: fprintf (of, "idata "); break;
3548 case S_PDATA: fprintf (of, "pdata "); break;
3549 case S_LITERAL: fprintf (of, "literal "); break;
3550 case S_STACK: fprintf (of, "stack "); break;
3551 case S_XSTACK: fprintf (of, "xstack "); break;
3552 case S_BIT: fprintf (of, "bit "); break;
3553 case S_EEPROM: fprintf (of, "eeprom "); break;
3562 /*--------------------------------------------------------------------*/
3563 /* pic16_packRegisters - does some transformations to reduce */
3564 /* register pressure */
3566 /*--------------------------------------------------------------------*/
3568 pic16_packRegisters (eBBlock * ebp)
3573 debugLog ("%s\n", __FUNCTION__);
3579 /* look for assignments of the form */
3580 /* iTempNN = TRueSym (someoperation) SomeOperand */
3582 /* TrueSym := iTempNN:1 */
3583 for (ic = ebp->sch; ic; ic = ic->next)
3585 // debugLog("%d\n", __LINE__);
3586 /* find assignment of the form TrueSym := iTempNN:1 */
3587 /* see BUGLOG0001 for workaround with the CAST - VR */
3588 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3589 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3590 change += packRegsForAssign (ic, ebp);
3594 if (POINTER_SET (ic))
3595 debugLog ("pointer is set\n");
3596 debugAopGet (" result:", IC_RESULT (ic));
3597 debugAopGet (" left:", IC_LEFT (ic));
3598 debugAopGet (" right:", IC_RIGHT (ic));
3607 for (ic = ebp->sch; ic; ic = ic->next) {
3609 if(IS_SYMOP ( IC_LEFT(ic))) {
3610 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3612 debugAopGet ("x left:", IC_LEFT (ic));
3614 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3616 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3618 debugLog (" is a pointer\n");
3620 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3621 debugLog (" is a ptr\n");
3623 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3624 debugLog (" is volatile\n");
3628 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3629 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3630 pic16_allocDirReg(IC_LEFT (ic));
3633 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3636 if(IS_SYMOP ( IC_RIGHT(ic))) {
3637 debugAopGet (" right:", IC_RIGHT (ic));
3638 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3641 if(IS_SYMOP ( IC_RESULT(ic))) {
3642 debugAopGet (" result:", IC_RESULT (ic));
3643 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3646 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3647 debugAopGet (" right:", IC_RIGHT (ic));
3648 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3649 // pic16_allocDirReg(IC_RIGHT(ic));
3652 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3653 debugAopGet (" result:", IC_RESULT (ic));
3654 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3655 // pic16_allocDirReg(IC_RESULT(ic));
3659 if (POINTER_SET (ic))
3660 debugLog (" %d - Pointer set\n", __LINE__);
3663 /* if this is an itemp & result of a address of a true sym
3664 then mark this as rematerialisable */
3665 if (ic->op == ADDRESS_OF &&
3666 IS_ITEMP (IC_RESULT (ic)) &&
3667 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3668 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3669 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3672 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3674 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3675 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3676 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3680 /* if straight assignment then carry remat flag if
3681 this is the only definition */
3682 if (ic->op == '=' &&
3683 !POINTER_SET (ic) &&
3684 IS_SYMOP (IC_RIGHT (ic)) &&
3685 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3686 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3688 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3690 OP_SYMBOL (IC_RESULT (ic))->remat =
3691 OP_SYMBOL (IC_RIGHT (ic))->remat;
3692 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3693 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3696 /* if this is a +/- operation with a rematerizable
3697 then mark this as rematerializable as well */
3698 if ((ic->op == '+' || ic->op == '-') &&
3699 (IS_SYMOP (IC_LEFT (ic)) &&
3700 IS_ITEMP (IC_RESULT (ic)) &&
3701 OP_SYMBOL (IC_LEFT (ic))->remat &&
3702 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3703 IS_OP_LITERAL (IC_RIGHT (ic))))
3705 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3707 operandLitValue (IC_RIGHT (ic));
3708 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3709 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3710 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3713 /* mark the pointer usages */
3714 if (POINTER_SET (ic))
3716 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3717 debugLog (" marking as a pointer (set) =>");
3718 debugAopGet (" result:", IC_RESULT (ic));
3720 if (POINTER_GET (ic))
3722 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3723 debugLog (" marking as a pointer (get) =>");
3724 debugAopGet (" left:", IC_LEFT (ic));
3727 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3731 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3732 /* if we are using a symbol on the stack
3733 then we should say pic16_ptrRegReq */
3734 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3735 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3736 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3737 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3738 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3739 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3743 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3744 if (IS_SYMOP (IC_LEFT (ic)))
3745 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3746 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3747 if (IS_SYMOP (IC_RIGHT (ic)))
3748 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3749 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3750 if (IS_SYMOP (IC_RESULT (ic)))
3751 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3752 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3755 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3759 /* if the condition of an if instruction
3760 is defined in the previous instruction then
3761 mark the itemp as a conditional */
3762 if ((IS_CONDITIONAL (ic) ||
3763 ((ic->op == BITWISEAND ||
3766 isBitwiseOptimizable (ic))) &&
3767 ic->next && ic->next->op == IFX &&
3768 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3769 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3772 debugLog (" %d\n", __LINE__);
3773 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3777 debugLog(" %d\n", __LINE__);
3779 #ifndef NO_packRegsForSupport
3780 /* reduce for support function calls */
3781 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3782 packRegsForSupport (ic, ebp);
3785 /* if a parameter is passed, it's in W, so we may not
3786 need to place a copy in a register */
3787 if (ic->op == RECEIVE)
3788 packForReceive (ic, ebp);
3790 #ifndef NO_packRegsForOneuse
3791 /* some cases the redundant moves can
3792 can be eliminated for return statements */
3793 if ((ic->op == RETURN || ic->op == SEND) &&
3794 !isOperandInFarSpace (IC_LEFT (ic)) &&
3796 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3799 #ifndef NO_packRegsForOneuse
3800 /* if pointer set & left has a size more than
3801 one and right is not in far space */
3802 if (POINTER_SET (ic) &&
3803 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3804 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3805 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3806 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3808 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3811 #ifndef NO_packRegsForOneuse
3812 /* if pointer get */
3813 if (POINTER_GET (ic) &&
3814 !isOperandInFarSpace (IC_RESULT (ic)) &&
3815 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3816 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3817 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3819 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3820 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3823 #ifndef NO_cast_peep
3824 /* if this is cast for intergral promotion then
3825 check if only use of the definition of the
3826 operand being casted/ if yes then replace
3827 the result of that arithmetic operation with
3828 this result and get rid of the cast */
3829 if (ic->op == CAST) {
3831 sym_link *fromType = operandType (IC_RIGHT (ic));
3832 sym_link *toType = operandType (IC_LEFT (ic));
3834 debugLog (" %d - casting\n", __LINE__);
3836 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3837 getSize (fromType) != getSize (toType)) {
3840 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3843 if (IS_ARITHMETIC_OP (dic)) {
3844 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3846 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3847 IC_RESULT (dic) = IC_RESULT (ic);
3848 remiCodeFromeBBlock (ebp, ic);
3849 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3850 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3851 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3855 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3859 /* if the type from and type to are the same
3860 then if this is the only use then packit */
3861 if (compareType (operandType (IC_RIGHT (ic)),
3862 operandType (IC_LEFT (ic))) == 1) {
3864 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3867 debugLog(" %d\n", __LINE__);
3869 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3870 IC_RESULT (dic) = IC_RESULT (ic);
3871 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3872 remiCodeFromeBBlock (ebp, ic);
3873 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3874 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3882 iTempNN := (some variable in farspace) V1
3887 if (ic->op == IPUSH)
3889 packForPush (ic, ebp);
3893 #ifndef NO_packRegsForAccUse
3894 /* pack registers for accumulator use, when the
3895 result of an arithmetic or bit wise operation
3896 has only one use, that use is immediately following
3897 the defintion and the using iCode has only one
3898 operand or has two operands but one is literal &
3899 the result of that operation is not on stack then
3900 we can leave the result of this operation in acc:b
3902 if ((IS_ARITHMETIC_OP (ic)
3904 || IS_BITWISE_OP (ic)
3906 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3909 IS_ITEMP (IC_RESULT (ic)) &&
3910 getSize (operandType (IC_RESULT (ic))) <= 1)
3912 packRegsForAccUse (ic);
3919 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3923 if (!pic16_ralloc_debug || !debugF)
3926 for (i = 0; i < count; i++)
3928 fprintf (debugF, "\n----------------------------------------------------------------\n");
3929 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3930 ebbs[i]->entryLabel->name,
3933 ebbs[i]->isLastInLoop);
3934 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3939 fprintf (debugF, "visited %d : hasFcall = %d\n",
3943 fprintf (debugF, "\ndefines bitVector :");
3944 bitVectDebugOn (ebbs[i]->defSet, debugF);
3945 fprintf (debugF, "\nlocal defines bitVector :");
3946 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3947 fprintf (debugF, "\npointers Set bitvector :");
3948 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3949 fprintf (debugF, "\nin pointers Set bitvector :");
3950 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3951 fprintf (debugF, "\ninDefs Set bitvector :");
3952 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3953 fprintf (debugF, "\noutDefs Set bitvector :");
3954 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3955 fprintf (debugF, "\nusesDefs Set bitvector :");
3956 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3957 fprintf (debugF, "\n----------------------------------------------------------------\n");
3958 printiCChain (ebbs[i]->sch, debugF);
3961 /*-----------------------------------------------------------------*/
3962 /* pic16_assignRegisters - assigns registers to each live range as need */
3963 /*-----------------------------------------------------------------*/
3965 pic16_assignRegisters (eBBlock ** ebbs, int count)
3970 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3971 debugLog ("\nebbs before optimizing:\n");
3972 dumpEbbsToDebug (ebbs, count);
3974 setToNull ((void *) &_G.funcrUsed);
3975 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3978 /* change assignments this will remove some
3979 live ranges reducing some register pressure */
3980 for (i = 0; i < count; i++)
3981 pic16_packRegisters (ebbs[i]);
3988 debugLog("dir registers allocated so far:\n");
3989 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3992 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3993 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3994 reg = hTabNextItem(dynDirectRegNames, &hkey);
3999 /* liveranges probably changed by register packing
4000 so we compute them again */
4001 recomputeLiveRanges (ebbs, count);
4003 if (options.dump_pack)
4004 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4006 /* first determine for each live range the number of
4007 registers & the type of registers required for each */
4010 /* and serially allocate registers */
4011 serialRegAssign (ebbs, count);
4013 // debugLog ("ebbs after serialRegAssign:\n");
4014 // dumpEbbsToDebug (ebbs, count);
4017 //pic16_freeAllRegs();
4019 /* if stack was extended then tell the user */
4022 /* werror(W_TOOMANY_SPILS,"stack", */
4023 /* _G.stackExtend,currFunc->name,""); */
4029 /* werror(W_TOOMANY_SPILS,"data space", */
4030 /* _G.dataExtend,currFunc->name,""); */
4034 /* after that create the register mask
4035 for each of the instruction */
4036 createRegMask (ebbs, count);
4038 /* redo that offsets for stacked automatic variables */
4039 redoStackOffsets ();
4041 if (options.dump_rassgn)
4042 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4044 /* now get back the chain */
4045 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4047 debugLog ("ebbs after optimizing:\n");
4048 dumpEbbsToDebug (ebbs, count);
4053 /* free up any _G.stackSpil locations allocated */
4054 applyToSet (_G.stackSpil, deallocStackSpil);
4056 setToNull ((void *) &_G.stackSpil);
4057 setToNull ((void *) &_G.spiltSet);
4058 /* mark all registers as free */
4059 pic16_freeAllRegs ();
4061 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");