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 *);
51 extern void pic16_assignConfigWordValue(int address, int value);
61 bitVect *funcrUsed; /* registers used in a function */
67 /* Shared with gen.c */
68 int pic16_ptrRegReq; /* one byte pointer register required */
71 set *pic16_dynAllocRegs=NULL;
72 set *pic16_dynStackRegs=NULL;
73 set *pic16_dynProcessorRegs=NULL;
74 set *pic16_dynDirectRegs=NULL;
75 set *pic16_dynDirectBitRegs=NULL;
76 set *pic16_dynInternalRegs=NULL;
78 static hTab *dynDirectRegNames= NULL;
79 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
81 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
82 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
83 set *pic16_equ_data=NULL; /* registers used by equates */
84 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
86 set *pic16_builtin_functions=NULL;
88 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
89 static int rDirectIdx=0;
91 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
93 int pic16_Gstack_base_addr=0; /* The starting address of registers that
94 * are used to pass and return parameters */
99 static void spillThis (symbol *);
100 int pic16_ralloc_debug = 0;
101 static FILE *debugF = NULL;
102 /*-----------------------------------------------------------------*/
103 /* debugLog - open a file for debugging information */
104 /*-----------------------------------------------------------------*/
105 //static void debugLog(char *inst,char *fmt, ...)
107 debugLog (char *fmt,...)
109 static int append = 0; // First time through, open the file without append.
112 //char *bufferP=buffer;
115 if (!pic16_ralloc_debug || !dstFileName)
121 /* create the file name */
122 strcpy (buffer, dstFileName);
123 strcat (buffer, ".d");
125 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
127 werror (E_FILE_OPEN_ERR, buffer);
130 append = 1; // Next time debubLog is called, we'll append the debug info
136 vsprintf (buffer, fmt, ap);
138 fprintf (debugF, "%s", buffer);
140 while (isspace(*bufferP)) bufferP++;
142 if (bufferP && *bufferP)
143 lineCurr = (lineCurr ?
144 connectLine(lineCurr,newLineNode(lb)) :
145 (lineHead = newLineNode(lb)));
146 lineCurr->isInline = _G.inLine;
147 lineCurr->isDebug = _G.debugLine;
156 if(!pic16_ralloc_debug)return;
159 fputc ('\n', debugF);
161 /*-----------------------------------------------------------------*/
162 /* debugLogClose - closes the debug log file (if opened) */
163 /*-----------------------------------------------------------------*/
173 #define AOP(op) op->aop
176 debugAopGet (char *str, operand * op)
178 if(!pic16_ralloc_debug)return NULL;
183 printOperand (op, debugF);
190 decodeOp (unsigned int op)
192 if (op < 128 && op > ' ') {
193 buffer[0] = (op & 0xff);
199 case IDENTIFIER: return "IDENTIFIER";
200 case TYPE_NAME: return "TYPE_NAME";
201 case CONSTANT: return "CONSTANT";
202 case STRING_LITERAL: return "STRING_LITERAL";
203 case SIZEOF: return "SIZEOF";
204 case PTR_OP: return "PTR_OP";
205 case INC_OP: return "INC_OP";
206 case DEC_OP: return "DEC_OP";
207 case LEFT_OP: return "LEFT_OP";
208 case RIGHT_OP: return "RIGHT_OP";
209 case LE_OP: return "LE_OP";
210 case GE_OP: return "GE_OP";
211 case EQ_OP: return "EQ_OP";
212 case NE_OP: return "NE_OP";
213 case AND_OP: return "AND_OP";
214 case OR_OP: return "OR_OP";
215 case MUL_ASSIGN: return "MUL_ASSIGN";
216 case DIV_ASSIGN: return "DIV_ASSIGN";
217 case MOD_ASSIGN: return "MOD_ASSIGN";
218 case ADD_ASSIGN: return "ADD_ASSIGN";
219 case SUB_ASSIGN: return "SUB_ASSIGN";
220 case LEFT_ASSIGN: return "LEFT_ASSIGN";
221 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
222 case AND_ASSIGN: return "AND_ASSIGN";
223 case XOR_ASSIGN: return "XOR_ASSIGN";
224 case OR_ASSIGN: return "OR_ASSIGN";
225 case TYPEDEF: return "TYPEDEF";
226 case EXTERN: return "EXTERN";
227 case STATIC: return "STATIC";
228 case AUTO: return "AUTO";
229 case REGISTER: return "REGISTER";
230 case CODE: return "CODE";
231 case EEPROM: return "EEPROM";
232 case INTERRUPT: return "INTERRUPT";
233 case SFR: return "SFR";
234 case AT: return "AT";
235 case SBIT: return "SBIT";
236 case REENTRANT: return "REENTRANT";
237 case USING: return "USING";
238 case XDATA: return "XDATA";
239 case DATA: return "DATA";
240 case IDATA: return "IDATA";
241 case PDATA: return "PDATA";
242 case VAR_ARGS: return "VAR_ARGS";
243 case CRITICAL: return "CRITICAL";
244 case NONBANKED: return "NONBANKED";
245 case BANKED: return "BANKED";
246 case CHAR: return "CHAR";
247 case SHORT: return "SHORT";
248 case INT: return "INT";
249 case LONG: return "LONG";
250 case SIGNED: return "SIGNED";
251 case UNSIGNED: return "UNSIGNED";
252 case FLOAT: return "FLOAT";
253 case DOUBLE: return "DOUBLE";
254 case CONST: return "CONST";
255 case VOLATILE: return "VOLATILE";
256 case VOID: return "VOID";
257 case BIT: return "BIT";
258 case STRUCT: return "STRUCT";
259 case UNION: return "UNION";
260 case ENUM: return "ENUM";
261 case ELIPSIS: return "ELIPSIS";
262 case RANGE: return "RANGE";
263 case FAR: return "FAR";
264 case CASE: return "CASE";
265 case DEFAULT: return "DEFAULT";
266 case IF: return "IF";
267 case ELSE: return "ELSE";
268 case SWITCH: return "SWITCH";
269 case WHILE: return "WHILE";
270 case DO: return "DO";
271 case FOR: return "FOR";
272 case GOTO: return "GOTO";
273 case CONTINUE: return "CONTINUE";
274 case BREAK: return "BREAK";
275 case RETURN: return "RETURN";
276 case INLINEASM: return "INLINEASM";
277 case IFX: return "IFX";
278 case ADDRESS_OF: return "ADDRESS_OF";
279 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
280 case SPIL: return "SPIL";
281 case UNSPIL: return "UNSPIL";
282 case GETHBIT: return "GETHBIT";
283 case BITWISEAND: return "BITWISEAND";
284 case UNARYMINUS: return "UNARYMINUS";
285 case IPUSH: return "IPUSH";
286 case IPOP: return "IPOP";
287 case PCALL: return "PCALL";
288 case ENDFUNCTION: return "ENDFUNCTION";
289 case JUMPTABLE: return "JUMPTABLE";
290 case RRC: return "RRC";
291 case RLC: return "RLC";
292 case CAST: return "CAST";
293 case CALL: return "CALL";
294 case PARAM: return "PARAM ";
295 case NULLOP: return "NULLOP";
296 case BLOCK: return "BLOCK";
297 case LABEL: return "LABEL";
298 case RECEIVE: return "RECEIVE";
299 case SEND: return "SEND";
301 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
305 /*-----------------------------------------------------------------*/
306 /*-----------------------------------------------------------------*/
308 debugLogRegType (short type)
310 if(!pic16_ralloc_debug)return NULL;
312 case REG_GPR: return "REG_GPR";
313 case REG_PTR: return "REG_PTR";
314 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
321 /*-----------------------------------------------------------------*/
322 /*-----------------------------------------------------------------*/
323 static int regname2key(char const *name)
332 key += (*name++) + 1;
336 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
348 dReg = Safe_calloc(1,sizeof(regs));
350 dReg->pc_type = pc_type;
353 dReg->name = Safe_strdup(name);
355 sprintf(buffer,"r0x%02X", dReg->rIdx);
358 dReg->name = Safe_strdup(buffer);
365 // dReg->isMapped = 0;
368 if(type == REG_SFR) {
370 dReg->address = rIdx;
371 dReg->accessBank = 1;
375 dReg->accessBank = 0;
378 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
382 dReg->reg_alias = NULL;
383 dReg->reglives.usedpFlows = newSet();
384 dReg->reglives.assignedpFlows = newSet();
387 if(!(type == REG_SFR && alias == 0x80))
388 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
393 /*-----------------------------------------------------------------*/
394 /* regWithIdx - Search through a set of registers that matches idx */
395 /*-----------------------------------------------------------------*/
397 regWithIdx (set *dRegs, int idx, int fixed)
401 for (dReg = setFirstItem(dRegs) ; dReg ;
402 dReg = setNextItem(dRegs)) {
404 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
412 /*-----------------------------------------------------------------*/
413 /* regFindFree - Search for a free register in a set of registers */
414 /*-----------------------------------------------------------------*/
416 regFindFree (set *dRegs)
420 for (dReg = setFirstItem(dRegs) ; dReg ;
421 dReg = setNextItem(dRegs)) {
423 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
424 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
433 /*-----------------------------------------------------------------*/
434 /* pic16_initStack - allocate registers for a pseudo stack */
435 /*-----------------------------------------------------------------*/
436 void pic16_initStack(int base_address, int size)
441 pic16_Gstack_base_addr = base_address;
442 //fprintf(stderr,"initStack");
444 for(i = 0; i<size; i++)
445 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
448 /*-----------------------------------------------------------------*
449 *-----------------------------------------------------------------*/
451 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
453 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
455 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
457 reg->wasUsed = 0; // we do not know if they are going to be used at all
458 reg->accessBank = 1; // implicit add access Bank
460 return addSet(&pic16_dynProcessorRegs, reg);
463 /*-----------------------------------------------------------------*
464 *-----------------------------------------------------------------*/
467 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
469 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
471 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
475 return addSet(&pic16_dynInternalRegs,reg);
480 /*-----------------------------------------------------------------*/
481 /* allocReg - allocates register of given type */
482 /*-----------------------------------------------------------------*/
484 allocReg (short type)
489 if(dynrIdx > pic16_nRegs)
493 /* try to reuse some unused registers */
494 reg = regFindFree( pic16_dynAllocRegs );
497 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
498 addSet(&pic16_dynAllocRegs, reg);
502 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
504 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
505 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
508 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
509 reg->isLocal = 1; /* this is a local frame register */
513 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
515 return (reg); // addSet(&pic16_dynAllocRegs,reg);
520 /*-----------------------------------------------------------------*/
521 /* pic16_dirregWithName - search for register by name */
522 /*-----------------------------------------------------------------*/
524 pic16_dirregWithName (char *name)
532 /* hash the name to get a key */
534 hkey = regname2key(name);
536 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
538 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
542 if(STRCASECMP(reg->name, name) == 0) {
546 reg = hTabNextItemWK (dynDirectRegNames);
550 return NULL; // name wasn't found in the hash table
553 static int IS_CONFIG_ADDRESS(int address)
556 return address >= 0x300000 && address <= 0x300000d;
559 /*-----------------------------------------------------------------*/
560 /* pic16_allocDirReg - allocates register of given type */
561 /*-----------------------------------------------------------------*/
563 pic16_allocDirReg (operand *op )
569 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
570 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
574 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
576 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { // patch 13
577 if(pic16_debug_verbose) //
579 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, //
580 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname); //
585 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
586 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
589 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
590 debugLog(" %d const char\n",__LINE__);
591 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
592 // fprintf(stderr, " %d const char\n",__LINE__);
593 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
597 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
598 if (IS_CODE ( OP_SYM_ETYPE(op)) )
599 debugLog(" %d code space\n",__LINE__);
601 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
602 debugLog(" %d integral\n",__LINE__);
604 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
605 debugLog(" %d literal\n",__LINE__);
607 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
608 debugLog(" %d specifier\n",__LINE__);
610 debugAopGet(NULL, op);
613 if (IS_CODE ( OP_SYM_ETYPE(op)) )
616 /* First, search the hash table to see if there is a register with this name */
617 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
619 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
623 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
624 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
626 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
627 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
630 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
632 reg = pic16_dirregWithName(name);
637 int regtype = REG_GPR;
639 /* if this is at an absolute address, then get the address. */
640 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
641 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
642 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
645 /* Register wasn't found in hash, so let's create
646 * a new one and put it in the hash table AND in the
647 * dynDirectRegNames set */
648 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
649 if(pic16_debug_verbose)
650 fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
651 OP_SYMBOL(op)->name);
652 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
656 if(!IS_CONFIG_ADDRESS(address)) {
657 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
659 if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
661 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13
662 if(pic16_debug_verbose) //
664 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
665 OP_SYMBOL(op)->name); //
670 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
671 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
673 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
675 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
676 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
677 // reg->type = REG_SFR;
680 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
681 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
682 addSet(&pic16_dynDirectBitRegs, reg);
685 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
686 checkAddReg(&pic16_dynDirectRegs, reg);
690 debugLog (" -- %s is declared at address 0x30000x\n",name);
691 fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
697 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
699 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
701 /* work around for user defined registers in access bank */
702 if((reg->address < 0x80)
703 || (reg->address >= 0xf80))
706 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
712 /*-----------------------------------------------------------------*/
713 /* pic16_allocRegByName - allocates register of given type */
714 /*-----------------------------------------------------------------*/
716 pic16_allocRegByName (char *name, int size)
722 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
726 /* First, search the hash table to see if there is a register with this name */
727 reg = pic16_dirregWithName(name);
731 /* Register wasn't found in hash, so let's create
732 * a new one and put it in the hash table AND in the
733 * dynDirectRegNames set */
734 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
735 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
737 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
738 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
740 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
741 addSet(&pic16_dynDirectRegs, reg);
747 /*-----------------------------------------------------------------*/
748 /* RegWithIdx - returns pointer to register with index number */
749 /*-----------------------------------------------------------------*/
750 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
755 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
756 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
761 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
763 debugLog ("Found a Dynamic Register!\n");
766 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
767 debugLog ("Found a Direct Register!\n");
773 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
774 debugLog ("Found a Stack Register!\n");
779 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
780 debugLog ("Found a Processor Register!\n");
794 /*-----------------------------------------------------------------*/
795 /* pic16_regWithIdx - returns pointer to register with index number*/
796 /*-----------------------------------------------------------------*/
798 pic16_regWithIdx (int idx)
802 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
805 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
808 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
814 /*-----------------------------------------------------------------*/
815 /* pic16_regWithIdx - returns pointer to register with index number */
816 /*-----------------------------------------------------------------*/
818 pic16_allocWithIdx (int idx)
823 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
824 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
826 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
828 debugLog ("Found a Dynamic Register!\n");
829 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
830 debugLog ("Found a Stack Register!\n");
831 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
832 debugLog ("Found a Processor Register!\n");
833 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
834 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
835 debugLog ("Found an Internal Register!\n");
838 debugLog ("Dynamic Register not found\n");
841 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
842 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
843 "regWithIdx not found");
853 /*-----------------------------------------------------------------*/
854 /*-----------------------------------------------------------------*/
856 pic16_findFreeReg(short type)
863 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
865 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
869 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
881 /*-----------------------------------------------------------------*/
882 /* freeReg - frees a register */
883 /*-----------------------------------------------------------------*/
887 debugLog ("%s\n", __FUNCTION__);
888 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
893 /*-----------------------------------------------------------------*/
894 /* nFreeRegs - returns number of free registers */
895 /*-----------------------------------------------------------------*/
903 /* although I fixed the register allocation/freeing scheme
904 * the for loop below doesn't give valid results. I do not
905 * know why yet. -- VR 10-Jan-2003 */
910 /* dynamically allocate as many as we need and worry about
911 * fitting them into a PIC later */
913 debugLog ("%s\n", __FUNCTION__);
915 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
916 if((reg->type == type) && reg->isFree)nfr++;
918 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
922 /*-----------------------------------------------------------------*/
923 /* nfreeRegsType - free registers with type */
924 /*-----------------------------------------------------------------*/
926 nfreeRegsType (int type)
929 debugLog ("%s\n", __FUNCTION__);
932 if ((nfr = nFreeRegs (type)) == 0)
933 return nFreeRegs (REG_GPR);
936 return nFreeRegs (type);
939 static void writeSetUsedRegs(FILE *of, set *dRegs)
944 for (dReg = setFirstItem(dRegs) ; dReg ;
945 dReg = setNextItem(dRegs)) {
948 fprintf (of, "\t%s\n",dReg->name);
954 extern void pic16_groupRegistersInSection(set *regset);
956 extern void pic16_dump_equates(FILE *of, set *equs);
957 //extern void pic16_dump_map(void);
958 extern void pic16_dump_section(FILE *of, set *section, int fix);
959 extern void pic16_dump_int_registers(FILE *of, set *section);
960 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
962 static void packBits(set *bregs)
967 regs *relocbitfield=NULL;
973 for (regset = bregs ; regset ;
974 regset = regset->next) {
977 breg->isBitField = 1;
978 //fprintf(stderr,"bit reg: %s\n",breg->name);
981 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
983 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
984 breg->rIdx = breg->address & 7;
988 sprintf (buffer, "fbitfield%02x", breg->address);
989 //fprintf(stderr,"new bit field\n");
990 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
991 bitfield->isBitField = 1;
992 bitfield->isFixed = 1;
993 bitfield->address = breg->address;
994 addSet(&pic16_dynDirectRegs,bitfield);
995 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
997 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1000 breg->reg_alias = bitfield;
1004 if(!relocbitfield || bit_no >7) {
1007 sprintf (buffer, "bitfield%d", byte_no);
1008 //fprintf(stderr,"new relocatable bit field\n");
1009 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1010 relocbitfield->isBitField = 1;
1011 addSet(&pic16_dynDirectRegs,relocbitfield);
1012 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1016 breg->reg_alias = relocbitfield;
1017 breg->address = rDirectIdx; /* byte_no; */
1018 breg->rIdx = bit_no++;
1027 static void bitEQUs(FILE *of, set *bregs)
1029 regs *breg,*bytereg;
1032 //fprintf(stderr," %s\n",__FUNCTION__);
1033 for (breg = setFirstItem(bregs) ; breg ;
1034 breg = setNextItem(bregs)) {
1036 //fprintf(stderr,"bit reg: %s\n",breg->name);
1038 bytereg = breg->reg_alias;
1040 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1043 breg->rIdx & 0x0007);
1046 fprintf(stderr, "bit field is not assigned to a register\n");
1047 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1058 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1063 for (reg = setFirstItem(fregs) ; reg ;
1064 reg = setNextItem(fregs)) {
1066 if(!reg->isEmitted && reg->wasUsed) {
1068 if (reg->type != REG_SFR) {
1069 fprintf (of, "%s\tEQU\t0x%03x\n",
1075 fprintf (of, "%s\tEQU\t0x%03x\n",
1084 void pic16_writeUsedRegs(FILE *of)
1086 packBits(pic16_dynDirectBitRegs);
1088 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1089 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1090 pic16_groupRegistersInSection(pic16_dynStackRegs);
1091 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1092 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1093 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1097 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1098 pic16_assignFixedRegisters(pic16_dynStackRegs);
1099 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1100 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1102 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1103 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1104 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1105 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1106 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1109 // pic16_dump_map();
1110 // pic16_dump_cblock(of);
1113 pic16_dump_equates(of, pic16_equ_data);
1115 /* dump initialised data */
1116 pic16_dump_idata(of, idataSymSet);
1118 /* dump internal registers */
1119 pic16_dump_int_registers(of, pic16_int_regs);
1121 /* dump other variables */
1122 pic16_dump_section(of, pic16_rel_udata, 0);
1123 pic16_dump_section(of, pic16_fix_udata, 1);
1128 /*-----------------------------------------------------------------*/
1129 /* allDefsOutOfRange - all definitions are out of a range */
1130 /*-----------------------------------------------------------------*/
1132 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1136 debugLog ("%s\n", __FUNCTION__);
1140 for (i = 0; i < defs->size; i++)
1144 if (bitVectBitValue (defs, i) &&
1145 (ic = hTabItemWithKey (iCodehTab, i)) &&
1146 (ic->seq >= fseq && ic->seq <= toseq))
1156 /*-----------------------------------------------------------------*/
1157 /* computeSpillable - given a point find the spillable live ranges */
1158 /*-----------------------------------------------------------------*/
1160 computeSpillable (iCode * ic)
1164 debugLog ("%s\n", __FUNCTION__);
1165 /* spillable live ranges are those that are live at this
1166 point . the following categories need to be subtracted
1168 a) - those that are already spilt
1169 b) - if being used by this one
1170 c) - defined by this one */
1172 spillable = bitVectCopy (ic->rlive);
1174 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1176 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1177 bitVectUnSetBit (spillable, ic->defKey);
1178 spillable = bitVectIntersect (spillable, _G.regAssigned);
1183 /*-----------------------------------------------------------------*/
1184 /* noSpilLoc - return true if a variable has no spil location */
1185 /*-----------------------------------------------------------------*/
1187 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1189 debugLog ("%s\n", __FUNCTION__);
1190 return (sym->usl.spillLoc ? 0 : 1);
1193 /*-----------------------------------------------------------------*/
1194 /* hasSpilLoc - will return 1 if the symbol has spil location */
1195 /*-----------------------------------------------------------------*/
1197 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1199 debugLog ("%s\n", __FUNCTION__);
1200 return (sym->usl.spillLoc ? 1 : 0);
1203 /*-----------------------------------------------------------------*/
1204 /* directSpilLoc - will return 1 if the splilocation is in direct */
1205 /*-----------------------------------------------------------------*/
1207 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1209 debugLog ("%s\n", __FUNCTION__);
1210 if (sym->usl.spillLoc &&
1211 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1217 /*-----------------------------------------------------------------*/
1218 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1219 /* but is not used as a pointer */
1220 /*-----------------------------------------------------------------*/
1222 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1224 debugLog ("%s\n", __FUNCTION__);
1225 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1228 /*-----------------------------------------------------------------*/
1229 /* rematable - will return 1 if the remat flag is set */
1230 /*-----------------------------------------------------------------*/
1232 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1234 debugLog ("%s\n", __FUNCTION__);
1238 /*-----------------------------------------------------------------*/
1239 /* notUsedInRemaining - not used or defined in remain of the block */
1240 /*-----------------------------------------------------------------*/
1242 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1244 debugLog ("%s\n", __FUNCTION__);
1245 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1246 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1249 /*-----------------------------------------------------------------*/
1250 /* allLRs - return true for all */
1251 /*-----------------------------------------------------------------*/
1253 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1255 debugLog ("%s\n", __FUNCTION__);
1259 /*-----------------------------------------------------------------*/
1260 /* liveRangesWith - applies function to a given set of live range */
1261 /*-----------------------------------------------------------------*/
1263 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1264 eBBlock * ebp, iCode * ic)
1269 debugLog ("%s\n", __FUNCTION__);
1270 if (!lrs || !lrs->size)
1273 for (i = 1; i < lrs->size; i++)
1276 if (!bitVectBitValue (lrs, i))
1279 /* if we don't find it in the live range
1280 hash table we are in serious trouble */
1281 if (!(sym = hTabItemWithKey (liveRanges, i)))
1283 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1284 "liveRangesWith could not find liveRange");
1288 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1289 addSetHead (&rset, sym);
1296 /*-----------------------------------------------------------------*/
1297 /* leastUsedLR - given a set determines which is the least used */
1298 /*-----------------------------------------------------------------*/
1300 leastUsedLR (set * sset)
1302 symbol *sym = NULL, *lsym = NULL;
1304 debugLog ("%s\n", __FUNCTION__);
1305 sym = lsym = setFirstItem (sset);
1310 for (; lsym; lsym = setNextItem (sset))
1313 /* if usage is the same then prefer
1314 the spill the smaller of the two */
1315 if (lsym->used == sym->used)
1316 if (getSize (lsym->type) < getSize (sym->type))
1320 if (lsym->used < sym->used)
1325 setToNull ((void *) &sset);
1330 /*-----------------------------------------------------------------*/
1331 /* noOverLap - will iterate through the list looking for over lap */
1332 /*-----------------------------------------------------------------*/
1334 noOverLap (set * itmpStack, symbol * fsym)
1337 debugLog ("%s\n", __FUNCTION__);
1340 for (sym = setFirstItem (itmpStack); sym;
1341 sym = setNextItem (itmpStack))
1343 if (sym->liveTo > fsym->liveFrom)
1351 /*-----------------------------------------------------------------*/
1352 /* isFree - will return 1 if the a free spil location is found */
1353 /*-----------------------------------------------------------------*/
1358 V_ARG (symbol **, sloc);
1359 V_ARG (symbol *, fsym);
1361 debugLog ("%s\n", __FUNCTION__);
1362 /* if already found */
1366 /* if it is free && and the itmp assigned to
1367 this does not have any overlapping live ranges
1368 with the one currently being assigned and
1369 the size can be accomodated */
1371 noOverLap (sym->usl.itmpStack, fsym) &&
1372 getSize (sym->type) >= getSize (fsym->type))
1381 /*-----------------------------------------------------------------*/
1382 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1383 /*-----------------------------------------------------------------*/
1385 spillLRWithPtrReg (symbol * forSym)
1391 debugLog ("%s\n", __FUNCTION__);
1392 if (!_G.regAssigned ||
1393 bitVectIsZero (_G.regAssigned))
1396 r0 = pic16_regWithIdx (R0_IDX);
1397 r1 = pic16_regWithIdx (R1_IDX);
1399 /* for all live ranges */
1400 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1401 lrsym = hTabNextItem (liveRanges, &k))
1405 /* if no registers assigned to it or
1407 /* if it does not overlap with this then
1408 not need to spill it */
1410 if (lrsym->isspilt || !lrsym->nRegs ||
1411 (lrsym->liveTo < forSym->liveFrom))
1414 /* go thru the registers : if it is either
1415 r0 or r1 then spil it */
1416 for (j = 0; j < lrsym->nRegs; j++)
1417 if (lrsym->regs[j] == r0 ||
1418 lrsym->regs[j] == r1)
1427 /*-----------------------------------------------------------------*/
1428 /* createStackSpil - create a location on the stack to spil */
1429 /*-----------------------------------------------------------------*/
1431 createStackSpil (symbol * sym)
1433 symbol *sloc = NULL;
1434 int useXstack, model, noOverlay;
1436 char slocBuffer[30];
1437 debugLog ("%s\n", __FUNCTION__);
1439 /* first go try and find a free one that is already
1440 existing on the stack */
1441 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1443 /* found a free one : just update & return */
1444 sym->usl.spillLoc = sloc;
1447 addSetHead (&sloc->usl.itmpStack, sym);
1451 /* could not then have to create one , this is the hard part
1452 we need to allocate this on the stack : this is really a
1453 hack!! but cannot think of anything better at this time */
1455 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1457 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1458 __FILE__, __LINE__);
1462 sloc = newiTemp (slocBuffer);
1464 /* set the type to the spilling symbol */
1465 sloc->type = copyLinkChain (sym->type);
1466 sloc->etype = getSpec (sloc->type);
1467 SPEC_SCLS (sloc->etype) = S_DATA;
1468 SPEC_EXTR (sloc->etype) = 0;
1469 SPEC_STAT (sloc->etype) = 0;
1471 /* we don't allow it to be allocated`
1472 onto the external stack since : so we
1473 temporarily turn it off ; we also
1474 turn off memory model to prevent
1475 the spil from going to the external storage
1476 and turn off overlaying
1479 useXstack = options.useXstack;
1480 model = options.model;
1481 noOverlay = options.noOverlay;
1482 options.noOverlay = 1;
1483 options.model = options.useXstack = 0;
1487 options.useXstack = useXstack;
1488 options.model = model;
1489 options.noOverlay = noOverlay;
1490 sloc->isref = 1; /* to prevent compiler warning */
1492 /* if it is on the stack then update the stack */
1493 if (IN_STACK (sloc->etype))
1495 currFunc->stack += getSize (sloc->type);
1496 _G.stackExtend += getSize (sloc->type);
1499 _G.dataExtend += getSize (sloc->type);
1501 /* add it to the _G.stackSpil set */
1502 addSetHead (&_G.stackSpil, sloc);
1503 sym->usl.spillLoc = sloc;
1506 /* add it to the set of itempStack set
1507 of the spill location */
1508 addSetHead (&sloc->usl.itmpStack, sym);
1512 /*-----------------------------------------------------------------*/
1513 /* isSpiltOnStack - returns true if the spil location is on stack */
1514 /*-----------------------------------------------------------------*/
1516 isSpiltOnStack (symbol * sym)
1520 debugLog ("%s\n", __FUNCTION__);
1527 /* if (sym->_G.stackSpil) */
1530 if (!sym->usl.spillLoc)
1533 etype = getSpec (sym->usl.spillLoc->type);
1534 if (IN_STACK (etype))
1540 /*-----------------------------------------------------------------*/
1541 /* spillThis - spils a specific operand */
1542 /*-----------------------------------------------------------------*/
1544 spillThis (symbol * sym)
1547 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1549 /* if this is rematerializable or has a spillLocation
1550 we are okay, else we need to create a spillLocation
1552 if (!(sym->remat || sym->usl.spillLoc))
1553 createStackSpil (sym);
1556 /* mark it has spilt & put it in the spilt set */
1558 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1560 bitVectUnSetBit (_G.regAssigned, sym->key);
1562 for (i = 0; i < sym->nRegs; i++)
1566 freeReg (sym->regs[i]);
1567 sym->regs[i] = NULL;
1570 /* if spilt on stack then free up r0 & r1
1571 if they could have been assigned to some
1573 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1576 spillLRWithPtrReg (sym);
1579 if (sym->usl.spillLoc && !sym->remat)
1580 sym->usl.spillLoc->allocreq = 1;
1584 /*-----------------------------------------------------------------*/
1585 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1586 /*-----------------------------------------------------------------*/
1588 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1590 bitVect *lrcs = NULL;
1594 debugLog ("%s\n", __FUNCTION__);
1595 /* get the spillable live ranges */
1596 lrcs = computeSpillable (ic);
1598 /* get all live ranges that are rematerizable */
1599 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1602 /* return the least used of these */
1603 return leastUsedLR (selectS);
1606 /* get live ranges with spillLocations in direct space */
1607 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1609 sym = leastUsedLR (selectS);
1610 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1611 sym->usl.spillLoc->rname :
1612 sym->usl.spillLoc->name));
1614 /* mark it as allocation required */
1615 sym->usl.spillLoc->allocreq = 1;
1619 /* if the symbol is local to the block then */
1620 if (forSym->liveTo < ebp->lSeq)
1623 /* check if there are any live ranges allocated
1624 to registers that are not used in this block */
1625 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1627 sym = leastUsedLR (selectS);
1628 /* if this is not rematerializable */
1637 /* check if there are any live ranges that not
1638 used in the remainder of the block */
1639 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1641 sym = leastUsedLR (selectS);
1644 sym->remainSpil = 1;
1651 /* find live ranges with spillocation && not used as pointers */
1652 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1655 sym = leastUsedLR (selectS);
1656 /* mark this as allocation required */
1657 sym->usl.spillLoc->allocreq = 1;
1661 /* find live ranges with spillocation */
1662 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1665 sym = leastUsedLR (selectS);
1666 sym->usl.spillLoc->allocreq = 1;
1670 /* couldn't find then we need to create a spil
1671 location on the stack , for which one? the least
1673 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1676 /* return a created spil location */
1677 sym = createStackSpil (leastUsedLR (selectS));
1678 sym->usl.spillLoc->allocreq = 1;
1682 /* this is an extreme situation we will spill
1683 this one : happens very rarely but it does happen */
1689 /*-----------------------------------------------------------------*/
1690 /* spilSomething - spil some variable & mark registers as free */
1691 /*-----------------------------------------------------------------*/
1693 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1698 debugLog ("%s\n", __FUNCTION__);
1699 /* get something we can spil */
1700 ssym = selectSpil (ic, ebp, forSym);
1702 /* mark it as spilt */
1704 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1706 /* mark it as not register assigned &
1707 take it away from the set */
1708 bitVectUnSetBit (_G.regAssigned, ssym->key);
1710 /* mark the registers as free */
1711 for (i = 0; i < ssym->nRegs; i++)
1713 freeReg (ssym->regs[i]);
1715 /* if spilt on stack then free up r0 & r1
1716 if they could have been assigned to as gprs */
1717 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1720 spillLRWithPtrReg (ssym);
1723 /* if this was a block level spil then insert push & pop
1724 at the start & end of block respectively */
1725 if (ssym->blockSpil)
1727 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1728 /* add push to the start of the block */
1729 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1730 ebp->sch->next : ebp->sch));
1731 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1732 /* add pop to the end of the block */
1733 addiCodeToeBBlock (ebp, nic, NULL);
1736 /* if spilt because not used in the remainder of the
1737 block then add a push before this instruction and
1738 a pop at the end of the block */
1739 if (ssym->remainSpil)
1742 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1743 /* add push just before this instruction */
1744 addiCodeToeBBlock (ebp, nic, ic);
1746 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1747 /* add pop to the end of the block */
1748 addiCodeToeBBlock (ebp, nic, NULL);
1757 /*-----------------------------------------------------------------*/
1758 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1759 /*-----------------------------------------------------------------*/
1761 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1766 debugLog ("%s\n", __FUNCTION__);
1768 /* try for a ptr type */
1769 if ((reg = allocReg (REG_PTR)))
1772 /* try for gpr type */
1773 if ((reg = allocReg (REG_GPR)))
1776 /* we have to spil */
1777 if (!spilSomething (ic, ebp, sym))
1780 /* make sure partially assigned registers aren't reused */
1781 for (j=0; j<=sym->nRegs; j++)
1783 sym->regs[j]->isFree = 0;
1785 /* this looks like an infinite loop but
1786 in really selectSpil will abort */
1790 /*-----------------------------------------------------------------*/
1791 /* getRegGpr - will try for GPR if not spil */
1792 /*-----------------------------------------------------------------*/
1794 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1799 debugLog ("%s\n", __FUNCTION__);
1801 /* try for gpr type */
1802 if ((reg = allocReg (REG_GPR)))
1805 if (!pic16_ptrRegReq)
1806 if ((reg = allocReg (REG_PTR)))
1809 /* we have to spil */
1810 if (!spilSomething (ic, ebp, sym))
1813 /* make sure partially assigned registers aren't reused */
1814 for (j=0; j<=sym->nRegs; j++)
1816 sym->regs[j]->isFree = 0;
1818 /* this looks like an infinite loop but
1819 in really selectSpil will abort */
1823 /*-----------------------------------------------------------------*/
1824 /* symHasReg - symbol has a given register */
1825 /*-----------------------------------------------------------------*/
1827 symHasReg (symbol * sym, regs * reg)
1831 debugLog ("%s\n", __FUNCTION__);
1832 for (i = 0; i < sym->nRegs; i++)
1833 if (sym->regs[i] == reg)
1839 /*-----------------------------------------------------------------*/
1840 /* deassignLRs - check the live to and if they have registers & are */
1841 /* not spilt then free up the registers */
1842 /*-----------------------------------------------------------------*/
1844 deassignLRs (iCode * ic, eBBlock * ebp)
1850 debugLog ("%s\n", __FUNCTION__);
1851 for (sym = hTabFirstItem (liveRanges, &k); sym;
1852 sym = hTabNextItem (liveRanges, &k))
1855 symbol *psym = NULL;
1856 /* if it does not end here */
1857 if (sym->liveTo > ic->seq)
1860 /* if it was spilt on stack then we can
1861 mark the stack spil location as free */
1866 sym->usl.spillLoc->isFree = 1;
1872 if (!bitVectBitValue (_G.regAssigned, sym->key))
1875 /* special case check if this is an IFX &
1876 the privious one was a pop and the
1877 previous one was not spilt then keep track
1879 if (ic->op == IFX && ic->prev &&
1880 ic->prev->op == IPOP &&
1881 !ic->prev->parmPush &&
1882 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1883 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1889 bitVectUnSetBit (_G.regAssigned, sym->key);
1891 /* if the result of this one needs registers
1892 and does not have it then assign it right
1894 if (IC_RESULT (ic) &&
1895 !(SKIP_IC2 (ic) || /* not a special icode */
1896 ic->op == JUMPTABLE ||
1901 POINTER_SET (ic)) &&
1902 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1903 result->liveTo > ic->seq && /* and will live beyond this */
1904 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1905 result->regType == sym->regType && /* same register types */
1906 result->nRegs && /* which needs registers */
1907 !result->isspilt && /* and does not already have them */
1909 !bitVectBitValue (_G.regAssigned, result->key) &&
1910 /* the number of free regs + number of regs in this LR
1911 can accomodate the what result Needs */
1912 ((nfreeRegsType (result->regType) +
1913 sym->nRegs) >= result->nRegs)
1917 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1919 result->regs[i] = sym->regs[i];
1921 result->regs[i] = getRegGpr (ic, ebp, result);
1923 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1927 /* free the remaining */
1928 for (; i < sym->nRegs; i++)
1932 if (!symHasReg (psym, sym->regs[i]))
1933 freeReg (sym->regs[i]);
1936 freeReg (sym->regs[i]);
1943 /*-----------------------------------------------------------------*/
1944 /* reassignLR - reassign this to registers */
1945 /*-----------------------------------------------------------------*/
1947 reassignLR (operand * op)
1949 symbol *sym = OP_SYMBOL (op);
1952 debugLog ("%s\n", __FUNCTION__);
1953 /* not spilt any more */
1954 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1955 bitVectUnSetBit (_G.spiltSet, sym->key);
1957 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1961 for (i = 0; i < sym->nRegs; i++)
1962 sym->regs[i]->isFree = 0;
1965 /*-----------------------------------------------------------------*/
1966 /* willCauseSpill - determines if allocating will cause a spill */
1967 /*-----------------------------------------------------------------*/
1969 willCauseSpill (int nr, int rt)
1971 debugLog ("%s\n", __FUNCTION__);
1972 /* first check if there are any avlb registers
1973 of te type required */
1976 /* special case for pointer type
1977 if pointer type not avlb then
1978 check for type gpr */
1979 if (nFreeRegs (rt) >= nr)
1981 if (nFreeRegs (REG_GPR) >= nr)
1986 if (pic16_ptrRegReq)
1988 if (nFreeRegs (rt) >= nr)
1993 if (nFreeRegs (REG_PTR) +
1994 nFreeRegs (REG_GPR) >= nr)
1999 debugLog (" ... yep it will (cause a spill)\n");
2000 /* it will cause a spil */
2004 /*-----------------------------------------------------------------*/
2005 /* positionRegs - the allocator can allocate same registers to res- */
2006 /* ult and operand, if this happens make sure they are in the same */
2007 /* position as the operand otherwise chaos results */
2008 /*-----------------------------------------------------------------*/
2010 positionRegs (symbol * result, symbol * opsym, int lineno)
2012 int count = min (result->nRegs, opsym->nRegs);
2013 int i, j = 0, shared = 0;
2015 debugLog ("%s\n", __FUNCTION__);
2016 /* if the result has been spilt then cannot share */
2021 /* first make sure that they actually share */
2022 for (i = 0; i < count; i++)
2024 for (j = 0; j < count; j++)
2026 if (result->regs[i] == opsym->regs[j] && i != j)
2036 regs *tmp = result->regs[i];
2037 result->regs[i] = result->regs[j];
2038 result->regs[j] = tmp;
2043 /*------------------------------------------------------------------*/
2044 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2045 /* it should either have registers or have beed spilled. Otherwise, */
2046 /* there was an uninitialized variable, so just spill this to get */
2047 /* the operand in a valid state. */
2048 /*------------------------------------------------------------------*/
2050 verifyRegsAssigned (operand *op, iCode * ic)
2055 if (!IS_ITEMP (op)) return;
2057 sym = OP_SYMBOL (op);
2058 if (sym->isspilt) return;
2059 if (!sym->nRegs) return;
2060 if (sym->regs[0]) return;
2062 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2063 sym->prereqv ? sym->prereqv->name : sym->name);
2068 /*-----------------------------------------------------------------*/
2069 /* serialRegAssign - serially allocate registers to the variables */
2070 /*-----------------------------------------------------------------*/
2072 serialRegAssign (eBBlock ** ebbs, int count)
2076 debugLog ("%s\n", __FUNCTION__);
2077 /* for all blocks */
2078 for (i = 0; i < count; i++)
2083 if (ebbs[i]->noPath &&
2084 (ebbs[i]->entryLabel != entryLabel &&
2085 ebbs[i]->entryLabel != returnLabel))
2088 /* of all instructions do */
2089 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2092 debugLog (" op: %s\n", decodeOp (ic->op));
2094 /* if this is an ipop that means some live
2095 range will have to be assigned again */
2097 reassignLR (IC_LEFT (ic));
2099 /* if result is present && is a true symbol */
2100 if (IC_RESULT (ic) && ic->op != IFX &&
2101 IS_TRUE_SYMOP (IC_RESULT (ic)))
2102 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2104 /* take away registers from live
2105 ranges that end at this instruction */
2106 deassignLRs (ic, ebbs[i]);
2108 /* some don't need registers */
2109 if (SKIP_IC2 (ic) ||
2110 ic->op == JUMPTABLE ||
2114 (IC_RESULT (ic) && POINTER_SET (ic)))
2117 /* now we need to allocate registers
2118 only for the result */
2121 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2127 /* if it does not need or is spilt
2128 or is already assigned to registers
2129 or will not live beyond this instructions */
2132 bitVectBitValue (_G.regAssigned, sym->key) ||
2133 sym->liveTo <= ic->seq)
2136 /* if some liverange has been spilt at the block level
2137 and this one live beyond this block then spil this
2139 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2144 /* if trying to allocate this will cause
2145 a spill and there is nothing to spill
2146 or this one is rematerializable then
2148 willCS = willCauseSpill (sym->nRegs, sym->regType);
2149 spillable = computeSpillable (ic);
2151 (willCS && bitVectIsZero (spillable)))
2159 /* if it has a spillocation & is used less than
2160 all other live ranges then spill this */
2162 if (sym->usl.spillLoc) {
2163 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2164 allLRs, ebbs[i], ic));
2165 if (leastUsed && leastUsed->used > sym->used) {
2170 /* if none of the liveRanges have a spillLocation then better
2171 to spill this one than anything else already assigned to registers */
2172 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2173 /* if this is local to this block then we might find a block spil */
2174 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2182 if (ic->op == RECEIVE)
2183 debugLog ("When I get clever, I'll optimize the receive logic\n");
2185 /* if we need ptr regs for the right side
2187 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2188 <= (unsigned) PTRSIZE)
2193 /* else we assign registers to it */
2194 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2196 debugLog (" %d - \n", __LINE__);
2198 bitVectDebugOn(_G.regAssigned, debugF);
2200 for (j = 0; j < sym->nRegs; j++)
2202 if (sym->regType == REG_PTR)
2203 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2205 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2207 /* if the allocation falied which means
2208 this was spilt then break */
2212 debugLog (" %d - \n", __LINE__);
2214 /* if it shares registers with operands make sure
2215 that they are in the same position */
2216 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2217 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2218 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2219 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2220 /* do the same for the right operand */
2221 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2222 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2223 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2224 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2226 debugLog (" %d - \n", __LINE__);
2229 debugLog (" %d - \n", __LINE__);
2238 /* Check for and fix any problems with uninitialized operands */
2239 for (i = 0; i < count; i++)
2243 if (ebbs[i]->noPath &&
2244 (ebbs[i]->entryLabel != entryLabel &&
2245 ebbs[i]->entryLabel != returnLabel))
2248 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2255 verifyRegsAssigned (IC_COND (ic), ic);
2259 if (ic->op == JUMPTABLE)
2261 verifyRegsAssigned (IC_JTCOND (ic), ic);
2265 verifyRegsAssigned (IC_RESULT (ic), ic);
2266 verifyRegsAssigned (IC_LEFT (ic), ic);
2267 verifyRegsAssigned (IC_RIGHT (ic), ic);
2273 /*-----------------------------------------------------------------*/
2274 /* rUmaskForOp :- returns register mask for an operand */
2275 /*-----------------------------------------------------------------*/
2277 rUmaskForOp (operand * op)
2283 debugLog ("%s\n", __FUNCTION__);
2284 /* only temporaries are assigned registers */
2288 sym = OP_SYMBOL (op);
2290 /* if spilt or no registers assigned to it
2292 if (sym->isspilt || !sym->nRegs)
2295 rumask = newBitVect (pic16_nRegs);
2297 for (j = 0; j < sym->nRegs; j++)
2299 rumask = bitVectSetBit (rumask,
2300 sym->regs[j]->rIdx);
2306 /*-----------------------------------------------------------------*/
2307 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2308 /*-----------------------------------------------------------------*/
2310 regsUsedIniCode (iCode * ic)
2312 bitVect *rmask = newBitVect (pic16_nRegs);
2314 debugLog ("%s\n", __FUNCTION__);
2315 /* do the special cases first */
2318 rmask = bitVectUnion (rmask,
2319 rUmaskForOp (IC_COND (ic)));
2323 /* for the jumptable */
2324 if (ic->op == JUMPTABLE)
2326 rmask = bitVectUnion (rmask,
2327 rUmaskForOp (IC_JTCOND (ic)));
2332 /* of all other cases */
2334 rmask = bitVectUnion (rmask,
2335 rUmaskForOp (IC_LEFT (ic)));
2339 rmask = bitVectUnion (rmask,
2340 rUmaskForOp (IC_RIGHT (ic)));
2343 rmask = bitVectUnion (rmask,
2344 rUmaskForOp (IC_RESULT (ic)));
2350 /*-----------------------------------------------------------------*/
2351 /* createRegMask - for each instruction will determine the regsUsed */
2352 /*-----------------------------------------------------------------*/
2354 createRegMask (eBBlock ** ebbs, int count)
2358 debugLog ("%s\n", __FUNCTION__);
2359 /* for all blocks */
2360 for (i = 0; i < count; i++)
2364 if (ebbs[i]->noPath &&
2365 (ebbs[i]->entryLabel != entryLabel &&
2366 ebbs[i]->entryLabel != returnLabel))
2369 /* for all instructions */
2370 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2375 if (SKIP_IC2 (ic) || !ic->rlive)
2378 /* first mark the registers used in this
2380 ic->rUsed = regsUsedIniCode (ic);
2381 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2383 /* now create the register mask for those
2384 registers that are in use : this is a
2385 super set of ic->rUsed */
2386 ic->rMask = newBitVect (pic16_nRegs + 1);
2388 /* for all live Ranges alive at this point */
2389 for (j = 1; j < ic->rlive->size; j++)
2394 /* if not alive then continue */
2395 if (!bitVectBitValue (ic->rlive, j))
2398 /* find the live range we are interested in */
2399 if (!(sym = hTabItemWithKey (liveRanges, j)))
2401 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2402 "createRegMask cannot find live range");
2406 /* if no register assigned to it */
2407 if (!sym->nRegs || sym->isspilt)
2410 /* for all the registers allocated to it */
2411 for (k = 0; k < sym->nRegs; k++)
2414 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2420 /*-----------------------------------------------------------------*/
2421 /* rematStr - returns the rematerialized string for a remat var */
2422 /*-----------------------------------------------------------------*/
2424 rematStr (symbol * sym)
2427 iCode *ic = sym->rematiCode;
2428 symbol *psym = NULL;
2430 debugLog ("%s\n", __FUNCTION__);
2432 //printf ("%s\n", s);
2434 /* if plus or minus print the right hand side */
2436 if (ic->op == '+' || ic->op == '-') {
2438 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2440 sprintf (s, "(%s %c 0x%04x)",
2441 OP_SYMBOL (IC_LEFT (ric))->rname,
2443 (int) operandLitValue (IC_RIGHT (ic)));
2446 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2448 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2449 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2454 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2455 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2457 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2462 /*-----------------------------------------------------------------*/
2463 /* rematStr - returns the rematerialized string for a remat var */
2464 /*-----------------------------------------------------------------*/
2466 rematStr (symbol * sym)
2469 iCode *ic = sym->rematiCode;
2471 debugLog ("%s\n", __FUNCTION__);
2476 /* if plus or minus print the right hand side */
2478 if (ic->op == '+' || ic->op == '-') {
2479 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2482 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2486 if (ic->op == '+' || ic->op == '-')
2488 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2489 sprintf (s, "(%s %c 0x%04x)",
2490 OP_SYMBOL (IC_LEFT (ric))->rname,
2492 (int) operandLitValue (IC_RIGHT (ic)));
2495 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2497 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2501 /* we reached the end */
2502 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2506 printf ("%s\n", buffer);
2511 /*-----------------------------------------------------------------*/
2512 /* regTypeNum - computes the type & number of registers required */
2513 /*-----------------------------------------------------------------*/
2521 debugLog ("%s\n", __FUNCTION__);
2522 /* for each live range do */
2523 for (sym = hTabFirstItem (liveRanges, &k); sym;
2524 sym = hTabNextItem (liveRanges, &k)) {
2526 debugLog (" %d - %s\n", __LINE__, sym->rname);
2527 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2529 /* if used zero times then no registers needed */
2530 if ((sym->liveTo - sym->liveFrom) == 0)
2534 /* if the live range is a temporary */
2537 debugLog (" %d - itemp register\n", __LINE__);
2539 /* if the type is marked as a conditional */
2540 if (sym->regType == REG_CND)
2543 /* if used in return only then we don't
2545 if (sym->ruonly || sym->accuse) {
2546 if (IS_AGGREGATE (sym->type) || sym->isptr)
2547 sym->type = aggrToPtr (sym->type, FALSE);
2548 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2553 /* if the symbol has only one definition &
2554 that definition is a get_pointer and the
2555 pointer we are getting is rematerializable and
2558 if (bitVectnBitsOn (sym->defs) == 1 &&
2559 (ic = hTabItemWithKey (iCodehTab,
2560 bitVectFirstBit (sym->defs))) &&
2563 !IS_BITVAR (sym->etype)) {
2566 debugLog (" %d - \n", __LINE__);
2568 /* if remat in data space */
2569 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2570 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2572 /* create a psuedo symbol & force a spil */
2573 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2574 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2575 psym->type = sym->type;
2576 psym->etype = sym->etype;
2577 strcpy (psym->rname, psym->name);
2579 sym->usl.spillLoc = psym;
2583 /* if in data space or idata space then try to
2584 allocate pointer register */
2588 /* if not then we require registers */
2589 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2590 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2591 getSize (sym->type));
2595 if(IS_PTR_CONST (sym->type)) {
2597 if(IS_CODEPTR (sym->type)) {
2599 // what IS this ???? (HJD)
2600 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2601 sym->nRegs = 3; // patch 14
2604 if (sym->nRegs > 4) {
2605 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2606 printTypeChain (sym->type, stderr);
2607 fprintf (stderr, "\n");
2610 /* determine the type of register required */
2611 if (sym->nRegs == 1 &&
2612 IS_PTR (sym->type) &&
2614 sym->regType = REG_PTR;
2616 sym->regType = REG_GPR;
2619 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2623 /* for the first run we don't provide */
2624 /* registers for true symbols we will */
2625 /* see how things go */
2630 static DEFSETFUNC (markRegFree)
2632 ((regs *)item)->isFree = 1;
2637 DEFSETFUNC (pic16_deallocReg)
2639 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2640 ((regs *)item)->isFree = 1;
2641 ((regs *)item)->wasUsed = 0;
2645 /*-----------------------------------------------------------------*/
2646 /* freeAllRegs - mark all registers as free */
2647 /*-----------------------------------------------------------------*/
2649 pic16_freeAllRegs ()
2651 debugLog ("%s\n", __FUNCTION__);
2653 applyToSet(pic16_dynAllocRegs,markRegFree);
2654 applyToSet(pic16_dynStackRegs,markRegFree);
2657 /*-----------------------------------------------------------------*/
2658 /*-----------------------------------------------------------------*/
2660 pic16_deallocateAllRegs ()
2662 debugLog ("%s\n", __FUNCTION__);
2664 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2668 /*-----------------------------------------------------------------*/
2669 /* deallocStackSpil - this will set the stack pointer back */
2670 /*-----------------------------------------------------------------*/
2672 DEFSETFUNC (deallocStackSpil)
2676 debugLog ("%s\n", __FUNCTION__);
2681 /*-----------------------------------------------------------------*/
2682 /* farSpacePackable - returns the packable icode for far variables */
2683 /*-----------------------------------------------------------------*/
2685 farSpacePackable (iCode * ic)
2689 debugLog ("%s\n", __FUNCTION__);
2690 /* go thru till we find a definition for the
2691 symbol on the right */
2692 for (dic = ic->prev; dic; dic = dic->prev)
2695 /* if the definition is a call then no */
2696 if ((dic->op == CALL || dic->op == PCALL) &&
2697 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2702 /* if shift by unknown amount then not */
2703 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2704 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2707 /* if pointer get and size > 1 */
2708 if (POINTER_GET (dic) &&
2709 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2712 if (POINTER_SET (dic) &&
2713 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2716 /* if any three is a true symbol in far space */
2717 if (IC_RESULT (dic) &&
2718 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2719 isOperandInFarSpace (IC_RESULT (dic)))
2722 if (IC_RIGHT (dic) &&
2723 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2724 isOperandInFarSpace (IC_RIGHT (dic)) &&
2725 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2728 if (IC_LEFT (dic) &&
2729 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2730 isOperandInFarSpace (IC_LEFT (dic)) &&
2731 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2734 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2736 if ((dic->op == LEFT_OP ||
2737 dic->op == RIGHT_OP ||
2739 IS_OP_LITERAL (IC_RIGHT (dic)))
2749 /*-----------------------------------------------------------------*/
2750 /* packRegsForAssign - register reduction for assignment */
2751 /*-----------------------------------------------------------------*/
2753 packRegsForAssign (iCode * ic, eBBlock * ebp)
2758 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2759 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2760 debugAopGet (" result:", IC_RESULT (ic));
2761 debugAopGet (" left:", IC_LEFT (ic));
2762 debugAopGet (" right:", IC_RIGHT (ic));
2764 /* if this is at an absolute address, then get the address. */
2765 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2766 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2767 debugLog (" %d - found config word declaration\n", __LINE__);
2768 if(IS_VALOP(IC_RIGHT(ic))) {
2769 debugLog (" setting config word to %x\n",
2770 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2771 fprintf(stderr, " setting config word to %x\n",
2772 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2773 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2774 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2778 debugLog(" %d\n", __LINE__);
2780 /* remove the assignment from the iCode chain. */
2782 remiCodeFromeBBlock (ebp, ic);
2783 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2784 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2790 debugLog(" %d - actuall processing\n", __LINE__ );
2792 if (!IS_ITEMP (IC_RESULT (ic))) {
2793 pic16_allocDirReg(IC_RESULT (ic));
2794 debugLog (" %d - result is not temp\n", __LINE__);
2798 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2799 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2800 pic16_allocDirReg(IC_LEFT (ic));
2804 /* See BUGLOG0001 - VR */
2806 if (!IS_ITEMP (IC_RIGHT (ic))) {
2807 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2808 pic16_allocDirReg(IC_RIGHT (ic));
2813 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2814 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2816 debugLog (" %d - not packing - right side fails \n", __LINE__);
2820 /* if the true symbol is defined in far space or on stack
2821 then we should not since this will increase register pressure */
2822 if (isOperandInFarSpace (IC_RESULT (ic)))
2824 if ((dic = farSpacePackable (ic)))
2831 /* find the definition of iTempNN scanning backwards if we find a
2832 a use of the true symbol before we find the definition then
2834 for (dic = ic->prev; dic; dic = dic->prev)
2837 /* if there is a function call and this is
2838 a parameter & not my parameter then don't pack it */
2839 if ((dic->op == CALL || dic->op == PCALL) &&
2840 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2841 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2843 debugLog (" %d - \n", __LINE__);
2852 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2855 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2856 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2857 debugAopGet(" result is ", IC_RESULT(dic));
2859 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2860 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2861 debugAopGet(" left is ", IC_LEFT(dic));
2863 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2864 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2865 debugAopGet(" right is ", IC_RIGHT(dic));
2869 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2870 IS_OP_VOLATILE (IC_RESULT (dic)))
2872 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2878 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2879 IS_OP_VOLATILE (IC_RIGHT(dic)))
2881 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2888 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2889 IS_OP_VOLATILE (IC_LEFT(dic)))
2891 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2899 if( IS_SYMOP( IC_RESULT(dic)) &&
2900 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2902 debugLog (" %d - result is bitfield\n", __LINE__);
2908 if (IS_SYMOP (IC_RESULT (dic)) &&
2909 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2911 /* A previous result was assigned to the same register - we'll our definition */
2912 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2913 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2914 if (POINTER_SET (dic))
2920 if (IS_SYMOP (IC_RIGHT (dic)) &&
2921 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2922 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2924 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2929 if (IS_SYMOP (IC_LEFT (dic)) &&
2930 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2931 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2933 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2938 if (POINTER_SET (dic) &&
2939 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2941 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2949 return 0; /* did not find */
2952 /* This code is taken from the hc08 port. Do not know
2953 * if it fits for pic16, but I leave it here just in case */
2955 /* if assignment then check that right is not a bit */
2956 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2957 sym_link *etype = operandType (IC_RIGHT (dic));
2959 if (IS_BITFIELD (etype)) {
2960 /* if result is a bit too then it's ok */
2961 etype = operandType (IC_RESULT (dic));
2962 if (!IS_BITFIELD (etype)) {
2963 debugLog(" %d bitfields\n");
2970 /* if the result is on stack or iaccess then it must be
2971 the same atleast one of the operands */
2972 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2973 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2976 /* the operation has only one symbol
2977 operator then we can pack */
2978 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2979 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2982 if (!((IC_LEFT (dic) &&
2983 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2985 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2989 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2990 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2991 /* found the definition */
2992 /* replace the result with the result of */
2993 /* this assignment and remove this assignment */
2994 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2995 IC_RESULT (dic) = IC_RESULT (ic);
2997 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2999 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3001 /* delete from liverange table also
3002 delete from all the points inbetween and the new
3004 for (sic = dic; sic != ic; sic = sic->next)
3006 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3007 if (IS_ITEMP (IC_RESULT (dic)))
3008 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3011 remiCodeFromeBBlock (ebp, ic);
3012 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3014 debugLog(" %d\n", __LINE__ );
3015 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3016 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3024 #define NO_packRegsForAccUse
3025 #define NO_packRegsForSupport
3026 #define NO_packRegsForOneuse
3027 #define NO_cast_peep
3032 #ifndef NO_packRegsForSupport
3033 /*-----------------------------------------------------------------*/
3034 /* findAssignToSym : scanning backwards looks for first assig found */
3035 /*-----------------------------------------------------------------*/
3037 findAssignToSym (operand * op, iCode * ic)
3041 debugLog ("%s\n", __FUNCTION__);
3042 for (dic = ic->prev; dic; dic = dic->prev)
3045 /* if definition by assignment */
3046 if (dic->op == '=' &&
3047 !POINTER_SET (dic) &&
3048 IC_RESULT (dic)->key == op->key
3049 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3053 /* we are interested only if defined in far space */
3054 /* or in stack space in case of + & - */
3056 /* if assigned to a non-symbol then return
3058 if (!IS_SYMOP (IC_RIGHT (dic)))
3061 /* if the symbol is in far space then
3063 if (isOperandInFarSpace (IC_RIGHT (dic)))
3066 /* for + & - operations make sure that
3067 if it is on the stack it is the same
3068 as one of the three operands */
3069 if ((ic->op == '+' || ic->op == '-') &&
3070 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3073 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3074 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3075 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3083 /* if we find an usage then we cannot delete it */
3084 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3087 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3090 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3094 /* now make sure that the right side of dic
3095 is not defined between ic & dic */
3098 iCode *sic = dic->next;
3100 for (; sic != ic; sic = sic->next)
3101 if (IC_RESULT (sic) &&
3102 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3113 #ifndef NO_packRegsForSupport
3114 /*-----------------------------------------------------------------*/
3115 /* packRegsForSupport :- reduce some registers for support calls */
3116 /*-----------------------------------------------------------------*/
3118 packRegsForSupport (iCode * ic, eBBlock * ebp)
3122 debugLog ("%s\n", __FUNCTION__);
3123 /* for the left & right operand :- look to see if the
3124 left was assigned a true symbol in far space in that
3125 case replace them */
3126 if (IS_ITEMP (IC_LEFT (ic)) &&
3127 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3129 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3135 debugAopGet ("removing left:", IC_LEFT (ic));
3137 /* found it we need to remove it from the
3139 for (sic = dic; sic != ic; sic = sic->next)
3140 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3142 IC_LEFT (ic)->operand.symOperand =
3143 IC_RIGHT (dic)->operand.symOperand;
3144 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3145 remiCodeFromeBBlock (ebp, dic);
3146 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3147 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3151 /* do the same for the right operand */
3154 IS_ITEMP (IC_RIGHT (ic)) &&
3155 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3157 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3163 /* if this is a subtraction & the result
3164 is a true symbol in far space then don't pack */
3165 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3167 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3168 if (IN_FARSPACE (SPEC_OCLS (etype)))
3172 debugAopGet ("removing right:", IC_RIGHT (ic));
3174 /* found it we need to remove it from the
3176 for (sic = dic; sic != ic; sic = sic->next)
3177 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3179 IC_RIGHT (ic)->operand.symOperand =
3180 IC_RIGHT (dic)->operand.symOperand;
3181 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3183 remiCodeFromeBBlock (ebp, dic);
3184 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3185 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3194 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3196 #ifndef NO_packRegsForOneuse
3197 /*-----------------------------------------------------------------*/
3198 /* packRegsForOneuse : - will reduce some registers for single Use */
3199 /*-----------------------------------------------------------------*/
3201 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3206 debugLog ("%s\n", __FUNCTION__);
3207 /* if returning a literal then do nothing */
3211 /* only upto 2 bytes since we cannot predict
3212 the usage of b, & acc */
3213 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3218 /* this routine will mark the a symbol as used in one
3219 instruction use only && if the definition is local
3220 (ie. within the basic block) && has only one definition &&
3221 that definition is either a return value from a
3222 function or does not contain any variables in
3224 uses = bitVectCopy (OP_USES (op));
3225 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3226 if (!bitVectIsZero (uses)) /* has other uses */
3229 /* if it has only one defintion */
3230 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3231 return NULL; /* has more than one definition */
3233 /* get that definition */
3235 hTabItemWithKey (iCodehTab,
3236 bitVectFirstBit (OP_DEFS (op)))))
3239 /* found the definition now check if it is local */
3240 if (dic->seq < ebp->fSeq ||
3241 dic->seq > ebp->lSeq)
3242 return NULL; /* non-local */
3244 /* now check if it is the return from
3246 if (dic->op == CALL || dic->op == PCALL)
3248 if (ic->op != SEND && ic->op != RETURN &&
3249 !POINTER_SET(ic) && !POINTER_GET(ic))
3251 OP_SYMBOL (op)->ruonly = 1;
3258 /* otherwise check that the definition does
3259 not contain any symbols in far space */
3260 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3261 isOperandInFarSpace (IC_RIGHT (dic)) ||
3262 IS_OP_RUONLY (IC_LEFT (ic)) ||
3263 IS_OP_RUONLY (IC_RIGHT (ic)))
3268 /* if pointer set then make sure the pointer
3270 if (POINTER_SET (dic) &&
3271 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3274 if (POINTER_GET (dic) &&
3275 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3280 /* also make sure the intervenening instructions
3281 don't have any thing in far space */
3282 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3285 /* if there is an intervening function call then no */
3286 if (dic->op == CALL || dic->op == PCALL)
3288 /* if pointer set then make sure the pointer
3290 if (POINTER_SET (dic) &&
3291 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3294 if (POINTER_GET (dic) &&
3295 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3298 /* if address of & the result is remat then okay */
3299 if (dic->op == ADDRESS_OF &&
3300 OP_SYMBOL (IC_RESULT (dic))->remat)
3303 /* if operand has size of three or more & this
3304 operation is a '*','/' or '%' then 'b' may
3306 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3307 getSize (operandType (op)) >= 3)
3310 /* if left or right or result is in far space */
3311 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3312 isOperandInFarSpace (IC_RIGHT (dic)) ||
3313 isOperandInFarSpace (IC_RESULT (dic)) ||
3314 IS_OP_RUONLY (IC_LEFT (dic)) ||
3315 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3316 IS_OP_RUONLY (IC_RESULT (dic)))
3322 OP_SYMBOL (op)->ruonly = 1;
3329 /*-----------------------------------------------------------------*/
3330 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3331 /*-----------------------------------------------------------------*/
3333 isBitwiseOptimizable (iCode * ic)
3335 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3336 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3338 debugLog ("%s\n", __FUNCTION__);
3339 /* bitwise operations are considered optimizable
3340 under the following conditions (Jean-Louis VERN)
3352 if (IS_LITERAL (rtype) ||
3353 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3360 #ifndef NO_packRegsForAccUse
3362 /*-----------------------------------------------------------------*/
3363 /* packRegsForAccUse - pack registers for acc use */
3364 /*-----------------------------------------------------------------*/
3366 packRegsForAccUse (iCode * ic)
3370 debugLog ("%s\n", __FUNCTION__);
3372 /* if this is an aggregate, e.g. a one byte char array */
3373 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3376 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3378 /* if + or - then it has to be one byte result */
3379 if ((ic->op == '+' || ic->op == '-')
3380 && getSize (operandType (IC_RESULT (ic))) > 1)
3383 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3384 /* if shift operation make sure right side is not a literal */
3385 if (ic->op == RIGHT_OP &&
3386 (isOperandLiteral (IC_RIGHT (ic)) ||
3387 getSize (operandType (IC_RESULT (ic))) > 1))
3390 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3391 if (ic->op == LEFT_OP &&
3392 (isOperandLiteral (IC_RIGHT (ic)) ||
3393 getSize (operandType (IC_RESULT (ic))) > 1))
3396 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3397 if (IS_BITWISE_OP (ic) &&
3398 getSize (operandType (IC_RESULT (ic))) > 1)
3402 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3403 /* has only one definition */
3404 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3407 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3408 /* has only one use */
3409 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3412 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3413 /* and the usage immediately follows this iCode */
3414 if (!(uic = hTabItemWithKey (iCodehTab,
3415 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3418 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3419 if (ic->next != uic)
3422 /* if it is a conditional branch then we definitely can */
3426 if (uic->op == JUMPTABLE)
3429 /* if the usage is not is an assignment
3430 or an arithmetic / bitwise / shift operation then not */
3431 if (POINTER_SET (uic) &&
3432 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3435 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3436 if (uic->op != '=' &&
3437 !IS_ARITHMETIC_OP (uic) &&
3438 !IS_BITWISE_OP (uic) &&
3439 uic->op != LEFT_OP &&
3440 uic->op != RIGHT_OP)
3443 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3444 /* if used in ^ operation then make sure right is not a
3446 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3449 /* if shift operation make sure right side is not a literal */
3450 if (uic->op == RIGHT_OP &&
3451 (isOperandLiteral (IC_RIGHT (uic)) ||
3452 getSize (operandType (IC_RESULT (uic))) > 1))
3455 if (uic->op == LEFT_OP &&
3456 (isOperandLiteral (IC_RIGHT (uic)) ||
3457 getSize (operandType (IC_RESULT (uic))) > 1))
3460 /* make sure that the result of this icode is not on the
3461 stack, since acc is used to compute stack offset */
3462 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3463 OP_SYMBOL (IC_RESULT (uic))->onStack)
3466 /* if either one of them in far space then we cannot */
3467 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3468 isOperandInFarSpace (IC_LEFT (uic))) ||
3469 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3470 isOperandInFarSpace (IC_RIGHT (uic))))
3473 /* if the usage has only one operand then we can */
3474 if (IC_LEFT (uic) == NULL ||
3475 IC_RIGHT (uic) == NULL)
3478 /* make sure this is on the left side if not
3479 a '+' since '+' is commutative */
3480 if (ic->op != '+' &&
3481 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3485 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3486 /* if one of them is a literal then we can */
3487 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3488 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3489 (getSize (operandType (IC_RESULT (uic))) <= 1))
3491 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3496 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3497 /* if the other one is not on stack then we can */
3498 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3499 (IS_ITEMP (IC_RIGHT (uic)) ||
3500 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3501 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3504 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3505 (IS_ITEMP (IC_LEFT (uic)) ||
3506 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3507 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3513 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3514 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3521 /*-----------------------------------------------------------------*/
3522 /* packForPush - hueristics to reduce iCode for pushing */
3523 /*-----------------------------------------------------------------*/
3525 packForReceive (iCode * ic, eBBlock * ebp)
3529 debugLog ("%s\n", __FUNCTION__);
3530 debugAopGet (" result:", IC_RESULT (ic));
3531 debugAopGet (" left:", IC_LEFT (ic));
3532 debugAopGet (" right:", IC_RIGHT (ic));
3537 for (dic = ic->next; dic; dic = dic->next)
3542 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3543 debugLog (" used on left\n");
3544 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3545 debugLog (" used on right\n");
3546 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3547 debugLog (" used on result\n");
3549 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3550 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3555 debugLog (" hey we can remove this unnecessary assign\n");
3557 /*-----------------------------------------------------------------*/
3558 /* packForPush - hueristics to reduce iCode for pushing */
3559 /*-----------------------------------------------------------------*/
3561 packForPush (iCode * ic, eBBlock * ebp)
3565 debugLog ("%s\n", __FUNCTION__);
3566 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3569 /* must have only definition & one usage */
3570 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3571 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3574 /* find the definition */
3575 if (!(dic = hTabItemWithKey (iCodehTab,
3576 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3579 if (dic->op != '=' || POINTER_SET (dic))
3582 /* we now we know that it has one & only one def & use
3583 and the that the definition is an assignment */
3584 IC_LEFT (ic) = IC_RIGHT (dic);
3586 remiCodeFromeBBlock (ebp, dic);
3587 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3588 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3591 static void printSymType(char * str, sym_link *sl)
3593 if(!pic16_ralloc_debug)return;
3595 debugLog (" %s Symbol type: ",str);
3596 printTypeChain( sl, debugF);
3600 /*-----------------------------------------------------------------*/
3601 /* some debug code to print the symbol S_TYPE. Note that
3602 * the function checkSClass in src/SDCCsymt.c dinks with
3603 * the S_TYPE in ways the PIC port doesn't fully like...*/
3604 /*-----------------------------------------------------------------*/
3605 static void isData(sym_link *sl)
3609 if(!pic16_ralloc_debug)return;
3616 for ( ; sl; sl=sl->next) {
3618 switch (SPEC_SCLS(sl)) {
3619 case S_DATA: fprintf (of, "data "); break;
3620 case S_XDATA: fprintf (of, "xdata "); break;
3621 case S_SFR: fprintf (of, "sfr "); break;
3622 case S_SBIT: fprintf (of, "sbit "); break;
3623 case S_CODE: fprintf (of, "code "); break;
3624 case S_IDATA: fprintf (of, "idata "); break;
3625 case S_PDATA: fprintf (of, "pdata "); break;
3626 case S_LITERAL: fprintf (of, "literal "); break;
3627 case S_STACK: fprintf (of, "stack "); break;
3628 case S_XSTACK: fprintf (of, "xstack "); break;
3629 case S_BIT: fprintf (of, "bit "); break;
3630 case S_EEPROM: fprintf (of, "eeprom "); break;
3639 /*--------------------------------------------------------------------*/
3640 /* pic16_packRegisters - does some transformations to reduce */
3641 /* register pressure */
3643 /*--------------------------------------------------------------------*/
3645 pic16_packRegisters (eBBlock * ebp)
3650 debugLog ("%s\n", __FUNCTION__);
3656 /* look for assignments of the form */
3657 /* iTempNN = TRueSym (someoperation) SomeOperand */
3659 /* TrueSym := iTempNN:1 */
3660 for (ic = ebp->sch; ic; ic = ic->next)
3662 // debugLog("%d\n", __LINE__);
3663 /* find assignment of the form TrueSym := iTempNN:1 */
3664 /* see BUGLOG0001 for workaround with the CAST - VR */
3665 if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3666 // if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3667 change += packRegsForAssign (ic, ebp);
3671 if (POINTER_SET (ic))
3672 debugLog ("pointer is set\n");
3673 debugAopGet (" result:", IC_RESULT (ic));
3674 debugAopGet (" left:", IC_LEFT (ic));
3675 debugAopGet (" right:", IC_RIGHT (ic));
3684 for (ic = ebp->sch; ic; ic = ic->next) {
3686 if(IS_SYMOP ( IC_LEFT(ic))) {
3687 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3689 debugAopGet ("x left:", IC_LEFT (ic));
3691 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3693 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3695 debugLog (" is a pointer\n");
3697 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3698 debugLog (" is a ptr\n");
3700 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3701 debugLog (" is volatile\n");
3705 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3706 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3707 pic16_allocDirReg(IC_LEFT (ic));
3710 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3713 if(IS_SYMOP ( IC_RIGHT(ic))) {
3714 debugAopGet (" right:", IC_RIGHT (ic));
3715 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3718 if(IS_SYMOP ( IC_RESULT(ic))) {
3719 debugAopGet (" result:", IC_RESULT (ic));
3720 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3723 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3724 debugAopGet (" right:", IC_RIGHT (ic));
3725 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3726 // pic16_allocDirReg(IC_RIGHT(ic));
3729 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3730 debugAopGet (" result:", IC_RESULT (ic));
3731 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3732 // pic16_allocDirReg(IC_RESULT(ic));
3736 if (POINTER_SET (ic))
3737 debugLog (" %d - Pointer set\n", __LINE__);
3740 /* if this is an itemp & result of a address of a true sym
3741 then mark this as rematerialisable */
3742 if (ic->op == ADDRESS_OF &&
3743 IS_ITEMP (IC_RESULT (ic)) &&
3744 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3745 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3746 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3749 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3751 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3752 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3753 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3757 /* if straight assignment then carry remat flag if
3758 this is the only definition */
3759 if (ic->op == '=' &&
3760 !POINTER_SET (ic) &&
3761 IS_SYMOP (IC_RIGHT (ic)) &&
3762 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3763 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3765 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3767 OP_SYMBOL (IC_RESULT (ic))->remat =
3768 OP_SYMBOL (IC_RIGHT (ic))->remat;
3769 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3770 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3773 /* if this is a +/- operation with a rematerizable
3774 then mark this as rematerializable as well */
3775 if ((ic->op == '+' || ic->op == '-') &&
3776 (IS_SYMOP (IC_LEFT (ic)) &&
3777 IS_ITEMP (IC_RESULT (ic)) &&
3778 OP_SYMBOL (IC_LEFT (ic))->remat &&
3779 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3780 IS_OP_LITERAL (IC_RIGHT (ic))))
3782 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3784 operandLitValue (IC_RIGHT (ic));
3785 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3786 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3787 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3790 /* mark the pointer usages */
3791 if (POINTER_SET (ic))
3793 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3794 debugLog (" marking as a pointer (set) =>");
3795 debugAopGet (" result:", IC_RESULT (ic));
3797 if (POINTER_GET (ic))
3799 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3800 debugLog (" marking as a pointer (get) =>");
3801 debugAopGet (" left:", IC_LEFT (ic));
3804 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3808 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3809 /* if we are using a symbol on the stack
3810 then we should say pic16_ptrRegReq */
3811 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3812 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3813 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3814 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3815 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3816 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3820 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3821 if (IS_SYMOP (IC_LEFT (ic)))
3822 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3823 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3824 if (IS_SYMOP (IC_RIGHT (ic)))
3825 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3826 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3827 if (IS_SYMOP (IC_RESULT (ic)))
3828 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3829 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3832 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3836 /* if the condition of an if instruction
3837 is defined in the previous instruction then
3838 mark the itemp as a conditional */
3839 if ((IS_CONDITIONAL (ic) ||
3840 ((ic->op == BITWISEAND ||
3843 isBitwiseOptimizable (ic))) &&
3844 ic->next && ic->next->op == IFX &&
3845 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3846 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3849 debugLog (" %d\n", __LINE__);
3850 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3854 debugLog(" %d\n", __LINE__);
3856 #ifndef NO_packRegsForSupport
3857 /* reduce for support function calls */
3858 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3859 packRegsForSupport (ic, ebp);
3862 /* if a parameter is passed, it's in W, so we may not
3863 need to place a copy in a register */
3864 if (ic->op == RECEIVE)
3865 packForReceive (ic, ebp);
3867 #ifndef NO_packRegsForOneuse
3868 /* some cases the redundant moves can
3869 can be eliminated for return statements */
3870 if ((ic->op == RETURN || ic->op == SEND) &&
3871 !isOperandInFarSpace (IC_LEFT (ic)) &&
3873 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3876 #ifndef NO_packRegsForOneuse
3877 /* if pointer set & left has a size more than
3878 one and right is not in far space */
3879 if (POINTER_SET (ic) &&
3880 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3881 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3882 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3883 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3885 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3888 #ifndef NO_packRegsForOneuse
3889 /* if pointer get */
3890 if (POINTER_GET (ic) &&
3891 !isOperandInFarSpace (IC_RESULT (ic)) &&
3892 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3893 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3894 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3896 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3897 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3900 #ifndef NO_cast_peep
3901 /* if this is cast for intergral promotion then
3902 check if only use of the definition of the
3903 operand being casted/ if yes then replace
3904 the result of that arithmetic operation with
3905 this result and get rid of the cast */
3906 if (ic->op == CAST) {
3908 sym_link *fromType = operandType (IC_RIGHT (ic));
3909 sym_link *toType = operandType (IC_LEFT (ic));
3911 debugLog (" %d - casting\n", __LINE__);
3913 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3914 getSize (fromType) != getSize (toType)) {
3917 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3920 if (IS_ARITHMETIC_OP (dic)) {
3921 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3923 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3924 IC_RESULT (dic) = IC_RESULT (ic);
3925 remiCodeFromeBBlock (ebp, ic);
3926 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3927 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3928 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3932 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3936 /* if the type from and type to are the same
3937 then if this is the only use then packit */
3938 if (compareType (operandType (IC_RIGHT (ic)),
3939 operandType (IC_LEFT (ic))) == 1) {
3941 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3944 debugLog(" %d\n", __LINE__);
3946 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3947 IC_RESULT (dic) = IC_RESULT (ic);
3948 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3949 remiCodeFromeBBlock (ebp, ic);
3950 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3951 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3959 iTempNN := (some variable in farspace) V1
3964 if (ic->op == IPUSH)
3966 packForPush (ic, ebp);
3970 #ifndef NO_packRegsForAccUse
3971 /* pack registers for accumulator use, when the
3972 result of an arithmetic or bit wise operation
3973 has only one use, that use is immediately following
3974 the defintion and the using iCode has only one
3975 operand or has two operands but one is literal &
3976 the result of that operation is not on stack then
3977 we can leave the result of this operation in acc:b
3979 if ((IS_ARITHMETIC_OP (ic)
3981 || IS_BITWISE_OP (ic)
3983 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3986 IS_ITEMP (IC_RESULT (ic)) &&
3987 getSize (operandType (IC_RESULT (ic))) <= 1)
3989 packRegsForAccUse (ic);
3996 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4000 if (!pic16_ralloc_debug || !debugF)
4003 for (i = 0; i < count; i++)
4005 fprintf (debugF, "\n----------------------------------------------------------------\n");
4006 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4007 ebbs[i]->entryLabel->name,
4010 ebbs[i]->isLastInLoop);
4011 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4016 fprintf (debugF, "visited %d : hasFcall = %d\n",
4020 fprintf (debugF, "\ndefines bitVector :");
4021 bitVectDebugOn (ebbs[i]->defSet, debugF);
4022 fprintf (debugF, "\nlocal defines bitVector :");
4023 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4024 fprintf (debugF, "\npointers Set bitvector :");
4025 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4026 fprintf (debugF, "\nin pointers Set bitvector :");
4027 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4028 fprintf (debugF, "\ninDefs Set bitvector :");
4029 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4030 fprintf (debugF, "\noutDefs Set bitvector :");
4031 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4032 fprintf (debugF, "\nusesDefs Set bitvector :");
4033 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4034 fprintf (debugF, "\n----------------------------------------------------------------\n");
4035 printiCChain (ebbs[i]->sch, debugF);
4038 /*-----------------------------------------------------------------*/
4039 /* pic16_assignRegisters - assigns registers to each live range as need */
4040 /*-----------------------------------------------------------------*/
4042 pic16_assignRegisters (eBBlock ** ebbs, int count)
4047 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4048 debugLog ("\nebbs before optimizing:\n");
4049 dumpEbbsToDebug (ebbs, count);
4051 setToNull ((void *) &_G.funcrUsed);
4052 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4055 /* change assignments this will remove some
4056 live ranges reducing some register pressure */
4057 for (i = 0; i < count; i++)
4058 pic16_packRegisters (ebbs[i]);
4065 debugLog("dir registers allocated so far:\n");
4066 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4069 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4070 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4071 reg = hTabNextItem(dynDirectRegNames, &hkey);
4076 /* liveranges probably changed by register packing
4077 so we compute them again */
4078 recomputeLiveRanges (ebbs, count);
4080 if (options.dump_pack)
4081 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4083 /* first determine for each live range the number of
4084 registers & the type of registers required for each */
4087 /* and serially allocate registers */
4088 serialRegAssign (ebbs, count);
4090 // debugLog ("ebbs after serialRegAssign:\n");
4091 // dumpEbbsToDebug (ebbs, count);
4094 //pic16_freeAllRegs();
4096 /* if stack was extended then tell the user */
4099 /* werror(W_TOOMANY_SPILS,"stack", */
4100 /* _G.stackExtend,currFunc->name,""); */
4106 /* werror(W_TOOMANY_SPILS,"data space", */
4107 /* _G.dataExtend,currFunc->name,""); */
4111 /* after that create the register mask
4112 for each of the instruction */
4113 createRegMask (ebbs, count);
4115 /* redo that offsets for stacked automatic variables */
4116 redoStackOffsets ();
4118 if (options.dump_rassgn)
4119 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4121 /* now get back the chain */
4122 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4124 debugLog ("ebbs after optimizing:\n");
4125 dumpEbbsToDebug (ebbs, count);
4130 /* free up any _G.stackSpil locations allocated */
4131 applyToSet (_G.stackSpil, deallocStackSpil);
4133 setToNull ((void *) &_G.stackSpil);
4134 setToNull ((void *) &_G.spiltSet);
4135 /* mark all registers as free */
4136 pic16_freeAllRegs ();
4138 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");