1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
40 /*-----------------------------------------------------------------*/
41 /* At this point we start getting processor specific although */
42 /* some routines are non-processor specific & can be reused when */
43 /* targetting other processors. The decision for this will have */
44 /* to be made on a routine by routine basis */
45 /* routines used to pack registers are most definitely not reusable */
46 /* since the pack the registers depending strictly on the MCU */
47 /*-----------------------------------------------------------------*/
49 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
50 extern void genpic16Code (iCode *);
60 bitVect *funcrUsed; /* registers used in a function */
66 /* Shared with gen.c */
67 int pic16_ptrRegReq; /* one byte pointer register required */
70 set *pic16_dynAllocRegs=NULL;
71 set *pic16_dynStackRegs=NULL;
72 set *pic16_dynProcessorRegs=NULL;
73 set *pic16_dynDirectRegs=NULL;
74 set *pic16_dynDirectBitRegs=NULL;
75 set *pic16_dynInternalRegs=NULL;
77 static hTab *dynDirectRegNames= NULL;
78 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
80 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
81 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
82 set *pic16_equ_data=NULL; /* registers used by equates */
83 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
85 set *pic16_builtin_functions=NULL;
87 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
88 static int rDirectIdx=0;
90 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
92 int pic16_Gstack_base_addr=0; /* The starting address of registers that
93 * are used to pass and return parameters */
98 static void spillThis (symbol *);
99 int pic16_ralloc_debug = 0;
100 static FILE *debugF = NULL;
101 /*-----------------------------------------------------------------*/
102 /* debugLog - open a file for debugging information */
103 /*-----------------------------------------------------------------*/
104 //static void debugLog(char *inst,char *fmt, ...)
106 debugLog (char *fmt,...)
108 static int append = 0; // First time through, open the file without append.
111 //char *bufferP=buffer;
114 if (!pic16_ralloc_debug || !dstFileName)
120 /* create the file name */
121 strcpy (buffer, dstFileName);
122 strcat (buffer, ".d");
124 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
126 werror (E_FILE_OPEN_ERR, buffer);
129 append = 1; // Next time debubLog is called, we'll append the debug info
135 vsprintf (buffer, fmt, ap);
137 fprintf (debugF, "%s", buffer);
139 while (isspace(*bufferP)) bufferP++;
141 if (bufferP && *bufferP)
142 lineCurr = (lineCurr ?
143 connectLine(lineCurr,newLineNode(lb)) :
144 (lineHead = newLineNode(lb)));
145 lineCurr->isInline = _G.inLine;
146 lineCurr->isDebug = _G.debugLine;
155 if(!pic16_ralloc_debug)return;
158 fputc ('\n', debugF);
160 /*-----------------------------------------------------------------*/
161 /* debugLogClose - closes the debug log file (if opened) */
162 /*-----------------------------------------------------------------*/
172 #define AOP(op) op->aop
175 debugAopGet (char *str, operand * op)
177 if(!pic16_ralloc_debug)return NULL;
182 printOperand (op, debugF);
189 decodeOp (unsigned int op)
191 if (op < 128 && op > ' ') {
192 buffer[0] = (op & 0xff);
198 case IDENTIFIER: return "IDENTIFIER";
199 case TYPE_NAME: return "TYPE_NAME";
200 case CONSTANT: return "CONSTANT";
201 case STRING_LITERAL: return "STRING_LITERAL";
202 case SIZEOF: return "SIZEOF";
203 case PTR_OP: return "PTR_OP";
204 case INC_OP: return "INC_OP";
205 case DEC_OP: return "DEC_OP";
206 case LEFT_OP: return "LEFT_OP";
207 case RIGHT_OP: return "RIGHT_OP";
208 case LE_OP: return "LE_OP";
209 case GE_OP: return "GE_OP";
210 case EQ_OP: return "EQ_OP";
211 case NE_OP: return "NE_OP";
212 case AND_OP: return "AND_OP";
213 case OR_OP: return "OR_OP";
214 case MUL_ASSIGN: return "MUL_ASSIGN";
215 case DIV_ASSIGN: return "DIV_ASSIGN";
216 case MOD_ASSIGN: return "MOD_ASSIGN";
217 case ADD_ASSIGN: return "ADD_ASSIGN";
218 case SUB_ASSIGN: return "SUB_ASSIGN";
219 case LEFT_ASSIGN: return "LEFT_ASSIGN";
220 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
221 case AND_ASSIGN: return "AND_ASSIGN";
222 case XOR_ASSIGN: return "XOR_ASSIGN";
223 case OR_ASSIGN: return "OR_ASSIGN";
224 case TYPEDEF: return "TYPEDEF";
225 case EXTERN: return "EXTERN";
226 case STATIC: return "STATIC";
227 case AUTO: return "AUTO";
228 case REGISTER: return "REGISTER";
229 case CODE: return "CODE";
230 case EEPROM: return "EEPROM";
231 case INTERRUPT: return "INTERRUPT";
232 case SFR: return "SFR";
233 case AT: return "AT";
234 case SBIT: return "SBIT";
235 case REENTRANT: return "REENTRANT";
236 case USING: return "USING";
237 case XDATA: return "XDATA";
238 case DATA: return "DATA";
239 case IDATA: return "IDATA";
240 case PDATA: return "PDATA";
241 case VAR_ARGS: return "VAR_ARGS";
242 case CRITICAL: return "CRITICAL";
243 case NONBANKED: return "NONBANKED";
244 case BANKED: return "BANKED";
245 case CHAR: return "CHAR";
246 case SHORT: return "SHORT";
247 case INT: return "INT";
248 case LONG: return "LONG";
249 case SIGNED: return "SIGNED";
250 case UNSIGNED: return "UNSIGNED";
251 case FLOAT: return "FLOAT";
252 case DOUBLE: return "DOUBLE";
253 case CONST: return "CONST";
254 case VOLATILE: return "VOLATILE";
255 case VOID: return "VOID";
256 case BIT: return "BIT";
257 case STRUCT: return "STRUCT";
258 case UNION: return "UNION";
259 case ENUM: return "ENUM";
260 case ELIPSIS: return "ELIPSIS";
261 case RANGE: return "RANGE";
262 case FAR: return "FAR";
263 case CASE: return "CASE";
264 case DEFAULT: return "DEFAULT";
265 case IF: return "IF";
266 case ELSE: return "ELSE";
267 case SWITCH: return "SWITCH";
268 case WHILE: return "WHILE";
269 case DO: return "DO";
270 case FOR: return "FOR";
271 case GOTO: return "GOTO";
272 case CONTINUE: return "CONTINUE";
273 case BREAK: return "BREAK";
274 case RETURN: return "RETURN";
275 case INLINEASM: return "INLINEASM";
276 case IFX: return "IFX";
277 case ADDRESS_OF: return "ADDRESS_OF";
278 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
279 case SPIL: return "SPIL";
280 case UNSPIL: return "UNSPIL";
281 case GETHBIT: return "GETHBIT";
282 case BITWISEAND: return "BITWISEAND";
283 case UNARYMINUS: return "UNARYMINUS";
284 case IPUSH: return "IPUSH";
285 case IPOP: return "IPOP";
286 case PCALL: return "PCALL";
287 case ENDFUNCTION: return "ENDFUNCTION";
288 case JUMPTABLE: return "JUMPTABLE";
289 case RRC: return "RRC";
290 case RLC: return "RLC";
291 case CAST: return "CAST";
292 case CALL: return "CALL";
293 case PARAM: return "PARAM ";
294 case NULLOP: return "NULLOP";
295 case BLOCK: return "BLOCK";
296 case LABEL: return "LABEL";
297 case RECEIVE: return "RECEIVE";
298 case SEND: return "SEND";
300 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
304 /*-----------------------------------------------------------------*/
305 /*-----------------------------------------------------------------*/
307 debugLogRegType (short type)
309 if(!pic16_ralloc_debug)return NULL;
311 case REG_GPR: return "REG_GPR";
312 case REG_PTR: return "REG_PTR";
313 case REG_CND: return "REG_CND";
315 sprintf (buffer, "unknown reg type %d", type);
320 /*-----------------------------------------------------------------*/
321 /*-----------------------------------------------------------------*/
322 static int regname2key(char const *name)
331 key += (*name++) + 1;
335 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
339 /*-----------------------------------------------------------------*/
340 /* newReg - allocate and init memory for a new register */
341 /*-----------------------------------------------------------------*/
342 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
347 dReg = Safe_calloc(1,sizeof(regs));
349 dReg->pc_type = pc_type;
352 dReg->name = Safe_strdup(name);
354 sprintf(buffer,"r0x%02X", dReg->rIdx);
357 dReg->name = Safe_strdup(buffer);
365 if(type == REG_SFR) {
367 dReg->address = rIdx;
368 dReg->accessBank = 1;
372 dReg->accessBank = 0;
375 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
379 dReg->reg_alias = NULL;
380 dReg->reglives.usedpFlows = newSet();
381 dReg->reglives.assignedpFlows = newSet();
384 if(!(type == REG_SFR && alias == 0x80))
385 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
390 /*-----------------------------------------------------------------*/
391 /* regWithIdx - Search through a set of registers that matches idx */
392 /*-----------------------------------------------------------------*/
394 regWithIdx (set *dRegs, int idx, int fixed)
398 for (dReg = setFirstItem(dRegs) ; dReg ;
399 dReg = setNextItem(dRegs)) {
401 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
409 /*-----------------------------------------------------------------*/
410 /* regFindFree - Search for a free register in a set of registers */
411 /*-----------------------------------------------------------------*/
413 regFindFree (set *dRegs)
417 for (dReg = setFirstItem(dRegs) ; dReg ;
418 dReg = setNextItem(dRegs)) {
420 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
421 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
430 /*-----------------------------------------------------------------*/
431 /* pic16_initStack - allocate registers for a pseudo stack */
432 /*-----------------------------------------------------------------*/
433 void pic16_initStack(int base_address, int size)
438 pic16_Gstack_base_addr = base_address;
439 //fprintf(stderr,"initStack");
441 for(i = 0; i<size; i++)
442 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
445 /*-----------------------------------------------------------------*
446 *-----------------------------------------------------------------*/
448 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
450 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
452 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
454 reg->wasUsed = 0; // we do not know if they are going to be used at all
455 reg->accessBank = 1; // implicit add access Bank
457 return addSet(&pic16_dynProcessorRegs, reg);
460 /*-----------------------------------------------------------------*
461 *-----------------------------------------------------------------*/
464 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
466 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
468 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
472 return addSet(&pic16_dynInternalRegs,reg);
477 /*-----------------------------------------------------------------*/
478 /* allocReg - allocates register of given type */
479 /*-----------------------------------------------------------------*/
481 allocReg (short type)
486 if(dynrIdx > pic16_nRegs)
490 /* try to reuse some unused registers */
491 reg = regFindFree( pic16_dynAllocRegs );
494 // fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
498 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
499 // addSet(&pic16_dynAllocRegs, reg);
502 addSet(&pic16_dynAllocRegs, reg);
506 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
508 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
509 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
512 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
513 reg->isLocal = 1; /* this is a local frame register */
517 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
518 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
521 return (reg); // addSet(&pic16_dynAllocRegs,reg);
526 /*-----------------------------------------------------------------*/
527 /* pic16_dirregWithName - search for register by name */
528 /*-----------------------------------------------------------------*/
530 pic16_dirregWithName (char *name)
538 /* hash the name to get a key */
540 hkey = regname2key(name);
542 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
544 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
548 if(STRCASECMP(reg->name, name) == 0) {
552 reg = hTabNextItemWK (dynDirectRegNames);
556 return NULL; // name wasn't found in the hash table
560 /*-----------------------------------------------------------------*/
561 /* pic16_allocDirReg - allocates register of given type */
562 /*-----------------------------------------------------------------*/
564 pic16_allocDirReg (operand *op )
570 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
571 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
575 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
577 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { // patch 13
578 if(pic16_debug_verbose) //
580 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, //
581 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname); //
586 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
587 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
590 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
591 debugLog(" %d const char\n",__LINE__);
592 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
593 // fprintf(stderr, " %d const char\n",__LINE__);
594 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
598 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
599 if (IS_CODE ( OP_SYM_ETYPE(op)) )
600 debugLog(" %d code space\n",__LINE__);
602 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
603 debugLog(" %d integral\n",__LINE__);
605 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
606 debugLog(" %d literal\n",__LINE__);
608 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
609 debugLog(" %d specifier\n",__LINE__);
611 debugAopGet(NULL, op);
614 if (IS_CODE ( OP_SYM_ETYPE(op)) )
617 /* First, search the hash table to see if there is a register with this name */
618 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
620 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
624 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
625 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
627 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
628 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
631 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
633 reg = pic16_dirregWithName(name);
638 int regtype = REG_GPR;
640 /* if this is at an absolute address, then get the address. */
641 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
642 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
643 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
646 /* Register wasn't found in hash, so let's create
647 * a new one and put it in the hash table AND in the
648 * dynDirectRegNames set */
649 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
651 // if(pic16_debug_verbose)
652 // fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
653 // OP_SYMBOL(op)->name);
655 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
659 if(1) { //!PIC16_IS_CONFIG_ADDRESS(address))
660 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
662 /* this is an error, why added? -- VR */
663 // if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
665 if(OP_SYMBOL(op)->onStack) {
666 // fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
667 OP_SYMBOL(op)->onStack = 0;
668 SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
672 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13
673 if(pic16_debug_verbose) //
675 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
676 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
677 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
678 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
679 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
680 IN_STACK( OP_SYM_ETYPE(op)),
681 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
683 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
684 OP_SYMBOL(op)->name); //
688 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
689 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
692 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
693 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
694 // reg->type = REG_SFR;
697 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
698 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
699 addSet(&pic16_dynDirectBitRegs, reg);
702 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
703 // addSet(&pic16_dynDirectRegs, reg);
704 checkAddReg(&pic16_dynDirectRegs, reg);
708 debugLog (" -- %s is declared at address 0x30000x\n",name);
714 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
716 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
718 /* work around for user defined registers in access bank */
719 if((reg->address>= 0x00 && reg->address < 0x80)
720 || (reg->address >= 0xf80 && reg->address <= 0xfff))
723 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
729 /*-----------------------------------------------------------------*/
730 /* pic16_allocRegByName - allocates register of given type */
731 /*-----------------------------------------------------------------*/
733 pic16_allocRegByName (char *name, int size, operand *op)
739 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
743 /* First, search the hash table to see if there is a register with this name */
744 reg = pic16_dirregWithName(name);
748 /* Register wasn't found in hash, so let's create
749 * a new one and put it in the hash table AND in the
750 * dynDirectRegNames set */
752 // fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
754 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
756 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
757 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
759 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
760 addSet(&pic16_dynDirectRegs, reg);
766 /*-----------------------------------------------------------------*/
767 /* RegWithIdx - returns pointer to register with index number */
768 /*-----------------------------------------------------------------*/
769 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
774 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
775 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
780 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
782 debugLog ("Found a Dynamic Register!\n");
785 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
786 debugLog ("Found a Direct Register!\n");
792 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
793 debugLog ("Found a Stack Register!\n");
798 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
799 debugLog ("Found a Processor Register!\n");
813 /*-----------------------------------------------------------------*/
814 /* pic16_regWithIdx - returns pointer to register with index number*/
815 /*-----------------------------------------------------------------*/
817 pic16_regWithIdx (int idx)
821 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
824 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
827 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
833 /*-----------------------------------------------------------------*/
834 /* pic16_regWithIdx - returns pointer to register with index number */
835 /*-----------------------------------------------------------------*/
837 pic16_allocWithIdx (int idx)
842 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
843 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
845 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
847 debugLog ("Found a Dynamic Register!\n");
848 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
849 debugLog ("Found a Stack Register!\n");
850 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
851 debugLog ("Found a Processor Register!\n");
852 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
853 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
854 debugLog ("Found an Internal Register!\n");
857 debugLog ("Dynamic Register not found\n");
860 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
861 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
862 "regWithIdx not found");
872 /*-----------------------------------------------------------------*/
873 /*-----------------------------------------------------------------*/
875 pic16_findFreeReg(short type)
882 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
884 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
888 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
900 /*-----------------------------------------------------------------*/
901 /* freeReg - frees a register */
902 /*-----------------------------------------------------------------*/
906 debugLog ("%s\n", __FUNCTION__);
907 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
912 /*-----------------------------------------------------------------*/
913 /* nFreeRegs - returns number of free registers */
914 /*-----------------------------------------------------------------*/
922 /* although I fixed the register allocation/freeing scheme
923 * the for loop below doesn't give valid results. I do not
924 * know why yet. -- VR 10-Jan-2003 */
929 /* dynamically allocate as many as we need and worry about
930 * fitting them into a PIC later */
932 debugLog ("%s\n", __FUNCTION__);
934 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
935 if((reg->type == type) && reg->isFree)nfr++;
937 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
941 /*-----------------------------------------------------------------*/
942 /* nfreeRegsType - free registers with type */
943 /*-----------------------------------------------------------------*/
945 nfreeRegsType (int type)
948 debugLog ("%s\n", __FUNCTION__);
951 if ((nfr = nFreeRegs (type)) == 0)
952 return nFreeRegs (REG_GPR);
955 return nFreeRegs (type);
958 static void writeSetUsedRegs(FILE *of, set *dRegs)
963 for (dReg = setFirstItem(dRegs) ; dReg ;
964 dReg = setNextItem(dRegs)) {
967 fprintf (of, "\t%s\n",dReg->name);
973 extern void pic16_groupRegistersInSection(set *regset);
975 extern void pic16_dump_equates(FILE *of, set *equs);
976 //extern void pic16_dump_map(void);
977 extern void pic16_dump_usection(FILE *of, set *section, int fix);
978 extern void pic16_dump_isection(FILE *of, set *section, int fix);
979 extern void pic16_dump_int_registers(FILE *of, set *section);
980 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
982 static void packBits(set *bregs)
987 regs *relocbitfield=NULL;
993 for (regset = bregs ; regset ;
994 regset = regset->next) {
997 breg->isBitField = 1;
998 //fprintf(stderr,"bit reg: %s\n",breg->name);
1001 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1003 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1004 breg->rIdx = breg->address & 7;
1005 breg->address >>= 3;
1008 sprintf (buffer, "fbitfield%02x", breg->address);
1009 //fprintf(stderr,"new bit field\n");
1010 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1011 bitfield->isBitField = 1;
1012 bitfield->isFixed = 1;
1013 bitfield->address = breg->address;
1014 addSet(&pic16_dynDirectRegs,bitfield);
1015 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1017 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1020 breg->reg_alias = bitfield;
1024 if(!relocbitfield || bit_no >7) {
1027 sprintf (buffer, "bitfield%d", byte_no);
1028 //fprintf(stderr,"new relocatable bit field\n");
1029 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1030 relocbitfield->isBitField = 1;
1031 addSet(&pic16_dynDirectRegs,relocbitfield);
1032 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1036 breg->reg_alias = relocbitfield;
1037 breg->address = rDirectIdx; /* byte_no; */
1038 breg->rIdx = bit_no++;
1047 static void bitEQUs(FILE *of, set *bregs)
1049 regs *breg,*bytereg;
1052 //fprintf(stderr," %s\n",__FUNCTION__);
1053 for (breg = setFirstItem(bregs) ; breg ;
1054 breg = setNextItem(bregs)) {
1056 //fprintf(stderr,"bit reg: %s\n",breg->name);
1058 bytereg = breg->reg_alias;
1060 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1063 breg->rIdx & 0x0007);
1066 fprintf(stderr, "bit field is not assigned to a register\n");
1067 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1078 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1083 for (reg = setFirstItem(fregs) ; reg ;
1084 reg = setNextItem(fregs)) {
1086 if(!reg->isEmitted && reg->wasUsed) {
1088 if (reg->type != REG_SFR) {
1089 fprintf (of, "%s\tEQU\t0x%03x\n",
1095 fprintf (of, "%s\tEQU\t0x%03x\n",
1104 void pic16_writeUsedRegs(FILE *of)
1106 packBits(pic16_dynDirectBitRegs);
1108 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1109 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1110 pic16_groupRegistersInSection(pic16_dynStackRegs);
1111 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1112 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1113 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1117 pic16_dump_equates(of, pic16_equ_data);
1119 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1120 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1122 /* dump initialised data */
1123 pic16_dump_isection(of, rel_idataSymSet, 0);
1124 pic16_dump_isection(of, fix_idataSymSet, 1);
1126 /* dump internal registers */
1127 pic16_dump_int_registers(of, pic16_int_regs);
1129 /* dump other variables */
1130 pic16_dump_usection(of, pic16_rel_udata, 0);
1131 pic16_dump_usection(of, pic16_fix_udata, 1);
1136 /*-----------------------------------------------------------------*/
1137 /* allDefsOutOfRange - all definitions are out of a range */
1138 /*-----------------------------------------------------------------*/
1140 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1144 debugLog ("%s\n", __FUNCTION__);
1148 for (i = 0; i < defs->size; i++)
1152 if (bitVectBitValue (defs, i) &&
1153 (ic = hTabItemWithKey (iCodehTab, i)) &&
1154 (ic->seq >= fseq && ic->seq <= toseq))
1164 /*-----------------------------------------------------------------*/
1165 /* computeSpillable - given a point find the spillable live ranges */
1166 /*-----------------------------------------------------------------*/
1168 computeSpillable (iCode * ic)
1172 debugLog ("%s\n", __FUNCTION__);
1173 /* spillable live ranges are those that are live at this
1174 point . the following categories need to be subtracted
1176 a) - those that are already spilt
1177 b) - if being used by this one
1178 c) - defined by this one */
1180 spillable = bitVectCopy (ic->rlive);
1182 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1184 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1185 bitVectUnSetBit (spillable, ic->defKey);
1186 spillable = bitVectIntersect (spillable, _G.regAssigned);
1191 /*-----------------------------------------------------------------*/
1192 /* noSpilLoc - return true if a variable has no spil location */
1193 /*-----------------------------------------------------------------*/
1195 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1197 debugLog ("%s\n", __FUNCTION__);
1198 return (sym->usl.spillLoc ? 0 : 1);
1201 /*-----------------------------------------------------------------*/
1202 /* hasSpilLoc - will return 1 if the symbol has spil location */
1203 /*-----------------------------------------------------------------*/
1205 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1207 debugLog ("%s\n", __FUNCTION__);
1208 return (sym->usl.spillLoc ? 1 : 0);
1211 /*-----------------------------------------------------------------*/
1212 /* directSpilLoc - will return 1 if the splilocation is in direct */
1213 /*-----------------------------------------------------------------*/
1215 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1217 debugLog ("%s\n", __FUNCTION__);
1218 if (sym->usl.spillLoc &&
1219 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1225 /*-----------------------------------------------------------------*/
1226 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1227 /* but is not used as a pointer */
1228 /*-----------------------------------------------------------------*/
1230 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1232 debugLog ("%s\n", __FUNCTION__);
1233 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1236 /*-----------------------------------------------------------------*/
1237 /* rematable - will return 1 if the remat flag is set */
1238 /*-----------------------------------------------------------------*/
1240 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1242 debugLog ("%s\n", __FUNCTION__);
1246 /*-----------------------------------------------------------------*/
1247 /* notUsedInRemaining - not used or defined in remain of the block */
1248 /*-----------------------------------------------------------------*/
1250 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1252 debugLog ("%s\n", __FUNCTION__);
1253 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1254 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1257 /*-----------------------------------------------------------------*/
1258 /* allLRs - return true for all */
1259 /*-----------------------------------------------------------------*/
1261 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1263 debugLog ("%s\n", __FUNCTION__);
1267 /*-----------------------------------------------------------------*/
1268 /* liveRangesWith - applies function to a given set of live range */
1269 /*-----------------------------------------------------------------*/
1271 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1272 eBBlock * ebp, iCode * ic)
1277 debugLog ("%s\n", __FUNCTION__);
1278 if (!lrs || !lrs->size)
1281 for (i = 1; i < lrs->size; i++)
1284 if (!bitVectBitValue (lrs, i))
1287 /* if we don't find it in the live range
1288 hash table we are in serious trouble */
1289 if (!(sym = hTabItemWithKey (liveRanges, i)))
1291 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1292 "liveRangesWith could not find liveRange");
1296 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1297 addSetHead (&rset, sym);
1304 /*-----------------------------------------------------------------*/
1305 /* leastUsedLR - given a set determines which is the least used */
1306 /*-----------------------------------------------------------------*/
1308 leastUsedLR (set * sset)
1310 symbol *sym = NULL, *lsym = NULL;
1312 debugLog ("%s\n", __FUNCTION__);
1313 sym = lsym = setFirstItem (sset);
1318 for (; lsym; lsym = setNextItem (sset))
1321 /* if usage is the same then prefer
1322 the spill the smaller of the two */
1323 if (lsym->used == sym->used)
1324 if (getSize (lsym->type) < getSize (sym->type))
1328 if (lsym->used < sym->used)
1333 setToNull ((void *) &sset);
1338 /*-----------------------------------------------------------------*/
1339 /* noOverLap - will iterate through the list looking for over lap */
1340 /*-----------------------------------------------------------------*/
1342 noOverLap (set * itmpStack, symbol * fsym)
1345 debugLog ("%s\n", __FUNCTION__);
1348 for (sym = setFirstItem (itmpStack); sym;
1349 sym = setNextItem (itmpStack))
1351 if (sym->liveTo > fsym->liveFrom)
1359 /*-----------------------------------------------------------------*/
1360 /* isFree - will return 1 if the a free spil location is found */
1361 /*-----------------------------------------------------------------*/
1366 V_ARG (symbol **, sloc);
1367 V_ARG (symbol *, fsym);
1369 debugLog ("%s\n", __FUNCTION__);
1370 /* if already found */
1374 /* if it is free && and the itmp assigned to
1375 this does not have any overlapping live ranges
1376 with the one currently being assigned and
1377 the size can be accomodated */
1379 noOverLap (sym->usl.itmpStack, fsym) &&
1380 getSize (sym->type) >= getSize (fsym->type))
1389 /*-----------------------------------------------------------------*/
1390 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1391 /*-----------------------------------------------------------------*/
1393 spillLRWithPtrReg (symbol * forSym)
1399 debugLog ("%s\n", __FUNCTION__);
1400 if (!_G.regAssigned ||
1401 bitVectIsZero (_G.regAssigned))
1404 r0 = pic16_regWithIdx (R0_IDX);
1405 r1 = pic16_regWithIdx (R1_IDX);
1407 /* for all live ranges */
1408 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1409 lrsym = hTabNextItem (liveRanges, &k))
1413 /* if no registers assigned to it or
1415 /* if it does not overlap with this then
1416 not need to spill it */
1418 if (lrsym->isspilt || !lrsym->nRegs ||
1419 (lrsym->liveTo < forSym->liveFrom))
1422 /* go thru the registers : if it is either
1423 r0 or r1 then spil it */
1424 for (j = 0; j < lrsym->nRegs; j++)
1425 if (lrsym->regs[j] == r0 ||
1426 lrsym->regs[j] == r1)
1435 /*-----------------------------------------------------------------*/
1436 /* createStackSpil - create a location on the stack to spil */
1437 /*-----------------------------------------------------------------*/
1439 createStackSpil (symbol * sym)
1441 symbol *sloc = NULL;
1442 int useXstack, model, noOverlay;
1444 char slocBuffer[30];
1445 debugLog ("%s\n", __FUNCTION__);
1447 /* first go try and find a free one that is already
1448 existing on the stack */
1449 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1451 /* found a free one : just update & return */
1452 sym->usl.spillLoc = sloc;
1455 addSetHead (&sloc->usl.itmpStack, sym);
1459 /* could not then have to create one , this is the hard part
1460 we need to allocate this on the stack : this is really a
1461 hack!! but cannot think of anything better at this time */
1463 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1465 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1466 __FILE__, __LINE__);
1470 sloc = newiTemp (slocBuffer);
1472 /* set the type to the spilling symbol */
1473 sloc->type = copyLinkChain (sym->type);
1474 sloc->etype = getSpec (sloc->type);
1475 SPEC_SCLS (sloc->etype) = S_DATA;
1476 SPEC_EXTR (sloc->etype) = 0;
1477 SPEC_STAT (sloc->etype) = 0;
1479 /* we don't allow it to be allocated`
1480 onto the external stack since : so we
1481 temporarily turn it off ; we also
1482 turn off memory model to prevent
1483 the spil from going to the external storage
1484 and turn off overlaying
1487 useXstack = options.useXstack;
1488 model = options.model;
1489 noOverlay = options.noOverlay;
1490 options.noOverlay = 1;
1491 options.model = options.useXstack = 0;
1495 options.useXstack = useXstack;
1496 options.model = model;
1497 options.noOverlay = noOverlay;
1498 sloc->isref = 1; /* to prevent compiler warning */
1500 /* if it is on the stack then update the stack */
1501 if (IN_STACK (sloc->etype))
1503 currFunc->stack += getSize (sloc->type);
1504 _G.stackExtend += getSize (sloc->type);
1507 _G.dataExtend += getSize (sloc->type);
1509 /* add it to the _G.stackSpil set */
1510 addSetHead (&_G.stackSpil, sloc);
1511 sym->usl.spillLoc = sloc;
1514 /* add it to the set of itempStack set
1515 of the spill location */
1516 addSetHead (&sloc->usl.itmpStack, sym);
1520 /*-----------------------------------------------------------------*/
1521 /* isSpiltOnStack - returns true if the spil location is on stack */
1522 /*-----------------------------------------------------------------*/
1524 isSpiltOnStack (symbol * sym)
1528 debugLog ("%s\n", __FUNCTION__);
1535 /* if (sym->_G.stackSpil) */
1538 if (!sym->usl.spillLoc)
1541 etype = getSpec (sym->usl.spillLoc->type);
1542 if (IN_STACK (etype))
1548 /*-----------------------------------------------------------------*/
1549 /* spillThis - spils a specific operand */
1550 /*-----------------------------------------------------------------*/
1552 spillThis (symbol * sym)
1555 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1557 /* if this is rematerializable or has a spillLocation
1558 we are okay, else we need to create a spillLocation
1560 if (!(sym->remat || sym->usl.spillLoc))
1561 createStackSpil (sym);
1564 /* mark it has spilt & put it in the spilt set */
1566 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1568 bitVectUnSetBit (_G.regAssigned, sym->key);
1570 for (i = 0; i < sym->nRegs; i++)
1574 freeReg (sym->regs[i]);
1575 sym->regs[i] = NULL;
1578 /* if spilt on stack then free up r0 & r1
1579 if they could have been assigned to some
1581 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1584 spillLRWithPtrReg (sym);
1587 if (sym->usl.spillLoc && !sym->remat)
1588 sym->usl.spillLoc->allocreq = 1;
1592 /*-----------------------------------------------------------------*/
1593 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1594 /*-----------------------------------------------------------------*/
1596 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1598 bitVect *lrcs = NULL;
1602 debugLog ("%s\n", __FUNCTION__);
1603 /* get the spillable live ranges */
1604 lrcs = computeSpillable (ic);
1606 /* get all live ranges that are rematerizable */
1607 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1610 /* return the least used of these */
1611 return leastUsedLR (selectS);
1614 /* get live ranges with spillLocations in direct space */
1615 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1617 sym = leastUsedLR (selectS);
1618 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1619 sym->usl.spillLoc->rname :
1620 sym->usl.spillLoc->name));
1622 /* mark it as allocation required */
1623 sym->usl.spillLoc->allocreq = 1;
1627 /* if the symbol is local to the block then */
1628 if (forSym->liveTo < ebp->lSeq)
1631 /* check if there are any live ranges allocated
1632 to registers that are not used in this block */
1633 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1635 sym = leastUsedLR (selectS);
1636 /* if this is not rematerializable */
1645 /* check if there are any live ranges that not
1646 used in the remainder of the block */
1647 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1649 sym = leastUsedLR (selectS);
1652 sym->remainSpil = 1;
1659 /* find live ranges with spillocation && not used as pointers */
1660 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1663 sym = leastUsedLR (selectS);
1664 /* mark this as allocation required */
1665 sym->usl.spillLoc->allocreq = 1;
1669 /* find live ranges with spillocation */
1670 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1673 sym = leastUsedLR (selectS);
1674 sym->usl.spillLoc->allocreq = 1;
1678 /* couldn't find then we need to create a spil
1679 location on the stack , for which one? the least
1681 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1684 /* return a created spil location */
1685 sym = createStackSpil (leastUsedLR (selectS));
1686 sym->usl.spillLoc->allocreq = 1;
1690 /* this is an extreme situation we will spill
1691 this one : happens very rarely but it does happen */
1697 /*-----------------------------------------------------------------*/
1698 /* spilSomething - spil some variable & mark registers as free */
1699 /*-----------------------------------------------------------------*/
1701 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1706 debugLog ("%s\n", __FUNCTION__);
1707 /* get something we can spil */
1708 ssym = selectSpil (ic, ebp, forSym);
1710 /* mark it as spilt */
1712 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1714 /* mark it as not register assigned &
1715 take it away from the set */
1716 bitVectUnSetBit (_G.regAssigned, ssym->key);
1718 /* mark the registers as free */
1719 for (i = 0; i < ssym->nRegs; i++)
1721 freeReg (ssym->regs[i]);
1723 /* if spilt on stack then free up r0 & r1
1724 if they could have been assigned to as gprs */
1725 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1728 spillLRWithPtrReg (ssym);
1731 /* if this was a block level spil then insert push & pop
1732 at the start & end of block respectively */
1733 if (ssym->blockSpil)
1735 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1736 /* add push to the start of the block */
1737 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1738 ebp->sch->next : ebp->sch));
1739 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1740 /* add pop to the end of the block */
1741 addiCodeToeBBlock (ebp, nic, NULL);
1744 /* if spilt because not used in the remainder of the
1745 block then add a push before this instruction and
1746 a pop at the end of the block */
1747 if (ssym->remainSpil)
1750 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1751 /* add push just before this instruction */
1752 addiCodeToeBBlock (ebp, nic, ic);
1754 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1755 /* add pop to the end of the block */
1756 addiCodeToeBBlock (ebp, nic, NULL);
1765 /*-----------------------------------------------------------------*/
1766 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1767 /*-----------------------------------------------------------------*/
1769 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1774 debugLog ("%s\n", __FUNCTION__);
1776 /* try for a ptr type */
1777 if ((reg = allocReg (REG_PTR)))
1780 /* try for gpr type */
1781 if ((reg = allocReg (REG_GPR)))
1784 /* we have to spil */
1785 if (!spilSomething (ic, ebp, sym))
1788 /* make sure partially assigned registers aren't reused */
1789 for (j=0; j<=sym->nRegs; j++)
1791 sym->regs[j]->isFree = 0;
1793 /* this looks like an infinite loop but
1794 in really selectSpil will abort */
1798 /*-----------------------------------------------------------------*/
1799 /* getRegGpr - will try for GPR if not spil */
1800 /*-----------------------------------------------------------------*/
1802 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1807 debugLog ("%s\n", __FUNCTION__);
1809 /* try for gpr type */
1810 if ((reg = allocReg (REG_GPR)))
1813 if (!pic16_ptrRegReq)
1814 if ((reg = allocReg (REG_PTR)))
1817 /* we have to spil */
1818 if (!spilSomething (ic, ebp, sym))
1821 /* make sure partially assigned registers aren't reused */
1822 for (j=0; j<=sym->nRegs; j++)
1824 sym->regs[j]->isFree = 0;
1826 /* this looks like an infinite loop but
1827 in really selectSpil will abort */
1831 /*-----------------------------------------------------------------*/
1832 /* symHasReg - symbol has a given register */
1833 /*-----------------------------------------------------------------*/
1835 symHasReg (symbol * sym, regs * reg)
1839 debugLog ("%s\n", __FUNCTION__);
1840 for (i = 0; i < sym->nRegs; i++)
1841 if (sym->regs[i] == reg)
1847 /*-----------------------------------------------------------------*/
1848 /* deassignLRs - check the live to and if they have registers & are */
1849 /* not spilt then free up the registers */
1850 /*-----------------------------------------------------------------*/
1852 deassignLRs (iCode * ic, eBBlock * ebp)
1858 debugLog ("%s\n", __FUNCTION__);
1859 for (sym = hTabFirstItem (liveRanges, &k); sym;
1860 sym = hTabNextItem (liveRanges, &k))
1863 symbol *psym = NULL;
1864 /* if it does not end here */
1865 if (sym->liveTo > ic->seq)
1868 /* if it was spilt on stack then we can
1869 mark the stack spil location as free */
1874 sym->usl.spillLoc->isFree = 1;
1880 if (!bitVectBitValue (_G.regAssigned, sym->key))
1883 /* special case check if this is an IFX &
1884 the privious one was a pop and the
1885 previous one was not spilt then keep track
1887 if (ic->op == IFX && ic->prev &&
1888 ic->prev->op == IPOP &&
1889 !ic->prev->parmPush &&
1890 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1891 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1897 bitVectUnSetBit (_G.regAssigned, sym->key);
1899 /* if the result of this one needs registers
1900 and does not have it then assign it right
1902 if (IC_RESULT (ic) &&
1903 !(SKIP_IC2 (ic) || /* not a special icode */
1904 ic->op == JUMPTABLE ||
1909 POINTER_SET (ic)) &&
1910 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1911 result->liveTo > ic->seq && /* and will live beyond this */
1912 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1913 result->regType == sym->regType && /* same register types */
1914 result->nRegs && /* which needs registers */
1915 !result->isspilt && /* and does not already have them */
1917 !bitVectBitValue (_G.regAssigned, result->key) &&
1918 /* the number of free regs + number of regs in this LR
1919 can accomodate the what result Needs */
1920 ((nfreeRegsType (result->regType) +
1921 sym->nRegs) >= result->nRegs)
1925 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1927 result->regs[i] = sym->regs[i];
1929 result->regs[i] = getRegGpr (ic, ebp, result);
1931 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1935 /* free the remaining */
1936 for (; i < sym->nRegs; i++)
1940 if (!symHasReg (psym, sym->regs[i]))
1941 freeReg (sym->regs[i]);
1944 freeReg (sym->regs[i]);
1951 /*-----------------------------------------------------------------*/
1952 /* reassignLR - reassign this to registers */
1953 /*-----------------------------------------------------------------*/
1955 reassignLR (operand * op)
1957 symbol *sym = OP_SYMBOL (op);
1960 debugLog ("%s\n", __FUNCTION__);
1961 /* not spilt any more */
1962 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1963 bitVectUnSetBit (_G.spiltSet, sym->key);
1965 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1969 for (i = 0; i < sym->nRegs; i++)
1970 sym->regs[i]->isFree = 0;
1973 /*-----------------------------------------------------------------*/
1974 /* willCauseSpill - determines if allocating will cause a spill */
1975 /*-----------------------------------------------------------------*/
1977 willCauseSpill (int nr, int rt)
1979 debugLog ("%s\n", __FUNCTION__);
1980 /* first check if there are any avlb registers
1981 of te type required */
1984 /* special case for pointer type
1985 if pointer type not avlb then
1986 check for type gpr */
1987 if (nFreeRegs (rt) >= nr)
1989 if (nFreeRegs (REG_GPR) >= nr)
1994 if (pic16_ptrRegReq)
1996 if (nFreeRegs (rt) >= nr)
2001 if (nFreeRegs (REG_PTR) +
2002 nFreeRegs (REG_GPR) >= nr)
2007 debugLog (" ... yep it will (cause a spill)\n");
2008 /* it will cause a spil */
2012 /*-----------------------------------------------------------------*/
2013 /* positionRegs - the allocator can allocate same registers to res- */
2014 /* ult and operand, if this happens make sure they are in the same */
2015 /* position as the operand otherwise chaos results */
2016 /*-----------------------------------------------------------------*/
2018 positionRegs (symbol * result, symbol * opsym, int lineno)
2020 int count = min (result->nRegs, opsym->nRegs);
2021 int i, j = 0, shared = 0;
2023 debugLog ("%s\n", __FUNCTION__);
2024 /* if the result has been spilt then cannot share */
2029 /* first make sure that they actually share */
2030 for (i = 0; i < count; i++)
2032 for (j = 0; j < count; j++)
2034 if (result->regs[i] == opsym->regs[j] && i != j)
2044 regs *tmp = result->regs[i];
2045 result->regs[i] = result->regs[j];
2046 result->regs[j] = tmp;
2051 /*------------------------------------------------------------------*/
2052 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2053 /* it should either have registers or have beed spilled. Otherwise, */
2054 /* there was an uninitialized variable, so just spill this to get */
2055 /* the operand in a valid state. */
2056 /*------------------------------------------------------------------*/
2058 verifyRegsAssigned (operand *op, iCode * ic)
2063 if (!IS_ITEMP (op)) return;
2065 sym = OP_SYMBOL (op);
2066 if (sym->isspilt) return;
2067 if (!sym->nRegs) return;
2068 if (sym->regs[0]) return;
2070 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2071 sym->prereqv ? sym->prereqv->name : sym->name);
2076 /*-----------------------------------------------------------------*/
2077 /* serialRegAssign - serially allocate registers to the variables */
2078 /*-----------------------------------------------------------------*/
2080 serialRegAssign (eBBlock ** ebbs, int count)
2084 debugLog ("%s\n", __FUNCTION__);
2085 /* for all blocks */
2086 for (i = 0; i < count; i++)
2091 if (ebbs[i]->noPath &&
2092 (ebbs[i]->entryLabel != entryLabel &&
2093 ebbs[i]->entryLabel != returnLabel))
2096 /* of all instructions do */
2097 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2100 debugLog (" op: %s\n", decodeOp (ic->op));
2102 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2103 pic16_allocDirReg(IC_RESULT(ic));
2105 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2106 pic16_allocDirReg(IC_LEFT(ic));
2108 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2109 pic16_allocDirReg(IC_RIGHT(ic));
2111 /* if this is an ipop that means some live
2112 range will have to be assigned again */
2114 reassignLR (IC_LEFT (ic));
2116 /* if result is present && is a true symbol */
2117 if (IC_RESULT (ic) && ic->op != IFX &&
2118 IS_TRUE_SYMOP (IC_RESULT (ic)))
2119 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2121 /* take away registers from live
2122 ranges that end at this instruction */
2123 deassignLRs (ic, ebbs[i]);
2125 /* some don't need registers */
2126 if (SKIP_IC2 (ic) ||
2127 ic->op == JUMPTABLE ||
2131 (IC_RESULT (ic) && POINTER_SET (ic)))
2134 /* now we need to allocate registers
2135 only for the result */
2138 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2144 /* if it does not need or is spilt
2145 or is already assigned to registers
2146 or will not live beyond this instructions */
2149 bitVectBitValue (_G.regAssigned, sym->key) ||
2150 sym->liveTo <= ic->seq)
2153 /* if some liverange has been spilt at the block level
2154 and this one live beyond this block then spil this
2156 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2161 /* if trying to allocate this will cause
2162 a spill and there is nothing to spill
2163 or this one is rematerializable then
2165 willCS = willCauseSpill (sym->nRegs, sym->regType);
2166 spillable = computeSpillable (ic);
2168 (willCS && bitVectIsZero (spillable)))
2176 /* If the live range preceeds the point of definition
2177 then ideally we must take into account registers that
2178 have been allocated after sym->liveFrom but freed
2179 before ic->seq. This is complicated, so spill this
2180 symbol instead and let fillGaps handle the allocation. */
2181 if (sym->liveFrom < ic->seq)
2187 /* if it has a spillocation & is used less than
2188 all other live ranges then spill this */
2190 if (sym->usl.spillLoc) {
2191 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2192 allLRs, ebbs[i], ic));
2193 if (leastUsed && leastUsed->used > sym->used) {
2198 /* if none of the liveRanges have a spillLocation then better
2199 to spill this one than anything else already assigned to registers */
2200 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2201 /* if this is local to this block then we might find a block spil */
2202 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2210 if (ic->op == RECEIVE)
2211 debugLog ("When I get clever, I'll optimize the receive logic\n");
2213 /* if we need ptr regs for the right side
2215 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2216 <= (unsigned) PTRSIZE)
2221 /* else we assign registers to it */
2222 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2224 debugLog (" %d - \n", __LINE__);
2226 bitVectDebugOn(_G.regAssigned, debugF);
2228 for (j = 0; j < sym->nRegs; j++)
2230 if (sym->regType == REG_PTR)
2231 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2233 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2235 /* if the allocation falied which means
2236 this was spilt then break */
2240 debugLog (" %d - \n", __LINE__);
2242 /* if it shares registers with operands make sure
2243 that they are in the same position */
2244 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2245 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2246 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2247 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2248 /* do the same for the right operand */
2249 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2250 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2251 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2252 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2254 debugLog (" %d - \n", __LINE__);
2257 debugLog (" %d - \n", __LINE__);
2266 /* Check for and fix any problems with uninitialized operands */
2267 for (i = 0; i < count; i++)
2271 if (ebbs[i]->noPath &&
2272 (ebbs[i]->entryLabel != entryLabel &&
2273 ebbs[i]->entryLabel != returnLabel))
2276 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2283 verifyRegsAssigned (IC_COND (ic), ic);
2287 if (ic->op == JUMPTABLE)
2289 verifyRegsAssigned (IC_JTCOND (ic), ic);
2293 verifyRegsAssigned (IC_RESULT (ic), ic);
2294 verifyRegsAssigned (IC_LEFT (ic), ic);
2295 verifyRegsAssigned (IC_RIGHT (ic), ic);
2301 /*-----------------------------------------------------------------*/
2302 /* rUmaskForOp :- returns register mask for an operand */
2303 /*-----------------------------------------------------------------*/
2305 rUmaskForOp (operand * op)
2311 debugLog ("%s\n", __FUNCTION__);
2312 /* only temporaries are assigned registers */
2316 sym = OP_SYMBOL (op);
2318 /* if spilt or no registers assigned to it
2320 if (sym->isspilt || !sym->nRegs)
2323 rumask = newBitVect (pic16_nRegs);
2325 for (j = 0; j < sym->nRegs; j++)
2327 rumask = bitVectSetBit (rumask,
2328 sym->regs[j]->rIdx);
2334 /*-----------------------------------------------------------------*/
2335 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2336 /*-----------------------------------------------------------------*/
2338 regsUsedIniCode (iCode * ic)
2340 bitVect *rmask = newBitVect (pic16_nRegs);
2342 debugLog ("%s\n", __FUNCTION__);
2343 /* do the special cases first */
2346 rmask = bitVectUnion (rmask,
2347 rUmaskForOp (IC_COND (ic)));
2351 /* for the jumptable */
2352 if (ic->op == JUMPTABLE)
2354 rmask = bitVectUnion (rmask,
2355 rUmaskForOp (IC_JTCOND (ic)));
2360 /* of all other cases */
2362 rmask = bitVectUnion (rmask,
2363 rUmaskForOp (IC_LEFT (ic)));
2367 rmask = bitVectUnion (rmask,
2368 rUmaskForOp (IC_RIGHT (ic)));
2371 rmask = bitVectUnion (rmask,
2372 rUmaskForOp (IC_RESULT (ic)));
2378 /*-----------------------------------------------------------------*/
2379 /* createRegMask - for each instruction will determine the regsUsed */
2380 /*-----------------------------------------------------------------*/
2382 createRegMask (eBBlock ** ebbs, int count)
2386 debugLog ("%s\n", __FUNCTION__);
2387 /* for all blocks */
2388 for (i = 0; i < count; i++)
2392 if (ebbs[i]->noPath &&
2393 (ebbs[i]->entryLabel != entryLabel &&
2394 ebbs[i]->entryLabel != returnLabel))
2397 /* for all instructions */
2398 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2403 if (SKIP_IC2 (ic) || !ic->rlive)
2406 /* first mark the registers used in this
2408 ic->rUsed = regsUsedIniCode (ic);
2409 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2411 /* now create the register mask for those
2412 registers that are in use : this is a
2413 super set of ic->rUsed */
2414 ic->rMask = newBitVect (pic16_nRegs + 1);
2416 /* for all live Ranges alive at this point */
2417 for (j = 1; j < ic->rlive->size; j++)
2422 /* if not alive then continue */
2423 if (!bitVectBitValue (ic->rlive, j))
2426 /* find the live range we are interested in */
2427 if (!(sym = hTabItemWithKey (liveRanges, j)))
2429 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2430 "createRegMask cannot find live range");
2434 /* if no register assigned to it */
2435 if (!sym->nRegs || sym->isspilt)
2438 /* for all the registers allocated to it */
2439 for (k = 0; k < sym->nRegs; k++)
2442 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2448 /*-----------------------------------------------------------------*/
2449 /* rematStr - returns the rematerialized string for a remat var */
2450 /*-----------------------------------------------------------------*/
2452 rematStr (symbol * sym)
2455 iCode *ic = sym->rematiCode;
2456 symbol *psym = NULL;
2458 debugLog ("%s\n", __FUNCTION__);
2460 //printf ("%s\n", s);
2462 /* if plus or minus print the right hand side */
2464 if (ic->op == '+' || ic->op == '-') {
2466 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2468 sprintf (s, "(%s %c 0x%04x)",
2469 OP_SYMBOL (IC_LEFT (ric))->rname,
2471 (int) operandLitValue (IC_RIGHT (ic)));
2474 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2476 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2477 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2482 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2483 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2485 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2490 /*-----------------------------------------------------------------*/
2491 /* rematStr - returns the rematerialized string for a remat var */
2492 /*-----------------------------------------------------------------*/
2494 rematStr (symbol * sym)
2497 iCode *ic = sym->rematiCode;
2499 debugLog ("%s\n", __FUNCTION__);
2504 /* if plus or minus print the right hand side */
2506 if (ic->op == '+' || ic->op == '-') {
2507 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2510 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2514 if (ic->op == '+' || ic->op == '-')
2516 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2517 sprintf (s, "(%s %c 0x%04x)",
2518 OP_SYMBOL (IC_LEFT (ric))->rname,
2520 (int) operandLitValue (IC_RIGHT (ic)));
2523 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2525 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2529 /* we reached the end */
2530 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2534 printf ("%s\n", buffer);
2539 /*-----------------------------------------------------------------*/
2540 /* regTypeNum - computes the type & number of registers required */
2541 /*-----------------------------------------------------------------*/
2549 debugLog ("%s\n", __FUNCTION__);
2550 /* for each live range do */
2551 for (sym = hTabFirstItem (liveRanges, &k); sym;
2552 sym = hTabNextItem (liveRanges, &k)) {
2554 debugLog (" %d - %s\n", __LINE__, sym->rname);
2555 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2557 /* if used zero times then no registers needed */
2558 if ((sym->liveTo - sym->liveFrom) == 0)
2562 /* if the live range is a temporary */
2565 debugLog (" %d - itemp register\n", __LINE__);
2567 /* if the type is marked as a conditional */
2568 if (sym->regType == REG_CND)
2571 /* if used in return only then we don't
2573 if (sym->ruonly || sym->accuse) {
2574 if (IS_AGGREGATE (sym->type) || sym->isptr)
2575 sym->type = aggrToPtr (sym->type, FALSE);
2576 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2581 /* if the symbol has only one definition &
2582 that definition is a get_pointer and the
2583 pointer we are getting is rematerializable and
2586 if (bitVectnBitsOn (sym->defs) == 1 &&
2587 (ic = hTabItemWithKey (iCodehTab,
2588 bitVectFirstBit (sym->defs))) &&
2590 !IS_BITVAR (sym->etype) &&
2591 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2593 if (ptrPseudoSymSafe (sym, ic)) {
2597 debugLog (" %d - \n", __LINE__);
2599 /* create a psuedo symbol & force a spil */
2600 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2601 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2602 psym->type = sym->type;
2603 psym->etype = sym->etype;
2604 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2605 strcpy (psym->rname, psym->name);
2607 sym->usl.spillLoc = psym;
2611 /* if in data space or idata space then try to
2612 allocate pointer register */
2616 /* if not then we require registers */
2617 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2618 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2619 getSize (sym->type));
2623 if(IS_PTR_CONST (sym->type)) {
2625 if(IS_CODEPTR (sym->type)) {
2627 // what IS this ???? (HJD)
2628 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2629 sym->nRegs = 3; // patch 14
2632 if (sym->nRegs > 4) {
2633 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2634 printTypeChain (sym->type, stderr);
2635 fprintf (stderr, "\n");
2638 /* determine the type of register required */
2639 if (sym->nRegs == 1 &&
2640 IS_PTR (sym->type) &&
2642 sym->regType = REG_PTR;
2644 sym->regType = REG_GPR;
2647 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2651 /* for the first run we don't provide */
2652 /* registers for true symbols we will */
2653 /* see how things go */
2658 static DEFSETFUNC (markRegFree)
2660 ((regs *)item)->isFree = 1;
2665 DEFSETFUNC (pic16_deallocReg)
2667 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2668 ((regs *)item)->isFree = 1;
2669 ((regs *)item)->wasUsed = 0;
2673 /*-----------------------------------------------------------------*/
2674 /* freeAllRegs - mark all registers as free */
2675 /*-----------------------------------------------------------------*/
2677 pic16_freeAllRegs ()
2679 debugLog ("%s\n", __FUNCTION__);
2681 applyToSet(pic16_dynAllocRegs,markRegFree);
2682 applyToSet(pic16_dynStackRegs,markRegFree);
2685 /*-----------------------------------------------------------------*/
2686 /*-----------------------------------------------------------------*/
2688 pic16_deallocateAllRegs ()
2690 debugLog ("%s\n", __FUNCTION__);
2692 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2696 /*-----------------------------------------------------------------*/
2697 /* deallocStackSpil - this will set the stack pointer back */
2698 /*-----------------------------------------------------------------*/
2700 DEFSETFUNC (deallocStackSpil)
2704 debugLog ("%s\n", __FUNCTION__);
2709 /*-----------------------------------------------------------------*/
2710 /* farSpacePackable - returns the packable icode for far variables */
2711 /*-----------------------------------------------------------------*/
2713 farSpacePackable (iCode * ic)
2717 debugLog ("%s\n", __FUNCTION__);
2718 /* go thru till we find a definition for the
2719 symbol on the right */
2720 for (dic = ic->prev; dic; dic = dic->prev)
2723 /* if the definition is a call then no */
2724 if ((dic->op == CALL || dic->op == PCALL) &&
2725 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2730 /* if shift by unknown amount then not */
2731 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2732 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2735 /* if pointer get and size > 1 */
2736 if (POINTER_GET (dic) &&
2737 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2740 if (POINTER_SET (dic) &&
2741 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2744 /* if any three is a true symbol in far space */
2745 if (IC_RESULT (dic) &&
2746 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2747 isOperandInFarSpace (IC_RESULT (dic)))
2750 if (IC_RIGHT (dic) &&
2751 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2752 isOperandInFarSpace (IC_RIGHT (dic)) &&
2753 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2756 if (IC_LEFT (dic) &&
2757 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2758 isOperandInFarSpace (IC_LEFT (dic)) &&
2759 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2762 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2764 if ((dic->op == LEFT_OP ||
2765 dic->op == RIGHT_OP ||
2767 IS_OP_LITERAL (IC_RIGHT (dic)))
2777 /*-----------------------------------------------------------------*/
2778 /* packRegsForAssign - register reduction for assignment */
2779 /*-----------------------------------------------------------------*/
2781 packRegsForAssign (iCode * ic, eBBlock * ebp)
2786 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2787 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2788 debugAopGet (" result:", IC_RESULT (ic));
2789 debugAopGet (" left:", IC_LEFT (ic));
2790 debugAopGet (" right:", IC_RIGHT (ic));
2792 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2795 /* if this is at an absolute address, then get the address. */
2796 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2797 if(PIC16_IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2798 debugLog (" %d - found config word declaration\n", __LINE__);
2799 if(IS_VALOP(IC_RIGHT(ic))) {
2800 debugLog (" setting config word to %x\n",
2801 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2803 fprintf(stderr, "%s:%d setting config word to %x\n", __FILE__, __LINE__,
2804 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2806 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2807 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2811 debugLog(" %d\n", __LINE__);
2813 /* remove the assignment from the iCode chain. */
2815 remiCodeFromeBBlock (ebp, ic);
2816 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2817 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2824 debugLog(" %d - actuall processing\n", __LINE__ );
2826 if (!IS_ITEMP (IC_RESULT (ic))) {
2827 pic16_allocDirReg(IC_RESULT (ic));
2828 debugLog (" %d - result is not temp\n", __LINE__);
2832 /* See BUGLOG0001 - VR */
2834 if (!IS_ITEMP (IC_RIGHT (ic))) {
2835 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2836 pic16_allocDirReg(IC_RIGHT (ic));
2841 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2842 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2844 debugLog (" %d - not packing - right side fails \n", __LINE__);
2848 /* if the true symbol is defined in far space or on stack
2849 then we should not since this will increase register pressure */
2850 if (isOperandInFarSpace (IC_RESULT (ic)))
2852 if ((dic = farSpacePackable (ic)))
2859 /* find the definition of iTempNN scanning backwards if we find a
2860 a use of the true symbol before we find the definition then
2862 for (dic = ic->prev; dic; dic = dic->prev)
2865 /* if there is a function call and this is
2866 a parameter & not my parameter then don't pack it */
2867 if ((dic->op == CALL || dic->op == PCALL) &&
2868 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2869 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2871 debugLog (" %d - \n", __LINE__);
2880 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2882 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2883 IS_OP_VOLATILE (IC_RESULT (dic)))
2885 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2891 if( IS_SYMOP( IC_RESULT(dic)) &&
2892 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2894 debugLog (" %d - result is bitfield\n", __LINE__);
2900 if (IS_SYMOP (IC_RESULT (dic)) &&
2901 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2903 /* A previous result was assigned to the same register - we'll our definition */
2904 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2905 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2906 if (POINTER_SET (dic))
2912 if (IS_SYMOP (IC_RIGHT (dic)) &&
2913 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2914 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2916 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2921 if (IS_SYMOP (IC_LEFT (dic)) &&
2922 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2923 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2925 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2930 if (POINTER_SET (dic) &&
2931 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2933 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2941 return 0; /* did not find */
2944 /* This code is taken from the hc08 port. Do not know
2945 * if it fits for pic16, but I leave it here just in case */
2947 /* if assignment then check that right is not a bit */
2948 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2949 sym_link *etype = operandType (IC_RIGHT (dic));
2951 if (IS_BITFIELD (etype)) {
2952 /* if result is a bit too then it's ok */
2953 etype = operandType (IC_RESULT (dic));
2954 if (!IS_BITFIELD (etype)) {
2955 debugLog(" %d bitfields\n");
2962 /* if the result is on stack or iaccess then it must be
2963 the same atleast one of the operands */
2964 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2965 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2969 /* clear the onStack flag, the port doesn't support it yet! FIXME */
2970 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2971 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2975 /* the operation has only one symbol
2976 operator then we can pack */
2977 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2978 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2981 if (!((IC_LEFT (dic) &&
2982 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2984 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2988 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2989 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2990 /* found the definition */
2991 /* replace the result with the result of */
2992 /* this assignment and remove this assignment */
2993 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2994 IC_RESULT (dic) = IC_RESULT (ic);
2996 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2998 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3000 /* delete from liverange table also
3001 delete from all the points inbetween and the new
3003 for (sic = dic; sic != ic; sic = sic->next)
3005 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3006 if (IS_ITEMP (IC_RESULT (dic)))
3007 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3010 remiCodeFromeBBlock (ebp, ic);
3011 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3013 debugLog(" %d\n", __LINE__ );
3014 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3015 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3023 #define NO_packRegsForAccUse
3024 #define NO_packRegsForSupport
3025 #define NO_packRegsForOneuse
3026 #define NO_cast_peep
3031 #ifndef NO_packRegsForSupport
3032 /*-----------------------------------------------------------------*/
3033 /* findAssignToSym : scanning backwards looks for first assig found */
3034 /*-----------------------------------------------------------------*/
3036 findAssignToSym (operand * op, iCode * ic)
3040 debugLog ("%s\n", __FUNCTION__);
3041 for (dic = ic->prev; dic; dic = dic->prev)
3044 /* if definition by assignment */
3045 if (dic->op == '=' &&
3046 !POINTER_SET (dic) &&
3047 IC_RESULT (dic)->key == op->key
3048 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3052 /* we are interested only if defined in far space */
3053 /* or in stack space in case of + & - */
3055 /* if assigned to a non-symbol then return
3057 if (!IS_SYMOP (IC_RIGHT (dic)))
3060 /* if the symbol is in far space then
3062 if (isOperandInFarSpace (IC_RIGHT (dic)))
3065 /* for + & - operations make sure that
3066 if it is on the stack it is the same
3067 as one of the three operands */
3068 if ((ic->op == '+' || ic->op == '-') &&
3069 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3073 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3074 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3077 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3078 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3079 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3087 /* if we find an usage then we cannot delete it */
3088 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3091 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3094 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3098 /* now make sure that the right side of dic
3099 is not defined between ic & dic */
3102 iCode *sic = dic->next;
3104 for (; sic != ic; sic = sic->next)
3105 if (IC_RESULT (sic) &&
3106 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3117 #ifndef NO_packRegsForSupport
3118 /*-----------------------------------------------------------------*/
3119 /* packRegsForSupport :- reduce some registers for support calls */
3120 /*-----------------------------------------------------------------*/
3122 packRegsForSupport (iCode * ic, eBBlock * ebp)
3126 debugLog ("%s\n", __FUNCTION__);
3127 /* for the left & right operand :- look to see if the
3128 left was assigned a true symbol in far space in that
3129 case replace them */
3130 if (IS_ITEMP (IC_LEFT (ic)) &&
3131 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3133 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3139 debugAopGet ("removing left:", IC_LEFT (ic));
3141 /* found it we need to remove it from the
3143 for (sic = dic; sic != ic; sic = sic->next)
3144 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3146 IC_LEFT (ic)->operand.symOperand =
3147 IC_RIGHT (dic)->operand.symOperand;
3148 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3149 remiCodeFromeBBlock (ebp, dic);
3150 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3151 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3155 /* do the same for the right operand */
3158 IS_ITEMP (IC_RIGHT (ic)) &&
3159 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3161 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3167 /* if this is a subtraction & the result
3168 is a true symbol in far space then don't pack */
3169 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3171 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3172 if (IN_FARSPACE (SPEC_OCLS (etype)))
3176 debugAopGet ("removing right:", IC_RIGHT (ic));
3178 /* found it we need to remove it from the
3180 for (sic = dic; sic != ic; sic = sic->next)
3181 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3183 IC_RIGHT (ic)->operand.symOperand =
3184 IC_RIGHT (dic)->operand.symOperand;
3185 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3187 remiCodeFromeBBlock (ebp, dic);
3188 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3189 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3198 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3200 #ifndef NO_packRegsForOneuse
3201 /*-----------------------------------------------------------------*/
3202 /* packRegsForOneuse : - will reduce some registers for single Use */
3203 /*-----------------------------------------------------------------*/
3205 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3210 debugLog ("%s\n", __FUNCTION__);
3211 /* if returning a literal then do nothing */
3215 /* only upto 2 bytes since we cannot predict
3216 the usage of b, & acc */
3217 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3222 /* this routine will mark the a symbol as used in one
3223 instruction use only && if the definition is local
3224 (ie. within the basic block) && has only one definition &&
3225 that definition is either a return value from a
3226 function or does not contain any variables in
3228 uses = bitVectCopy (OP_USES (op));
3229 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3230 if (!bitVectIsZero (uses)) /* has other uses */
3233 /* if it has only one defintion */
3234 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3235 return NULL; /* has more than one definition */
3237 /* get that definition */
3239 hTabItemWithKey (iCodehTab,
3240 bitVectFirstBit (OP_DEFS (op)))))
3243 /* found the definition now check if it is local */
3244 if (dic->seq < ebp->fSeq ||
3245 dic->seq > ebp->lSeq)
3246 return NULL; /* non-local */
3248 /* now check if it is the return from
3250 if (dic->op == CALL || dic->op == PCALL)
3252 if (ic->op != SEND && ic->op != RETURN &&
3253 !POINTER_SET(ic) && !POINTER_GET(ic))
3255 OP_SYMBOL (op)->ruonly = 1;
3262 /* otherwise check that the definition does
3263 not contain any symbols in far space */
3264 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3265 isOperandInFarSpace (IC_RIGHT (dic)) ||
3266 IS_OP_RUONLY (IC_LEFT (ic)) ||
3267 IS_OP_RUONLY (IC_RIGHT (ic)))
3272 /* if pointer set then make sure the pointer
3274 if (POINTER_SET (dic) &&
3275 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3278 if (POINTER_GET (dic) &&
3279 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3284 /* also make sure the intervenening instructions
3285 don't have any thing in far space */
3286 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3289 /* if there is an intervening function call then no */
3290 if (dic->op == CALL || dic->op == PCALL)
3292 /* if pointer set then make sure the pointer
3294 if (POINTER_SET (dic) &&
3295 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3298 if (POINTER_GET (dic) &&
3299 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3302 /* if address of & the result is remat then okay */
3303 if (dic->op == ADDRESS_OF &&
3304 OP_SYMBOL (IC_RESULT (dic))->remat)
3307 /* if operand has size of three or more & this
3308 operation is a '*','/' or '%' then 'b' may
3310 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3311 getSize (operandType (op)) >= 3)
3314 /* if left or right or result is in far space */
3315 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3316 isOperandInFarSpace (IC_RIGHT (dic)) ||
3317 isOperandInFarSpace (IC_RESULT (dic)) ||
3318 IS_OP_RUONLY (IC_LEFT (dic)) ||
3319 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3320 IS_OP_RUONLY (IC_RESULT (dic)))
3326 OP_SYMBOL (op)->ruonly = 1;
3333 /*-----------------------------------------------------------------*/
3334 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3335 /*-----------------------------------------------------------------*/
3337 isBitwiseOptimizable (iCode * ic)
3339 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3340 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3342 debugLog ("%s\n", __FUNCTION__);
3343 /* bitwise operations are considered optimizable
3344 under the following conditions (Jean-Louis VERN)
3356 if (IS_LITERAL (rtype) ||
3357 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3364 #ifndef NO_packRegsForAccUse
3366 /*-----------------------------------------------------------------*/
3367 /* packRegsForAccUse - pack registers for acc use */
3368 /*-----------------------------------------------------------------*/
3370 packRegsForAccUse (iCode * ic)
3374 debugLog ("%s\n", __FUNCTION__);
3376 /* if this is an aggregate, e.g. a one byte char array */
3377 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3380 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3382 /* if + or - then it has to be one byte result */
3383 if ((ic->op == '+' || ic->op == '-')
3384 && getSize (operandType (IC_RESULT (ic))) > 1)
3387 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3388 /* if shift operation make sure right side is not a literal */
3389 if (ic->op == RIGHT_OP &&
3390 (isOperandLiteral (IC_RIGHT (ic)) ||
3391 getSize (operandType (IC_RESULT (ic))) > 1))
3394 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3395 if (ic->op == LEFT_OP &&
3396 (isOperandLiteral (IC_RIGHT (ic)) ||
3397 getSize (operandType (IC_RESULT (ic))) > 1))
3400 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3401 if (IS_BITWISE_OP (ic) &&
3402 getSize (operandType (IC_RESULT (ic))) > 1)
3406 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3407 /* has only one definition */
3408 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3411 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3412 /* has only one use */
3413 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3416 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3417 /* and the usage immediately follows this iCode */
3418 if (!(uic = hTabItemWithKey (iCodehTab,
3419 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3422 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3423 if (ic->next != uic)
3426 /* if it is a conditional branch then we definitely can */
3430 if (uic->op == JUMPTABLE)
3433 /* if the usage is not is an assignment
3434 or an arithmetic / bitwise / shift operation then not */
3435 if (POINTER_SET (uic) &&
3436 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3439 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3440 if (uic->op != '=' &&
3441 !IS_ARITHMETIC_OP (uic) &&
3442 !IS_BITWISE_OP (uic) &&
3443 uic->op != LEFT_OP &&
3444 uic->op != RIGHT_OP)
3447 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3448 /* if used in ^ operation then make sure right is not a
3450 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3453 /* if shift operation make sure right side is not a literal */
3454 if (uic->op == RIGHT_OP &&
3455 (isOperandLiteral (IC_RIGHT (uic)) ||
3456 getSize (operandType (IC_RESULT (uic))) > 1))
3459 if (uic->op == LEFT_OP &&
3460 (isOperandLiteral (IC_RIGHT (uic)) ||
3461 getSize (operandType (IC_RESULT (uic))) > 1))
3464 /* make sure that the result of this icode is not on the
3465 stack, since acc is used to compute stack offset */
3466 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3467 OP_SYMBOL (IC_RESULT (uic))->onStack)
3470 /* if either one of them in far space then we cannot */
3471 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3472 isOperandInFarSpace (IC_LEFT (uic))) ||
3473 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3474 isOperandInFarSpace (IC_RIGHT (uic))))
3477 /* if the usage has only one operand then we can */
3478 if (IC_LEFT (uic) == NULL ||
3479 IC_RIGHT (uic) == NULL)
3482 /* make sure this is on the left side if not
3483 a '+' since '+' is commutative */
3484 if (ic->op != '+' &&
3485 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3489 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3490 /* if one of them is a literal then we can */
3491 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3492 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3493 (getSize (operandType (IC_RESULT (uic))) <= 1))
3495 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3500 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3501 /* if the other one is not on stack then we can */
3502 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3503 (IS_ITEMP (IC_RIGHT (uic)) ||
3504 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3505 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3508 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3509 (IS_ITEMP (IC_LEFT (uic)) ||
3510 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3511 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3517 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3518 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3525 /*-----------------------------------------------------------------*/
3526 /* packForPush - hueristics to reduce iCode for pushing */
3527 /*-----------------------------------------------------------------*/
3529 packForReceive (iCode * ic, eBBlock * ebp)
3533 debugLog ("%s\n", __FUNCTION__);
3534 debugAopGet (" result:", IC_RESULT (ic));
3535 debugAopGet (" left:", IC_LEFT (ic));
3536 debugAopGet (" right:", IC_RIGHT (ic));
3541 for (dic = ic->next; dic; dic = dic->next)
3546 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3547 debugLog (" used on left\n");
3548 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3549 debugLog (" used on right\n");
3550 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3551 debugLog (" used on result\n");
3553 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3554 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3559 debugLog (" hey we can remove this unnecessary assign\n");
3561 /*-----------------------------------------------------------------*/
3562 /* packForPush - hueristics to reduce iCode for pushing */
3563 /*-----------------------------------------------------------------*/
3565 packForPush (iCode * ic, eBBlock * ebp)
3569 debugLog ("%s\n", __FUNCTION__);
3570 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3573 /* must have only definition & one usage */
3574 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3575 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3578 /* find the definition */
3579 if (!(dic = hTabItemWithKey (iCodehTab,
3580 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3583 if (dic->op != '=' || POINTER_SET (dic))
3586 /* we now we know that it has one & only one def & use
3587 and the that the definition is an assignment */
3588 IC_LEFT (ic) = IC_RIGHT (dic);
3590 remiCodeFromeBBlock (ebp, dic);
3591 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3592 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3595 static void printSymType(char * str, sym_link *sl)
3597 if(!pic16_ralloc_debug)return;
3599 debugLog (" %s Symbol type: ",str);
3600 printTypeChain( sl, debugF);
3604 /*-----------------------------------------------------------------*/
3605 /* some debug code to print the symbol S_TYPE. Note that
3606 * the function checkSClass in src/SDCCsymt.c dinks with
3607 * the S_TYPE in ways the PIC port doesn't fully like...*/
3608 /*-----------------------------------------------------------------*/
3609 static void isData(sym_link *sl)
3613 if(!pic16_ralloc_debug)return;
3620 for ( ; sl; sl=sl->next) {
3622 switch (SPEC_SCLS(sl)) {
3623 case S_DATA: fprintf (of, "data "); break;
3624 case S_XDATA: fprintf (of, "xdata "); break;
3625 case S_SFR: fprintf (of, "sfr "); break;
3626 case S_SBIT: fprintf (of, "sbit "); break;
3627 case S_CODE: fprintf (of, "code "); break;
3628 case S_IDATA: fprintf (of, "idata "); break;
3629 case S_PDATA: fprintf (of, "pdata "); break;
3630 case S_LITERAL: fprintf (of, "literal "); break;
3631 case S_STACK: fprintf (of, "stack "); break;
3632 case S_XSTACK: fprintf (of, "xstack "); break;
3633 case S_BIT: fprintf (of, "bit "); break;
3634 case S_EEPROM: fprintf (of, "eeprom "); break;
3643 /*--------------------------------------------------------------------*/
3644 /* pic16_packRegisters - does some transformations to reduce */
3645 /* register pressure */
3647 /*--------------------------------------------------------------------*/
3649 pic16_packRegisters (eBBlock * ebp)
3654 debugLog ("%s\n", __FUNCTION__);
3660 /* look for assignments of the form */
3661 /* iTempNN = TRueSym (someoperation) SomeOperand */
3663 /* TrueSym := iTempNN:1 */
3664 for (ic = ebp->sch; ic; ic = ic->next)
3666 // debugLog("%d\n", __LINE__);
3667 /* find assignment of the form TrueSym := iTempNN:1 */
3668 /* see BUGLOG0001 for workaround with the CAST - VR */
3669 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3670 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3671 change += packRegsForAssign (ic, ebp);
3675 if (POINTER_SET (ic))
3676 debugLog ("pointer is set\n");
3677 debugAopGet (" result:", IC_RESULT (ic));
3678 debugAopGet (" left:", IC_LEFT (ic));
3679 debugAopGet (" right:", IC_RIGHT (ic));
3688 for (ic = ebp->sch; ic; ic = ic->next) {
3690 if(IS_SYMOP ( IC_LEFT(ic))) {
3691 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3693 debugAopGet ("x left:", IC_LEFT (ic));
3695 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3697 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3699 debugLog (" is a pointer\n");
3701 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3702 debugLog (" is a ptr\n");
3704 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3705 debugLog (" is volatile\n");
3709 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3710 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3711 pic16_allocDirReg(IC_LEFT (ic));
3714 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3717 if(IS_SYMOP ( IC_RIGHT(ic))) {
3718 debugAopGet (" right:", IC_RIGHT (ic));
3719 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3722 if(IS_SYMOP ( IC_RESULT(ic))) {
3723 debugAopGet (" result:", IC_RESULT (ic));
3724 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3727 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3728 debugAopGet (" right:", IC_RIGHT (ic));
3729 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3730 // pic16_allocDirReg(IC_RIGHT(ic));
3733 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3734 debugAopGet (" result:", IC_RESULT (ic));
3735 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3736 // pic16_allocDirReg(IC_RESULT(ic));
3740 if (POINTER_SET (ic))
3741 debugLog (" %d - Pointer set\n", __LINE__);
3744 /* if this is an itemp & result of a address of a true sym
3745 then mark this as rematerialisable */
3746 if (ic->op == ADDRESS_OF &&
3747 IS_ITEMP (IC_RESULT (ic)) &&
3748 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3749 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3750 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3753 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3755 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3756 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3757 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3761 /* if straight assignment then carry remat flag if
3762 this is the only definition */
3763 if (ic->op == '=' &&
3764 !POINTER_SET (ic) &&
3765 IS_SYMOP (IC_RIGHT (ic)) &&
3766 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3767 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3769 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3771 OP_SYMBOL (IC_RESULT (ic))->remat =
3772 OP_SYMBOL (IC_RIGHT (ic))->remat;
3773 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3774 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3777 /* if this is a +/- operation with a rematerizable
3778 then mark this as rematerializable as well */
3779 if ((ic->op == '+' || ic->op == '-') &&
3780 (IS_SYMOP (IC_LEFT (ic)) &&
3781 IS_ITEMP (IC_RESULT (ic)) &&
3782 OP_SYMBOL (IC_LEFT (ic))->remat &&
3783 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3784 IS_OP_LITERAL (IC_RIGHT (ic))))
3786 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3788 operandLitValue (IC_RIGHT (ic));
3789 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3790 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3791 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3794 /* mark the pointer usages */
3795 if (POINTER_SET (ic))
3797 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3798 debugLog (" marking as a pointer (set) =>");
3799 debugAopGet (" result:", IC_RESULT (ic));
3801 if (POINTER_GET (ic))
3803 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3804 debugLog (" marking as a pointer (get) =>");
3805 debugAopGet (" left:", IC_LEFT (ic));
3808 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3812 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3813 /* if we are using a symbol on the stack
3814 then we should say pic16_ptrRegReq */
3815 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3816 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3817 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3818 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3819 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3820 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3824 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3825 if (IS_SYMOP (IC_LEFT (ic)))
3826 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3827 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3828 if (IS_SYMOP (IC_RIGHT (ic)))
3829 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3830 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3831 if (IS_SYMOP (IC_RESULT (ic)))
3832 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3833 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3836 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3840 /* if the condition of an if instruction
3841 is defined in the previous instruction then
3842 mark the itemp as a conditional */
3843 if ((IS_CONDITIONAL (ic) ||
3844 ((ic->op == BITWISEAND ||
3847 isBitwiseOptimizable (ic))) &&
3848 ic->next && ic->next->op == IFX &&
3849 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3850 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3853 debugLog (" %d\n", __LINE__);
3854 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3858 debugLog(" %d\n", __LINE__);
3860 #ifndef NO_packRegsForSupport
3861 /* reduce for support function calls */
3862 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3863 packRegsForSupport (ic, ebp);
3866 /* if a parameter is passed, it's in W, so we may not
3867 need to place a copy in a register */
3868 if (ic->op == RECEIVE)
3869 packForReceive (ic, ebp);
3871 #ifndef NO_packRegsForOneuse
3872 /* some cases the redundant moves can
3873 can be eliminated for return statements */
3874 if ((ic->op == RETURN || ic->op == SEND) &&
3875 !isOperandInFarSpace (IC_LEFT (ic)) &&
3877 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3880 #ifndef NO_packRegsForOneuse
3881 /* if pointer set & left has a size more than
3882 one and right is not in far space */
3883 if (POINTER_SET (ic) &&
3884 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3885 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3886 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3887 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3889 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3892 #ifndef NO_packRegsForOneuse
3893 /* if pointer get */
3894 if (POINTER_GET (ic) &&
3895 !isOperandInFarSpace (IC_RESULT (ic)) &&
3896 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3897 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3898 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3900 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3901 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3904 #ifndef NO_cast_peep
3905 /* if this is cast for intergral promotion then
3906 check if only use of the definition of the
3907 operand being casted/ if yes then replace
3908 the result of that arithmetic operation with
3909 this result and get rid of the cast */
3910 if (ic->op == CAST) {
3912 sym_link *fromType = operandType (IC_RIGHT (ic));
3913 sym_link *toType = operandType (IC_LEFT (ic));
3915 debugLog (" %d - casting\n", __LINE__);
3917 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3918 getSize (fromType) != getSize (toType)) {
3921 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3924 if (IS_ARITHMETIC_OP (dic)) {
3925 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3927 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3928 IC_RESULT (dic) = IC_RESULT (ic);
3929 remiCodeFromeBBlock (ebp, ic);
3930 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3931 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3932 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3936 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3940 /* if the type from and type to are the same
3941 then if this is the only use then packit */
3942 if (compareType (operandType (IC_RIGHT (ic)),
3943 operandType (IC_LEFT (ic))) == 1) {
3945 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3948 debugLog(" %d\n", __LINE__);
3950 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3951 IC_RESULT (dic) = IC_RESULT (ic);
3952 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3953 remiCodeFromeBBlock (ebp, ic);
3954 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3955 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3963 iTempNN := (some variable in farspace) V1
3968 if (ic->op == IPUSH)
3970 packForPush (ic, ebp);
3974 #ifndef NO_packRegsForAccUse
3975 /* pack registers for accumulator use, when the
3976 result of an arithmetic or bit wise operation
3977 has only one use, that use is immediately following
3978 the defintion and the using iCode has only one
3979 operand or has two operands but one is literal &
3980 the result of that operation is not on stack then
3981 we can leave the result of this operation in acc:b
3983 if ((IS_ARITHMETIC_OP (ic)
3985 || IS_BITWISE_OP (ic)
3987 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3990 IS_ITEMP (IC_RESULT (ic)) &&
3991 getSize (operandType (IC_RESULT (ic))) <= 1)
3993 packRegsForAccUse (ic);
4000 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4004 if (!pic16_ralloc_debug || !debugF)
4007 for (i = 0; i < count; i++)
4009 fprintf (debugF, "\n----------------------------------------------------------------\n");
4010 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4011 ebbs[i]->entryLabel->name,
4014 ebbs[i]->isLastInLoop);
4015 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4020 fprintf (debugF, "visited %d : hasFcall = %d\n",
4024 fprintf (debugF, "\ndefines bitVector :");
4025 bitVectDebugOn (ebbs[i]->defSet, debugF);
4026 fprintf (debugF, "\nlocal defines bitVector :");
4027 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4028 fprintf (debugF, "\npointers Set bitvector :");
4029 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4030 fprintf (debugF, "\nin pointers Set bitvector :");
4031 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4032 fprintf (debugF, "\ninDefs Set bitvector :");
4033 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4034 fprintf (debugF, "\noutDefs Set bitvector :");
4035 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4036 fprintf (debugF, "\nusesDefs Set bitvector :");
4037 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4038 fprintf (debugF, "\n----------------------------------------------------------------\n");
4039 printiCChain (ebbs[i]->sch, debugF);
4042 /*-----------------------------------------------------------------*/
4043 /* pic16_assignRegisters - assigns registers to each live range as need */
4044 /*-----------------------------------------------------------------*/
4046 pic16_assignRegisters (eBBlock ** ebbs, int count)
4051 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4052 debugLog ("\nebbs before optimizing:\n");
4053 dumpEbbsToDebug (ebbs, count);
4055 setToNull ((void *) &_G.funcrUsed);
4056 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4059 /* change assignments this will remove some
4060 live ranges reducing some register pressure */
4061 for (i = 0; i < count; i++)
4062 pic16_packRegisters (ebbs[i]);
4069 debugLog("dir registers allocated so far:\n");
4070 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4073 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4074 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4075 reg = hTabNextItem(dynDirectRegNames, &hkey);
4080 /* liveranges probably changed by register packing
4081 so we compute them again */
4082 recomputeLiveRanges (ebbs, count);
4084 if (options.dump_pack)
4085 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4087 /* first determine for each live range the number of
4088 registers & the type of registers required for each */
4091 /* and serially allocate registers */
4092 serialRegAssign (ebbs, count);
4094 // debugLog ("ebbs after serialRegAssign:\n");
4095 // dumpEbbsToDebug (ebbs, count);
4098 //pic16_freeAllRegs();
4100 /* if stack was extended then tell the user */
4103 /* werror(W_TOOMANY_SPILS,"stack", */
4104 /* _G.stackExtend,currFunc->name,""); */
4110 /* werror(W_TOOMANY_SPILS,"data space", */
4111 /* _G.dataExtend,currFunc->name,""); */
4115 /* after that create the register mask
4116 for each of the instruction */
4117 createRegMask (ebbs, count);
4119 /* redo that offsets for stacked automatic variables */
4120 redoStackOffsets ();
4122 if (options.dump_rassgn)
4123 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4125 /* now get back the chain */
4126 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4128 debugLog ("ebbs after optimizing:\n");
4129 dumpEbbsToDebug (ebbs, count);
4134 /* free up any _G.stackSpil locations allocated */
4135 applyToSet (_G.stackSpil, deallocStackSpil);
4137 setToNull ((void *) &_G.stackSpil);
4138 setToNull ((void *) &_G.spiltSet);
4139 /* mark all registers as free */
4140 pic16_freeAllRegs ();
4142 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");