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\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)));
682 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
683 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);
691 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
693 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
694 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
695 // reg->type = REG_SFR;
698 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
699 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
700 addSet(&pic16_dynDirectBitRegs, reg);
703 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
704 // addSet(&pic16_dynDirectRegs, reg);
705 checkAddReg(&pic16_dynDirectRegs, reg);
709 debugLog (" -- %s is declared at address 0x30000x\n",name);
710 // fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
716 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
718 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
720 /* work around for user defined registers in access bank */
721 if((reg->address>= 0x00 && reg->address < 0x80)
722 || (reg->address >= 0xf80 && reg->address <= 0xfff))
725 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
731 /*-----------------------------------------------------------------*/
732 /* pic16_allocRegByName - allocates register of given type */
733 /*-----------------------------------------------------------------*/
735 pic16_allocRegByName (char *name, int size, operand *op)
741 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
745 /* First, search the hash table to see if there is a register with this name */
746 reg = pic16_dirregWithName(name);
750 /* Register wasn't found in hash, so let's create
751 * a new one and put it in the hash table AND in the
752 * dynDirectRegNames set */
753 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_assignFixedRegisters(pic16_dynAllocRegs);
1118 pic16_assignFixedRegisters(pic16_dynStackRegs);
1119 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1120 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1122 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1123 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1124 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1125 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1126 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1129 // pic16_dump_map();
1130 // pic16_dump_cblock(of);
1133 pic16_dump_equates(of, pic16_equ_data);
1135 /* dump initialised data */
1136 pic16_dump_isection(of, rel_idataSymSet, 0);
1137 pic16_dump_isection(of, fix_idataSymSet, 1);
1139 // pic16_dump_idata(of, idataSymSet);
1141 /* dump internal registers */
1142 pic16_dump_int_registers(of, pic16_int_regs);
1144 /* dump other variables */
1145 pic16_dump_usection(of, pic16_rel_udata, 0);
1146 pic16_dump_usection(of, pic16_fix_udata, 1);
1151 /*-----------------------------------------------------------------*/
1152 /* allDefsOutOfRange - all definitions are out of a range */
1153 /*-----------------------------------------------------------------*/
1155 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1159 debugLog ("%s\n", __FUNCTION__);
1163 for (i = 0; i < defs->size; i++)
1167 if (bitVectBitValue (defs, i) &&
1168 (ic = hTabItemWithKey (iCodehTab, i)) &&
1169 (ic->seq >= fseq && ic->seq <= toseq))
1179 /*-----------------------------------------------------------------*/
1180 /* computeSpillable - given a point find the spillable live ranges */
1181 /*-----------------------------------------------------------------*/
1183 computeSpillable (iCode * ic)
1187 debugLog ("%s\n", __FUNCTION__);
1188 /* spillable live ranges are those that are live at this
1189 point . the following categories need to be subtracted
1191 a) - those that are already spilt
1192 b) - if being used by this one
1193 c) - defined by this one */
1195 spillable = bitVectCopy (ic->rlive);
1197 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1199 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1200 bitVectUnSetBit (spillable, ic->defKey);
1201 spillable = bitVectIntersect (spillable, _G.regAssigned);
1206 /*-----------------------------------------------------------------*/
1207 /* noSpilLoc - return true if a variable has no spil location */
1208 /*-----------------------------------------------------------------*/
1210 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1212 debugLog ("%s\n", __FUNCTION__);
1213 return (sym->usl.spillLoc ? 0 : 1);
1216 /*-----------------------------------------------------------------*/
1217 /* hasSpilLoc - will return 1 if the symbol has spil location */
1218 /*-----------------------------------------------------------------*/
1220 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1222 debugLog ("%s\n", __FUNCTION__);
1223 return (sym->usl.spillLoc ? 1 : 0);
1226 /*-----------------------------------------------------------------*/
1227 /* directSpilLoc - will return 1 if the splilocation is in direct */
1228 /*-----------------------------------------------------------------*/
1230 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1232 debugLog ("%s\n", __FUNCTION__);
1233 if (sym->usl.spillLoc &&
1234 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1240 /*-----------------------------------------------------------------*/
1241 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1242 /* but is not used as a pointer */
1243 /*-----------------------------------------------------------------*/
1245 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1247 debugLog ("%s\n", __FUNCTION__);
1248 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1251 /*-----------------------------------------------------------------*/
1252 /* rematable - will return 1 if the remat flag is set */
1253 /*-----------------------------------------------------------------*/
1255 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1257 debugLog ("%s\n", __FUNCTION__);
1261 /*-----------------------------------------------------------------*/
1262 /* notUsedInRemaining - not used or defined in remain of the block */
1263 /*-----------------------------------------------------------------*/
1265 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1267 debugLog ("%s\n", __FUNCTION__);
1268 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1269 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1272 /*-----------------------------------------------------------------*/
1273 /* allLRs - return true for all */
1274 /*-----------------------------------------------------------------*/
1276 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1278 debugLog ("%s\n", __FUNCTION__);
1282 /*-----------------------------------------------------------------*/
1283 /* liveRangesWith - applies function to a given set of live range */
1284 /*-----------------------------------------------------------------*/
1286 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1287 eBBlock * ebp, iCode * ic)
1292 debugLog ("%s\n", __FUNCTION__);
1293 if (!lrs || !lrs->size)
1296 for (i = 1; i < lrs->size; i++)
1299 if (!bitVectBitValue (lrs, i))
1302 /* if we don't find it in the live range
1303 hash table we are in serious trouble */
1304 if (!(sym = hTabItemWithKey (liveRanges, i)))
1306 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1307 "liveRangesWith could not find liveRange");
1311 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1312 addSetHead (&rset, sym);
1319 /*-----------------------------------------------------------------*/
1320 /* leastUsedLR - given a set determines which is the least used */
1321 /*-----------------------------------------------------------------*/
1323 leastUsedLR (set * sset)
1325 symbol *sym = NULL, *lsym = NULL;
1327 debugLog ("%s\n", __FUNCTION__);
1328 sym = lsym = setFirstItem (sset);
1333 for (; lsym; lsym = setNextItem (sset))
1336 /* if usage is the same then prefer
1337 the spill the smaller of the two */
1338 if (lsym->used == sym->used)
1339 if (getSize (lsym->type) < getSize (sym->type))
1343 if (lsym->used < sym->used)
1348 setToNull ((void *) &sset);
1353 /*-----------------------------------------------------------------*/
1354 /* noOverLap - will iterate through the list looking for over lap */
1355 /*-----------------------------------------------------------------*/
1357 noOverLap (set * itmpStack, symbol * fsym)
1360 debugLog ("%s\n", __FUNCTION__);
1363 for (sym = setFirstItem (itmpStack); sym;
1364 sym = setNextItem (itmpStack))
1366 if (sym->liveTo > fsym->liveFrom)
1374 /*-----------------------------------------------------------------*/
1375 /* isFree - will return 1 if the a free spil location is found */
1376 /*-----------------------------------------------------------------*/
1381 V_ARG (symbol **, sloc);
1382 V_ARG (symbol *, fsym);
1384 debugLog ("%s\n", __FUNCTION__);
1385 /* if already found */
1389 /* if it is free && and the itmp assigned to
1390 this does not have any overlapping live ranges
1391 with the one currently being assigned and
1392 the size can be accomodated */
1394 noOverLap (sym->usl.itmpStack, fsym) &&
1395 getSize (sym->type) >= getSize (fsym->type))
1404 /*-----------------------------------------------------------------*/
1405 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1406 /*-----------------------------------------------------------------*/
1408 spillLRWithPtrReg (symbol * forSym)
1414 debugLog ("%s\n", __FUNCTION__);
1415 if (!_G.regAssigned ||
1416 bitVectIsZero (_G.regAssigned))
1419 r0 = pic16_regWithIdx (R0_IDX);
1420 r1 = pic16_regWithIdx (R1_IDX);
1422 /* for all live ranges */
1423 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1424 lrsym = hTabNextItem (liveRanges, &k))
1428 /* if no registers assigned to it or
1430 /* if it does not overlap with this then
1431 not need to spill it */
1433 if (lrsym->isspilt || !lrsym->nRegs ||
1434 (lrsym->liveTo < forSym->liveFrom))
1437 /* go thru the registers : if it is either
1438 r0 or r1 then spil it */
1439 for (j = 0; j < lrsym->nRegs; j++)
1440 if (lrsym->regs[j] == r0 ||
1441 lrsym->regs[j] == r1)
1450 /*-----------------------------------------------------------------*/
1451 /* createStackSpil - create a location on the stack to spil */
1452 /*-----------------------------------------------------------------*/
1454 createStackSpil (symbol * sym)
1456 symbol *sloc = NULL;
1457 int useXstack, model, noOverlay;
1459 char slocBuffer[30];
1460 debugLog ("%s\n", __FUNCTION__);
1462 /* first go try and find a free one that is already
1463 existing on the stack */
1464 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1466 /* found a free one : just update & return */
1467 sym->usl.spillLoc = sloc;
1470 addSetHead (&sloc->usl.itmpStack, sym);
1474 /* could not then have to create one , this is the hard part
1475 we need to allocate this on the stack : this is really a
1476 hack!! but cannot think of anything better at this time */
1478 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1480 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1481 __FILE__, __LINE__);
1485 sloc = newiTemp (slocBuffer);
1487 /* set the type to the spilling symbol */
1488 sloc->type = copyLinkChain (sym->type);
1489 sloc->etype = getSpec (sloc->type);
1490 SPEC_SCLS (sloc->etype) = S_DATA;
1491 SPEC_EXTR (sloc->etype) = 0;
1492 SPEC_STAT (sloc->etype) = 0;
1494 /* we don't allow it to be allocated`
1495 onto the external stack since : so we
1496 temporarily turn it off ; we also
1497 turn off memory model to prevent
1498 the spil from going to the external storage
1499 and turn off overlaying
1502 useXstack = options.useXstack;
1503 model = options.model;
1504 noOverlay = options.noOverlay;
1505 options.noOverlay = 1;
1506 options.model = options.useXstack = 0;
1510 options.useXstack = useXstack;
1511 options.model = model;
1512 options.noOverlay = noOverlay;
1513 sloc->isref = 1; /* to prevent compiler warning */
1515 /* if it is on the stack then update the stack */
1516 if (IN_STACK (sloc->etype))
1518 currFunc->stack += getSize (sloc->type);
1519 _G.stackExtend += getSize (sloc->type);
1522 _G.dataExtend += getSize (sloc->type);
1524 /* add it to the _G.stackSpil set */
1525 addSetHead (&_G.stackSpil, sloc);
1526 sym->usl.spillLoc = sloc;
1529 /* add it to the set of itempStack set
1530 of the spill location */
1531 addSetHead (&sloc->usl.itmpStack, sym);
1535 /*-----------------------------------------------------------------*/
1536 /* isSpiltOnStack - returns true if the spil location is on stack */
1537 /*-----------------------------------------------------------------*/
1539 isSpiltOnStack (symbol * sym)
1543 debugLog ("%s\n", __FUNCTION__);
1550 /* if (sym->_G.stackSpil) */
1553 if (!sym->usl.spillLoc)
1556 etype = getSpec (sym->usl.spillLoc->type);
1557 if (IN_STACK (etype))
1563 /*-----------------------------------------------------------------*/
1564 /* spillThis - spils a specific operand */
1565 /*-----------------------------------------------------------------*/
1567 spillThis (symbol * sym)
1570 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1572 /* if this is rematerializable or has a spillLocation
1573 we are okay, else we need to create a spillLocation
1575 if (!(sym->remat || sym->usl.spillLoc))
1576 createStackSpil (sym);
1579 /* mark it has spilt & put it in the spilt set */
1581 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1583 bitVectUnSetBit (_G.regAssigned, sym->key);
1585 for (i = 0; i < sym->nRegs; i++)
1589 freeReg (sym->regs[i]);
1590 sym->regs[i] = NULL;
1593 /* if spilt on stack then free up r0 & r1
1594 if they could have been assigned to some
1596 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1599 spillLRWithPtrReg (sym);
1602 if (sym->usl.spillLoc && !sym->remat)
1603 sym->usl.spillLoc->allocreq = 1;
1607 /*-----------------------------------------------------------------*/
1608 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1609 /*-----------------------------------------------------------------*/
1611 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1613 bitVect *lrcs = NULL;
1617 debugLog ("%s\n", __FUNCTION__);
1618 /* get the spillable live ranges */
1619 lrcs = computeSpillable (ic);
1621 /* get all live ranges that are rematerizable */
1622 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1625 /* return the least used of these */
1626 return leastUsedLR (selectS);
1629 /* get live ranges with spillLocations in direct space */
1630 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1632 sym = leastUsedLR (selectS);
1633 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1634 sym->usl.spillLoc->rname :
1635 sym->usl.spillLoc->name));
1637 /* mark it as allocation required */
1638 sym->usl.spillLoc->allocreq = 1;
1642 /* if the symbol is local to the block then */
1643 if (forSym->liveTo < ebp->lSeq)
1646 /* check if there are any live ranges allocated
1647 to registers that are not used in this block */
1648 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1650 sym = leastUsedLR (selectS);
1651 /* if this is not rematerializable */
1660 /* check if there are any live ranges that not
1661 used in the remainder of the block */
1662 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1664 sym = leastUsedLR (selectS);
1667 sym->remainSpil = 1;
1674 /* find live ranges with spillocation && not used as pointers */
1675 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1678 sym = leastUsedLR (selectS);
1679 /* mark this as allocation required */
1680 sym->usl.spillLoc->allocreq = 1;
1684 /* find live ranges with spillocation */
1685 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1688 sym = leastUsedLR (selectS);
1689 sym->usl.spillLoc->allocreq = 1;
1693 /* couldn't find then we need to create a spil
1694 location on the stack , for which one? the least
1696 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1699 /* return a created spil location */
1700 sym = createStackSpil (leastUsedLR (selectS));
1701 sym->usl.spillLoc->allocreq = 1;
1705 /* this is an extreme situation we will spill
1706 this one : happens very rarely but it does happen */
1712 /*-----------------------------------------------------------------*/
1713 /* spilSomething - spil some variable & mark registers as free */
1714 /*-----------------------------------------------------------------*/
1716 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1721 debugLog ("%s\n", __FUNCTION__);
1722 /* get something we can spil */
1723 ssym = selectSpil (ic, ebp, forSym);
1725 /* mark it as spilt */
1727 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1729 /* mark it as not register assigned &
1730 take it away from the set */
1731 bitVectUnSetBit (_G.regAssigned, ssym->key);
1733 /* mark the registers as free */
1734 for (i = 0; i < ssym->nRegs; i++)
1736 freeReg (ssym->regs[i]);
1738 /* if spilt on stack then free up r0 & r1
1739 if they could have been assigned to as gprs */
1740 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1743 spillLRWithPtrReg (ssym);
1746 /* if this was a block level spil then insert push & pop
1747 at the start & end of block respectively */
1748 if (ssym->blockSpil)
1750 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1751 /* add push to the start of the block */
1752 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1753 ebp->sch->next : ebp->sch));
1754 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1755 /* add pop to the end of the block */
1756 addiCodeToeBBlock (ebp, nic, NULL);
1759 /* if spilt because not used in the remainder of the
1760 block then add a push before this instruction and
1761 a pop at the end of the block */
1762 if (ssym->remainSpil)
1765 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1766 /* add push just before this instruction */
1767 addiCodeToeBBlock (ebp, nic, ic);
1769 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1770 /* add pop to the end of the block */
1771 addiCodeToeBBlock (ebp, nic, NULL);
1780 /*-----------------------------------------------------------------*/
1781 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1782 /*-----------------------------------------------------------------*/
1784 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1789 debugLog ("%s\n", __FUNCTION__);
1791 /* try for a ptr type */
1792 if ((reg = allocReg (REG_PTR)))
1795 /* try for gpr type */
1796 if ((reg = allocReg (REG_GPR)))
1799 /* we have to spil */
1800 if (!spilSomething (ic, ebp, sym))
1803 /* make sure partially assigned registers aren't reused */
1804 for (j=0; j<=sym->nRegs; j++)
1806 sym->regs[j]->isFree = 0;
1808 /* this looks like an infinite loop but
1809 in really selectSpil will abort */
1813 /*-----------------------------------------------------------------*/
1814 /* getRegGpr - will try for GPR if not spil */
1815 /*-----------------------------------------------------------------*/
1817 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1822 debugLog ("%s\n", __FUNCTION__);
1824 /* try for gpr type */
1825 if ((reg = allocReg (REG_GPR)))
1828 if (!pic16_ptrRegReq)
1829 if ((reg = allocReg (REG_PTR)))
1832 /* we have to spil */
1833 if (!spilSomething (ic, ebp, sym))
1836 /* make sure partially assigned registers aren't reused */
1837 for (j=0; j<=sym->nRegs; j++)
1839 sym->regs[j]->isFree = 0;
1841 /* this looks like an infinite loop but
1842 in really selectSpil will abort */
1846 /*-----------------------------------------------------------------*/
1847 /* symHasReg - symbol has a given register */
1848 /*-----------------------------------------------------------------*/
1850 symHasReg (symbol * sym, regs * reg)
1854 debugLog ("%s\n", __FUNCTION__);
1855 for (i = 0; i < sym->nRegs; i++)
1856 if (sym->regs[i] == reg)
1862 /*-----------------------------------------------------------------*/
1863 /* deassignLRs - check the live to and if they have registers & are */
1864 /* not spilt then free up the registers */
1865 /*-----------------------------------------------------------------*/
1867 deassignLRs (iCode * ic, eBBlock * ebp)
1873 debugLog ("%s\n", __FUNCTION__);
1874 for (sym = hTabFirstItem (liveRanges, &k); sym;
1875 sym = hTabNextItem (liveRanges, &k))
1878 symbol *psym = NULL;
1879 /* if it does not end here */
1880 if (sym->liveTo > ic->seq)
1883 /* if it was spilt on stack then we can
1884 mark the stack spil location as free */
1889 sym->usl.spillLoc->isFree = 1;
1895 if (!bitVectBitValue (_G.regAssigned, sym->key))
1898 /* special case check if this is an IFX &
1899 the privious one was a pop and the
1900 previous one was not spilt then keep track
1902 if (ic->op == IFX && ic->prev &&
1903 ic->prev->op == IPOP &&
1904 !ic->prev->parmPush &&
1905 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1906 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1912 bitVectUnSetBit (_G.regAssigned, sym->key);
1914 /* if the result of this one needs registers
1915 and does not have it then assign it right
1917 if (IC_RESULT (ic) &&
1918 !(SKIP_IC2 (ic) || /* not a special icode */
1919 ic->op == JUMPTABLE ||
1924 POINTER_SET (ic)) &&
1925 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1926 result->liveTo > ic->seq && /* and will live beyond this */
1927 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1928 result->regType == sym->regType && /* same register types */
1929 result->nRegs && /* which needs registers */
1930 !result->isspilt && /* and does not already have them */
1932 !bitVectBitValue (_G.regAssigned, result->key) &&
1933 /* the number of free regs + number of regs in this LR
1934 can accomodate the what result Needs */
1935 ((nfreeRegsType (result->regType) +
1936 sym->nRegs) >= result->nRegs)
1940 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1942 result->regs[i] = sym->regs[i];
1944 result->regs[i] = getRegGpr (ic, ebp, result);
1946 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1950 /* free the remaining */
1951 for (; i < sym->nRegs; i++)
1955 if (!symHasReg (psym, sym->regs[i]))
1956 freeReg (sym->regs[i]);
1959 freeReg (sym->regs[i]);
1966 /*-----------------------------------------------------------------*/
1967 /* reassignLR - reassign this to registers */
1968 /*-----------------------------------------------------------------*/
1970 reassignLR (operand * op)
1972 symbol *sym = OP_SYMBOL (op);
1975 debugLog ("%s\n", __FUNCTION__);
1976 /* not spilt any more */
1977 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1978 bitVectUnSetBit (_G.spiltSet, sym->key);
1980 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1984 for (i = 0; i < sym->nRegs; i++)
1985 sym->regs[i]->isFree = 0;
1988 /*-----------------------------------------------------------------*/
1989 /* willCauseSpill - determines if allocating will cause a spill */
1990 /*-----------------------------------------------------------------*/
1992 willCauseSpill (int nr, int rt)
1994 debugLog ("%s\n", __FUNCTION__);
1995 /* first check if there are any avlb registers
1996 of te type required */
1999 /* special case for pointer type
2000 if pointer type not avlb then
2001 check for type gpr */
2002 if (nFreeRegs (rt) >= nr)
2004 if (nFreeRegs (REG_GPR) >= nr)
2009 if (pic16_ptrRegReq)
2011 if (nFreeRegs (rt) >= nr)
2016 if (nFreeRegs (REG_PTR) +
2017 nFreeRegs (REG_GPR) >= nr)
2022 debugLog (" ... yep it will (cause a spill)\n");
2023 /* it will cause a spil */
2027 /*-----------------------------------------------------------------*/
2028 /* positionRegs - the allocator can allocate same registers to res- */
2029 /* ult and operand, if this happens make sure they are in the same */
2030 /* position as the operand otherwise chaos results */
2031 /*-----------------------------------------------------------------*/
2033 positionRegs (symbol * result, symbol * opsym, int lineno)
2035 int count = min (result->nRegs, opsym->nRegs);
2036 int i, j = 0, shared = 0;
2038 debugLog ("%s\n", __FUNCTION__);
2039 /* if the result has been spilt then cannot share */
2044 /* first make sure that they actually share */
2045 for (i = 0; i < count; i++)
2047 for (j = 0; j < count; j++)
2049 if (result->regs[i] == opsym->regs[j] && i != j)
2059 regs *tmp = result->regs[i];
2060 result->regs[i] = result->regs[j];
2061 result->regs[j] = tmp;
2066 /*------------------------------------------------------------------*/
2067 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2068 /* it should either have registers or have beed spilled. Otherwise, */
2069 /* there was an uninitialized variable, so just spill this to get */
2070 /* the operand in a valid state. */
2071 /*------------------------------------------------------------------*/
2073 verifyRegsAssigned (operand *op, iCode * ic)
2078 if (!IS_ITEMP (op)) return;
2080 sym = OP_SYMBOL (op);
2081 if (sym->isspilt) return;
2082 if (!sym->nRegs) return;
2083 if (sym->regs[0]) return;
2085 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2086 sym->prereqv ? sym->prereqv->name : sym->name);
2091 /*-----------------------------------------------------------------*/
2092 /* serialRegAssign - serially allocate registers to the variables */
2093 /*-----------------------------------------------------------------*/
2095 serialRegAssign (eBBlock ** ebbs, int count)
2099 debugLog ("%s\n", __FUNCTION__);
2100 /* for all blocks */
2101 for (i = 0; i < count; i++)
2106 if (ebbs[i]->noPath &&
2107 (ebbs[i]->entryLabel != entryLabel &&
2108 ebbs[i]->entryLabel != returnLabel))
2111 /* of all instructions do */
2112 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2115 debugLog (" op: %s\n", decodeOp (ic->op));
2117 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2118 pic16_allocDirReg(IC_RESULT(ic));
2120 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2121 pic16_allocDirReg(IC_LEFT(ic));
2123 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2124 pic16_allocDirReg(IC_RIGHT(ic));
2126 /* if this is an ipop that means some live
2127 range will have to be assigned again */
2129 reassignLR (IC_LEFT (ic));
2131 /* if result is present && is a true symbol */
2132 if (IC_RESULT (ic) && ic->op != IFX &&
2133 IS_TRUE_SYMOP (IC_RESULT (ic)))
2134 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2136 /* take away registers from live
2137 ranges that end at this instruction */
2138 deassignLRs (ic, ebbs[i]);
2140 /* some don't need registers */
2141 if (SKIP_IC2 (ic) ||
2142 ic->op == JUMPTABLE ||
2146 (IC_RESULT (ic) && POINTER_SET (ic)))
2149 /* now we need to allocate registers
2150 only for the result */
2153 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2159 /* if it does not need or is spilt
2160 or is already assigned to registers
2161 or will not live beyond this instructions */
2164 bitVectBitValue (_G.regAssigned, sym->key) ||
2165 sym->liveTo <= ic->seq)
2168 /* if some liverange has been spilt at the block level
2169 and this one live beyond this block then spil this
2171 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2176 /* if trying to allocate this will cause
2177 a spill and there is nothing to spill
2178 or this one is rematerializable then
2180 willCS = willCauseSpill (sym->nRegs, sym->regType);
2181 spillable = computeSpillable (ic);
2183 (willCS && bitVectIsZero (spillable)))
2191 /* if it has a spillocation & is used less than
2192 all other live ranges then spill this */
2194 if (sym->usl.spillLoc) {
2195 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2196 allLRs, ebbs[i], ic));
2197 if (leastUsed && leastUsed->used > sym->used) {
2202 /* if none of the liveRanges have a spillLocation then better
2203 to spill this one than anything else already assigned to registers */
2204 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2205 /* if this is local to this block then we might find a block spil */
2206 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2214 if (ic->op == RECEIVE)
2215 debugLog ("When I get clever, I'll optimize the receive logic\n");
2217 /* if we need ptr regs for the right side
2219 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2220 <= (unsigned) PTRSIZE)
2225 /* else we assign registers to it */
2226 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2228 debugLog (" %d - \n", __LINE__);
2230 bitVectDebugOn(_G.regAssigned, debugF);
2232 for (j = 0; j < sym->nRegs; j++)
2234 if (sym->regType == REG_PTR)
2235 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2237 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2239 /* if the allocation falied which means
2240 this was spilt then break */
2244 debugLog (" %d - \n", __LINE__);
2246 /* if it shares registers with operands make sure
2247 that they are in the same position */
2248 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2249 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2250 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2251 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2252 /* do the same for the right operand */
2253 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2254 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2255 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2256 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2258 debugLog (" %d - \n", __LINE__);
2261 debugLog (" %d - \n", __LINE__);
2270 /* Check for and fix any problems with uninitialized operands */
2271 for (i = 0; i < count; i++)
2275 if (ebbs[i]->noPath &&
2276 (ebbs[i]->entryLabel != entryLabel &&
2277 ebbs[i]->entryLabel != returnLabel))
2280 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2287 verifyRegsAssigned (IC_COND (ic), ic);
2291 if (ic->op == JUMPTABLE)
2293 verifyRegsAssigned (IC_JTCOND (ic), ic);
2297 verifyRegsAssigned (IC_RESULT (ic), ic);
2298 verifyRegsAssigned (IC_LEFT (ic), ic);
2299 verifyRegsAssigned (IC_RIGHT (ic), ic);
2305 /*-----------------------------------------------------------------*/
2306 /* rUmaskForOp :- returns register mask for an operand */
2307 /*-----------------------------------------------------------------*/
2309 rUmaskForOp (operand * op)
2315 debugLog ("%s\n", __FUNCTION__);
2316 /* only temporaries are assigned registers */
2320 sym = OP_SYMBOL (op);
2322 /* if spilt or no registers assigned to it
2324 if (sym->isspilt || !sym->nRegs)
2327 rumask = newBitVect (pic16_nRegs);
2329 for (j = 0; j < sym->nRegs; j++)
2331 rumask = bitVectSetBit (rumask,
2332 sym->regs[j]->rIdx);
2338 /*-----------------------------------------------------------------*/
2339 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2340 /*-----------------------------------------------------------------*/
2342 regsUsedIniCode (iCode * ic)
2344 bitVect *rmask = newBitVect (pic16_nRegs);
2346 debugLog ("%s\n", __FUNCTION__);
2347 /* do the special cases first */
2350 rmask = bitVectUnion (rmask,
2351 rUmaskForOp (IC_COND (ic)));
2355 /* for the jumptable */
2356 if (ic->op == JUMPTABLE)
2358 rmask = bitVectUnion (rmask,
2359 rUmaskForOp (IC_JTCOND (ic)));
2364 /* of all other cases */
2366 rmask = bitVectUnion (rmask,
2367 rUmaskForOp (IC_LEFT (ic)));
2371 rmask = bitVectUnion (rmask,
2372 rUmaskForOp (IC_RIGHT (ic)));
2375 rmask = bitVectUnion (rmask,
2376 rUmaskForOp (IC_RESULT (ic)));
2382 /*-----------------------------------------------------------------*/
2383 /* createRegMask - for each instruction will determine the regsUsed */
2384 /*-----------------------------------------------------------------*/
2386 createRegMask (eBBlock ** ebbs, int count)
2390 debugLog ("%s\n", __FUNCTION__);
2391 /* for all blocks */
2392 for (i = 0; i < count; i++)
2396 if (ebbs[i]->noPath &&
2397 (ebbs[i]->entryLabel != entryLabel &&
2398 ebbs[i]->entryLabel != returnLabel))
2401 /* for all instructions */
2402 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2407 if (SKIP_IC2 (ic) || !ic->rlive)
2410 /* first mark the registers used in this
2412 ic->rUsed = regsUsedIniCode (ic);
2413 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2415 /* now create the register mask for those
2416 registers that are in use : this is a
2417 super set of ic->rUsed */
2418 ic->rMask = newBitVect (pic16_nRegs + 1);
2420 /* for all live Ranges alive at this point */
2421 for (j = 1; j < ic->rlive->size; j++)
2426 /* if not alive then continue */
2427 if (!bitVectBitValue (ic->rlive, j))
2430 /* find the live range we are interested in */
2431 if (!(sym = hTabItemWithKey (liveRanges, j)))
2433 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2434 "createRegMask cannot find live range");
2438 /* if no register assigned to it */
2439 if (!sym->nRegs || sym->isspilt)
2442 /* for all the registers allocated to it */
2443 for (k = 0; k < sym->nRegs; k++)
2446 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2452 /*-----------------------------------------------------------------*/
2453 /* rematStr - returns the rematerialized string for a remat var */
2454 /*-----------------------------------------------------------------*/
2456 rematStr (symbol * sym)
2459 iCode *ic = sym->rematiCode;
2460 symbol *psym = NULL;
2462 debugLog ("%s\n", __FUNCTION__);
2464 //printf ("%s\n", s);
2466 /* if plus or minus print the right hand side */
2468 if (ic->op == '+' || ic->op == '-') {
2470 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2472 sprintf (s, "(%s %c 0x%04x)",
2473 OP_SYMBOL (IC_LEFT (ric))->rname,
2475 (int) operandLitValue (IC_RIGHT (ic)));
2478 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2480 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2481 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2486 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2487 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2489 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2494 /*-----------------------------------------------------------------*/
2495 /* rematStr - returns the rematerialized string for a remat var */
2496 /*-----------------------------------------------------------------*/
2498 rematStr (symbol * sym)
2501 iCode *ic = sym->rematiCode;
2503 debugLog ("%s\n", __FUNCTION__);
2508 /* if plus or minus print the right hand side */
2510 if (ic->op == '+' || ic->op == '-') {
2511 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2514 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2518 if (ic->op == '+' || ic->op == '-')
2520 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2521 sprintf (s, "(%s %c 0x%04x)",
2522 OP_SYMBOL (IC_LEFT (ric))->rname,
2524 (int) operandLitValue (IC_RIGHT (ic)));
2527 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2529 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2533 /* we reached the end */
2534 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2538 printf ("%s\n", buffer);
2543 /*-----------------------------------------------------------------*/
2544 /* regTypeNum - computes the type & number of registers required */
2545 /*-----------------------------------------------------------------*/
2553 debugLog ("%s\n", __FUNCTION__);
2554 /* for each live range do */
2555 for (sym = hTabFirstItem (liveRanges, &k); sym;
2556 sym = hTabNextItem (liveRanges, &k)) {
2558 debugLog (" %d - %s\n", __LINE__, sym->rname);
2559 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2561 /* if used zero times then no registers needed */
2562 if ((sym->liveTo - sym->liveFrom) == 0)
2566 /* if the live range is a temporary */
2569 debugLog (" %d - itemp register\n", __LINE__);
2571 /* if the type is marked as a conditional */
2572 if (sym->regType == REG_CND)
2575 /* if used in return only then we don't
2577 if (sym->ruonly || sym->accuse) {
2578 if (IS_AGGREGATE (sym->type) || sym->isptr)
2579 sym->type = aggrToPtr (sym->type, FALSE);
2580 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2585 /* if the symbol has only one definition &
2586 that definition is a get_pointer and the
2587 pointer we are getting is rematerializable and
2590 if (bitVectnBitsOn (sym->defs) == 1 &&
2591 (ic = hTabItemWithKey (iCodehTab,
2592 bitVectFirstBit (sym->defs))) &&
2594 !IS_BITVAR (sym->etype) &&
2595 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2597 if (ptrPseudoSymSafe (sym, ic)) {
2601 debugLog (" %d - \n", __LINE__);
2603 /* create a psuedo symbol & force a spil */
2604 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2605 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2606 psym->type = sym->type;
2607 psym->etype = sym->etype;
2608 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2609 strcpy (psym->rname, psym->name);
2611 sym->usl.spillLoc = psym;
2615 /* if in data space or idata space then try to
2616 allocate pointer register */
2620 /* if not then we require registers */
2621 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2622 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2623 getSize (sym->type));
2627 if(IS_PTR_CONST (sym->type)) {
2629 if(IS_CODEPTR (sym->type)) {
2631 // what IS this ???? (HJD)
2632 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2633 sym->nRegs = 3; // patch 14
2636 if (sym->nRegs > 4) {
2637 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2638 printTypeChain (sym->type, stderr);
2639 fprintf (stderr, "\n");
2642 /* determine the type of register required */
2643 if (sym->nRegs == 1 &&
2644 IS_PTR (sym->type) &&
2646 sym->regType = REG_PTR;
2648 sym->regType = REG_GPR;
2651 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2655 /* for the first run we don't provide */
2656 /* registers for true symbols we will */
2657 /* see how things go */
2662 static DEFSETFUNC (markRegFree)
2664 ((regs *)item)->isFree = 1;
2669 DEFSETFUNC (pic16_deallocReg)
2671 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2672 ((regs *)item)->isFree = 1;
2673 ((regs *)item)->wasUsed = 0;
2677 /*-----------------------------------------------------------------*/
2678 /* freeAllRegs - mark all registers as free */
2679 /*-----------------------------------------------------------------*/
2681 pic16_freeAllRegs ()
2683 debugLog ("%s\n", __FUNCTION__);
2685 applyToSet(pic16_dynAllocRegs,markRegFree);
2686 applyToSet(pic16_dynStackRegs,markRegFree);
2689 /*-----------------------------------------------------------------*/
2690 /*-----------------------------------------------------------------*/
2692 pic16_deallocateAllRegs ()
2694 debugLog ("%s\n", __FUNCTION__);
2696 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2700 /*-----------------------------------------------------------------*/
2701 /* deallocStackSpil - this will set the stack pointer back */
2702 /*-----------------------------------------------------------------*/
2704 DEFSETFUNC (deallocStackSpil)
2708 debugLog ("%s\n", __FUNCTION__);
2713 /*-----------------------------------------------------------------*/
2714 /* farSpacePackable - returns the packable icode for far variables */
2715 /*-----------------------------------------------------------------*/
2717 farSpacePackable (iCode * ic)
2721 debugLog ("%s\n", __FUNCTION__);
2722 /* go thru till we find a definition for the
2723 symbol on the right */
2724 for (dic = ic->prev; dic; dic = dic->prev)
2727 /* if the definition is a call then no */
2728 if ((dic->op == CALL || dic->op == PCALL) &&
2729 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2734 /* if shift by unknown amount then not */
2735 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2736 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2739 /* if pointer get and size > 1 */
2740 if (POINTER_GET (dic) &&
2741 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2744 if (POINTER_SET (dic) &&
2745 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2748 /* if any three is a true symbol in far space */
2749 if (IC_RESULT (dic) &&
2750 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2751 isOperandInFarSpace (IC_RESULT (dic)))
2754 if (IC_RIGHT (dic) &&
2755 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2756 isOperandInFarSpace (IC_RIGHT (dic)) &&
2757 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2760 if (IC_LEFT (dic) &&
2761 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2762 isOperandInFarSpace (IC_LEFT (dic)) &&
2763 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2766 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2768 if ((dic->op == LEFT_OP ||
2769 dic->op == RIGHT_OP ||
2771 IS_OP_LITERAL (IC_RIGHT (dic)))
2781 /*-----------------------------------------------------------------*/
2782 /* packRegsForAssign - register reduction for assignment */
2783 /*-----------------------------------------------------------------*/
2785 packRegsForAssign (iCode * ic, eBBlock * ebp)
2790 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2791 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2792 debugAopGet (" result:", IC_RESULT (ic));
2793 debugAopGet (" left:", IC_LEFT (ic));
2794 debugAopGet (" right:", IC_RIGHT (ic));
2796 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2799 /* if this is at an absolute address, then get the address. */
2800 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2801 if(PIC16_IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2802 debugLog (" %d - found config word declaration\n", __LINE__);
2803 if(IS_VALOP(IC_RIGHT(ic))) {
2804 debugLog (" setting config word to %x\n",
2805 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2807 fprintf(stderr, "%s:%d setting config word to %x\n", __FILE__, __LINE__,
2808 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2810 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2811 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2815 debugLog(" %d\n", __LINE__);
2817 /* remove the assignment from the iCode chain. */
2819 remiCodeFromeBBlock (ebp, ic);
2820 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2821 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2828 debugLog(" %d - actuall processing\n", __LINE__ );
2830 if (!IS_ITEMP (IC_RESULT (ic))) {
2831 pic16_allocDirReg(IC_RESULT (ic));
2832 debugLog (" %d - result is not temp\n", __LINE__);
2836 /* See BUGLOG0001 - VR */
2838 if (!IS_ITEMP (IC_RIGHT (ic))) {
2839 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2840 pic16_allocDirReg(IC_RIGHT (ic));
2845 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2846 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2848 debugLog (" %d - not packing - right side fails \n", __LINE__);
2852 /* if the true symbol is defined in far space or on stack
2853 then we should not since this will increase register pressure */
2854 if (isOperandInFarSpace (IC_RESULT (ic)))
2856 if ((dic = farSpacePackable (ic)))
2863 /* find the definition of iTempNN scanning backwards if we find a
2864 a use of the true symbol before we find the definition then
2866 for (dic = ic->prev; dic; dic = dic->prev)
2869 /* if there is a function call and this is
2870 a parameter & not my parameter then don't pack it */
2871 if ((dic->op == CALL || dic->op == PCALL) &&
2872 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2873 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2875 debugLog (" %d - \n", __LINE__);
2884 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2886 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2887 IS_OP_VOLATILE (IC_RESULT (dic)))
2889 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2895 if( IS_SYMOP( IC_RESULT(dic)) &&
2896 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2898 debugLog (" %d - result is bitfield\n", __LINE__);
2904 if (IS_SYMOP (IC_RESULT (dic)) &&
2905 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2907 /* A previous result was assigned to the same register - we'll our definition */
2908 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2909 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2910 if (POINTER_SET (dic))
2916 if (IS_SYMOP (IC_RIGHT (dic)) &&
2917 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2918 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2920 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2925 if (IS_SYMOP (IC_LEFT (dic)) &&
2926 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2927 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2929 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2934 if (POINTER_SET (dic) &&
2935 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2937 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2945 return 0; /* did not find */
2948 /* This code is taken from the hc08 port. Do not know
2949 * if it fits for pic16, but I leave it here just in case */
2951 /* if assignment then check that right is not a bit */
2952 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2953 sym_link *etype = operandType (IC_RIGHT (dic));
2955 if (IS_BITFIELD (etype)) {
2956 /* if result is a bit too then it's ok */
2957 etype = operandType (IC_RESULT (dic));
2958 if (!IS_BITFIELD (etype)) {
2959 debugLog(" %d bitfields\n");
2966 /* if the result is on stack or iaccess then it must be
2967 the same atleast one of the operands */
2968 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2969 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2973 /* clear the onStack flag, the port doesn't support it yet! FIXME */
2974 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2975 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2979 /* the operation has only one symbol
2980 operator then we can pack */
2981 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2982 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2985 if (!((IC_LEFT (dic) &&
2986 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2988 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2992 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2993 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2994 /* found the definition */
2995 /* replace the result with the result of */
2996 /* this assignment and remove this assignment */
2997 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2998 IC_RESULT (dic) = IC_RESULT (ic);
3000 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3002 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3004 /* delete from liverange table also
3005 delete from all the points inbetween and the new
3007 for (sic = dic; sic != ic; sic = sic->next)
3009 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3010 if (IS_ITEMP (IC_RESULT (dic)))
3011 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3014 remiCodeFromeBBlock (ebp, ic);
3015 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3017 debugLog(" %d\n", __LINE__ );
3018 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3019 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3027 #define NO_packRegsForAccUse
3028 #define NO_packRegsForSupport
3029 #define NO_packRegsForOneuse
3030 #define NO_cast_peep
3035 #ifndef NO_packRegsForSupport
3036 /*-----------------------------------------------------------------*/
3037 /* findAssignToSym : scanning backwards looks for first assig found */
3038 /*-----------------------------------------------------------------*/
3040 findAssignToSym (operand * op, iCode * ic)
3044 debugLog ("%s\n", __FUNCTION__);
3045 for (dic = ic->prev; dic; dic = dic->prev)
3048 /* if definition by assignment */
3049 if (dic->op == '=' &&
3050 !POINTER_SET (dic) &&
3051 IC_RESULT (dic)->key == op->key
3052 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3056 /* we are interested only if defined in far space */
3057 /* or in stack space in case of + & - */
3059 /* if assigned to a non-symbol then return
3061 if (!IS_SYMOP (IC_RIGHT (dic)))
3064 /* if the symbol is in far space then
3066 if (isOperandInFarSpace (IC_RIGHT (dic)))
3069 /* for + & - operations make sure that
3070 if it is on the stack it is the same
3071 as one of the three operands */
3072 if ((ic->op == '+' || ic->op == '-') &&
3073 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3077 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3078 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3081 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3082 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3083 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3091 /* if we find an usage then we cannot delete it */
3092 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3095 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3098 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3102 /* now make sure that the right side of dic
3103 is not defined between ic & dic */
3106 iCode *sic = dic->next;
3108 for (; sic != ic; sic = sic->next)
3109 if (IC_RESULT (sic) &&
3110 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3121 #ifndef NO_packRegsForSupport
3122 /*-----------------------------------------------------------------*/
3123 /* packRegsForSupport :- reduce some registers for support calls */
3124 /*-----------------------------------------------------------------*/
3126 packRegsForSupport (iCode * ic, eBBlock * ebp)
3130 debugLog ("%s\n", __FUNCTION__);
3131 /* for the left & right operand :- look to see if the
3132 left was assigned a true symbol in far space in that
3133 case replace them */
3134 if (IS_ITEMP (IC_LEFT (ic)) &&
3135 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3137 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3143 debugAopGet ("removing left:", IC_LEFT (ic));
3145 /* found it we need to remove it from the
3147 for (sic = dic; sic != ic; sic = sic->next)
3148 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3150 IC_LEFT (ic)->operand.symOperand =
3151 IC_RIGHT (dic)->operand.symOperand;
3152 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3153 remiCodeFromeBBlock (ebp, dic);
3154 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3155 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3159 /* do the same for the right operand */
3162 IS_ITEMP (IC_RIGHT (ic)) &&
3163 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3165 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3171 /* if this is a subtraction & the result
3172 is a true symbol in far space then don't pack */
3173 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3175 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3176 if (IN_FARSPACE (SPEC_OCLS (etype)))
3180 debugAopGet ("removing right:", IC_RIGHT (ic));
3182 /* found it we need to remove it from the
3184 for (sic = dic; sic != ic; sic = sic->next)
3185 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3187 IC_RIGHT (ic)->operand.symOperand =
3188 IC_RIGHT (dic)->operand.symOperand;
3189 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3191 remiCodeFromeBBlock (ebp, dic);
3192 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3193 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3202 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3204 #ifndef NO_packRegsForOneuse
3205 /*-----------------------------------------------------------------*/
3206 /* packRegsForOneuse : - will reduce some registers for single Use */
3207 /*-----------------------------------------------------------------*/
3209 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3214 debugLog ("%s\n", __FUNCTION__);
3215 /* if returning a literal then do nothing */
3219 /* only upto 2 bytes since we cannot predict
3220 the usage of b, & acc */
3221 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3226 /* this routine will mark the a symbol as used in one
3227 instruction use only && if the definition is local
3228 (ie. within the basic block) && has only one definition &&
3229 that definition is either a return value from a
3230 function or does not contain any variables in
3232 uses = bitVectCopy (OP_USES (op));
3233 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3234 if (!bitVectIsZero (uses)) /* has other uses */
3237 /* if it has only one defintion */
3238 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3239 return NULL; /* has more than one definition */
3241 /* get that definition */
3243 hTabItemWithKey (iCodehTab,
3244 bitVectFirstBit (OP_DEFS (op)))))
3247 /* found the definition now check if it is local */
3248 if (dic->seq < ebp->fSeq ||
3249 dic->seq > ebp->lSeq)
3250 return NULL; /* non-local */
3252 /* now check if it is the return from
3254 if (dic->op == CALL || dic->op == PCALL)
3256 if (ic->op != SEND && ic->op != RETURN &&
3257 !POINTER_SET(ic) && !POINTER_GET(ic))
3259 OP_SYMBOL (op)->ruonly = 1;
3266 /* otherwise check that the definition does
3267 not contain any symbols in far space */
3268 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3269 isOperandInFarSpace (IC_RIGHT (dic)) ||
3270 IS_OP_RUONLY (IC_LEFT (ic)) ||
3271 IS_OP_RUONLY (IC_RIGHT (ic)))
3276 /* if pointer set then make sure the pointer
3278 if (POINTER_SET (dic) &&
3279 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3282 if (POINTER_GET (dic) &&
3283 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3288 /* also make sure the intervenening instructions
3289 don't have any thing in far space */
3290 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3293 /* if there is an intervening function call then no */
3294 if (dic->op == CALL || dic->op == PCALL)
3296 /* if pointer set then make sure the pointer
3298 if (POINTER_SET (dic) &&
3299 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3302 if (POINTER_GET (dic) &&
3303 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3306 /* if address of & the result is remat then okay */
3307 if (dic->op == ADDRESS_OF &&
3308 OP_SYMBOL (IC_RESULT (dic))->remat)
3311 /* if operand has size of three or more & this
3312 operation is a '*','/' or '%' then 'b' may
3314 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3315 getSize (operandType (op)) >= 3)
3318 /* if left or right or result is in far space */
3319 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3320 isOperandInFarSpace (IC_RIGHT (dic)) ||
3321 isOperandInFarSpace (IC_RESULT (dic)) ||
3322 IS_OP_RUONLY (IC_LEFT (dic)) ||
3323 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3324 IS_OP_RUONLY (IC_RESULT (dic)))
3330 OP_SYMBOL (op)->ruonly = 1;
3337 /*-----------------------------------------------------------------*/
3338 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3339 /*-----------------------------------------------------------------*/
3341 isBitwiseOptimizable (iCode * ic)
3343 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3344 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3346 debugLog ("%s\n", __FUNCTION__);
3347 /* bitwise operations are considered optimizable
3348 under the following conditions (Jean-Louis VERN)
3360 if (IS_LITERAL (rtype) ||
3361 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3368 #ifndef NO_packRegsForAccUse
3370 /*-----------------------------------------------------------------*/
3371 /* packRegsForAccUse - pack registers for acc use */
3372 /*-----------------------------------------------------------------*/
3374 packRegsForAccUse (iCode * ic)
3378 debugLog ("%s\n", __FUNCTION__);
3380 /* if this is an aggregate, e.g. a one byte char array */
3381 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3384 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3386 /* if + or - then it has to be one byte result */
3387 if ((ic->op == '+' || ic->op == '-')
3388 && getSize (operandType (IC_RESULT (ic))) > 1)
3391 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3392 /* if shift operation make sure right side is not a literal */
3393 if (ic->op == RIGHT_OP &&
3394 (isOperandLiteral (IC_RIGHT (ic)) ||
3395 getSize (operandType (IC_RESULT (ic))) > 1))
3398 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3399 if (ic->op == LEFT_OP &&
3400 (isOperandLiteral (IC_RIGHT (ic)) ||
3401 getSize (operandType (IC_RESULT (ic))) > 1))
3404 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3405 if (IS_BITWISE_OP (ic) &&
3406 getSize (operandType (IC_RESULT (ic))) > 1)
3410 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3411 /* has only one definition */
3412 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3415 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3416 /* has only one use */
3417 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3420 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3421 /* and the usage immediately follows this iCode */
3422 if (!(uic = hTabItemWithKey (iCodehTab,
3423 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3426 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3427 if (ic->next != uic)
3430 /* if it is a conditional branch then we definitely can */
3434 if (uic->op == JUMPTABLE)
3437 /* if the usage is not is an assignment
3438 or an arithmetic / bitwise / shift operation then not */
3439 if (POINTER_SET (uic) &&
3440 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3443 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3444 if (uic->op != '=' &&
3445 !IS_ARITHMETIC_OP (uic) &&
3446 !IS_BITWISE_OP (uic) &&
3447 uic->op != LEFT_OP &&
3448 uic->op != RIGHT_OP)
3451 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3452 /* if used in ^ operation then make sure right is not a
3454 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3457 /* if shift operation make sure right side is not a literal */
3458 if (uic->op == RIGHT_OP &&
3459 (isOperandLiteral (IC_RIGHT (uic)) ||
3460 getSize (operandType (IC_RESULT (uic))) > 1))
3463 if (uic->op == LEFT_OP &&
3464 (isOperandLiteral (IC_RIGHT (uic)) ||
3465 getSize (operandType (IC_RESULT (uic))) > 1))
3468 /* make sure that the result of this icode is not on the
3469 stack, since acc is used to compute stack offset */
3470 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3471 OP_SYMBOL (IC_RESULT (uic))->onStack)
3474 /* if either one of them in far space then we cannot */
3475 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3476 isOperandInFarSpace (IC_LEFT (uic))) ||
3477 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3478 isOperandInFarSpace (IC_RIGHT (uic))))
3481 /* if the usage has only one operand then we can */
3482 if (IC_LEFT (uic) == NULL ||
3483 IC_RIGHT (uic) == NULL)
3486 /* make sure this is on the left side if not
3487 a '+' since '+' is commutative */
3488 if (ic->op != '+' &&
3489 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3493 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3494 /* if one of them is a literal then we can */
3495 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3496 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3497 (getSize (operandType (IC_RESULT (uic))) <= 1))
3499 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3504 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3505 /* if the other one is not on stack then we can */
3506 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3507 (IS_ITEMP (IC_RIGHT (uic)) ||
3508 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3509 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3512 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3513 (IS_ITEMP (IC_LEFT (uic)) ||
3514 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3515 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3521 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3522 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3529 /*-----------------------------------------------------------------*/
3530 /* packForPush - hueristics to reduce iCode for pushing */
3531 /*-----------------------------------------------------------------*/
3533 packForReceive (iCode * ic, eBBlock * ebp)
3537 debugLog ("%s\n", __FUNCTION__);
3538 debugAopGet (" result:", IC_RESULT (ic));
3539 debugAopGet (" left:", IC_LEFT (ic));
3540 debugAopGet (" right:", IC_RIGHT (ic));
3545 for (dic = ic->next; dic; dic = dic->next)
3550 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3551 debugLog (" used on left\n");
3552 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3553 debugLog (" used on right\n");
3554 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3555 debugLog (" used on result\n");
3557 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3558 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3563 debugLog (" hey we can remove this unnecessary assign\n");
3565 /*-----------------------------------------------------------------*/
3566 /* packForPush - hueristics to reduce iCode for pushing */
3567 /*-----------------------------------------------------------------*/
3569 packForPush (iCode * ic, eBBlock * ebp)
3573 debugLog ("%s\n", __FUNCTION__);
3574 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3577 /* must have only definition & one usage */
3578 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3579 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3582 /* find the definition */
3583 if (!(dic = hTabItemWithKey (iCodehTab,
3584 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3587 if (dic->op != '=' || POINTER_SET (dic))
3590 /* we now we know that it has one & only one def & use
3591 and the that the definition is an assignment */
3592 IC_LEFT (ic) = IC_RIGHT (dic);
3594 remiCodeFromeBBlock (ebp, dic);
3595 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3596 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3599 static void printSymType(char * str, sym_link *sl)
3601 if(!pic16_ralloc_debug)return;
3603 debugLog (" %s Symbol type: ",str);
3604 printTypeChain( sl, debugF);
3608 /*-----------------------------------------------------------------*/
3609 /* some debug code to print the symbol S_TYPE. Note that
3610 * the function checkSClass in src/SDCCsymt.c dinks with
3611 * the S_TYPE in ways the PIC port doesn't fully like...*/
3612 /*-----------------------------------------------------------------*/
3613 static void isData(sym_link *sl)
3617 if(!pic16_ralloc_debug)return;
3624 for ( ; sl; sl=sl->next) {
3626 switch (SPEC_SCLS(sl)) {
3627 case S_DATA: fprintf (of, "data "); break;
3628 case S_XDATA: fprintf (of, "xdata "); break;
3629 case S_SFR: fprintf (of, "sfr "); break;
3630 case S_SBIT: fprintf (of, "sbit "); break;
3631 case S_CODE: fprintf (of, "code "); break;
3632 case S_IDATA: fprintf (of, "idata "); break;
3633 case S_PDATA: fprintf (of, "pdata "); break;
3634 case S_LITERAL: fprintf (of, "literal "); break;
3635 case S_STACK: fprintf (of, "stack "); break;
3636 case S_XSTACK: fprintf (of, "xstack "); break;
3637 case S_BIT: fprintf (of, "bit "); break;
3638 case S_EEPROM: fprintf (of, "eeprom "); break;
3647 /*--------------------------------------------------------------------*/
3648 /* pic16_packRegisters - does some transformations to reduce */
3649 /* register pressure */
3651 /*--------------------------------------------------------------------*/
3653 pic16_packRegisters (eBBlock * ebp)
3658 debugLog ("%s\n", __FUNCTION__);
3664 /* look for assignments of the form */
3665 /* iTempNN = TRueSym (someoperation) SomeOperand */
3667 /* TrueSym := iTempNN:1 */
3668 for (ic = ebp->sch; ic; ic = ic->next)
3670 // debugLog("%d\n", __LINE__);
3671 /* find assignment of the form TrueSym := iTempNN:1 */
3672 /* see BUGLOG0001 for workaround with the CAST - VR */
3673 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3674 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3675 change += packRegsForAssign (ic, ebp);
3679 if (POINTER_SET (ic))
3680 debugLog ("pointer is set\n");
3681 debugAopGet (" result:", IC_RESULT (ic));
3682 debugAopGet (" left:", IC_LEFT (ic));
3683 debugAopGet (" right:", IC_RIGHT (ic));
3692 for (ic = ebp->sch; ic; ic = ic->next) {
3694 if(IS_SYMOP ( IC_LEFT(ic))) {
3695 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3697 debugAopGet ("x left:", IC_LEFT (ic));
3699 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3701 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3703 debugLog (" is a pointer\n");
3705 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3706 debugLog (" is a ptr\n");
3708 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3709 debugLog (" is volatile\n");
3713 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3714 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3715 pic16_allocDirReg(IC_LEFT (ic));
3718 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3721 if(IS_SYMOP ( IC_RIGHT(ic))) {
3722 debugAopGet (" right:", IC_RIGHT (ic));
3723 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3726 if(IS_SYMOP ( IC_RESULT(ic))) {
3727 debugAopGet (" result:", IC_RESULT (ic));
3728 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3731 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3732 debugAopGet (" right:", IC_RIGHT (ic));
3733 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3734 // pic16_allocDirReg(IC_RIGHT(ic));
3737 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3738 debugAopGet (" result:", IC_RESULT (ic));
3739 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3740 // pic16_allocDirReg(IC_RESULT(ic));
3744 if (POINTER_SET (ic))
3745 debugLog (" %d - Pointer set\n", __LINE__);
3748 /* if this is an itemp & result of a address of a true sym
3749 then mark this as rematerialisable */
3750 if (ic->op == ADDRESS_OF &&
3751 IS_ITEMP (IC_RESULT (ic)) &&
3752 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3753 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3754 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3757 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3759 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3760 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3761 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3765 /* if straight assignment then carry remat flag if
3766 this is the only definition */
3767 if (ic->op == '=' &&
3768 !POINTER_SET (ic) &&
3769 IS_SYMOP (IC_RIGHT (ic)) &&
3770 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3771 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3773 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3775 OP_SYMBOL (IC_RESULT (ic))->remat =
3776 OP_SYMBOL (IC_RIGHT (ic))->remat;
3777 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3778 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3781 /* if this is a +/- operation with a rematerizable
3782 then mark this as rematerializable as well */
3783 if ((ic->op == '+' || ic->op == '-') &&
3784 (IS_SYMOP (IC_LEFT (ic)) &&
3785 IS_ITEMP (IC_RESULT (ic)) &&
3786 OP_SYMBOL (IC_LEFT (ic))->remat &&
3787 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3788 IS_OP_LITERAL (IC_RIGHT (ic))))
3790 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3792 operandLitValue (IC_RIGHT (ic));
3793 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3794 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3795 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3798 /* mark the pointer usages */
3799 if (POINTER_SET (ic))
3801 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3802 debugLog (" marking as a pointer (set) =>");
3803 debugAopGet (" result:", IC_RESULT (ic));
3805 if (POINTER_GET (ic))
3807 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3808 debugLog (" marking as a pointer (get) =>");
3809 debugAopGet (" left:", IC_LEFT (ic));
3812 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3816 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3817 /* if we are using a symbol on the stack
3818 then we should say pic16_ptrRegReq */
3819 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3820 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3821 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3822 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3823 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3824 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3828 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3829 if (IS_SYMOP (IC_LEFT (ic)))
3830 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3831 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3832 if (IS_SYMOP (IC_RIGHT (ic)))
3833 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3834 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3835 if (IS_SYMOP (IC_RESULT (ic)))
3836 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3837 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3840 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3844 /* if the condition of an if instruction
3845 is defined in the previous instruction then
3846 mark the itemp as a conditional */
3847 if ((IS_CONDITIONAL (ic) ||
3848 ((ic->op == BITWISEAND ||
3851 isBitwiseOptimizable (ic))) &&
3852 ic->next && ic->next->op == IFX &&
3853 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3854 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3857 debugLog (" %d\n", __LINE__);
3858 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3862 debugLog(" %d\n", __LINE__);
3864 #ifndef NO_packRegsForSupport
3865 /* reduce for support function calls */
3866 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3867 packRegsForSupport (ic, ebp);
3870 /* if a parameter is passed, it's in W, so we may not
3871 need to place a copy in a register */
3872 if (ic->op == RECEIVE)
3873 packForReceive (ic, ebp);
3875 #ifndef NO_packRegsForOneuse
3876 /* some cases the redundant moves can
3877 can be eliminated for return statements */
3878 if ((ic->op == RETURN || ic->op == SEND) &&
3879 !isOperandInFarSpace (IC_LEFT (ic)) &&
3881 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3884 #ifndef NO_packRegsForOneuse
3885 /* if pointer set & left has a size more than
3886 one and right is not in far space */
3887 if (POINTER_SET (ic) &&
3888 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3889 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3890 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3891 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3893 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3896 #ifndef NO_packRegsForOneuse
3897 /* if pointer get */
3898 if (POINTER_GET (ic) &&
3899 !isOperandInFarSpace (IC_RESULT (ic)) &&
3900 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3901 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3902 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3904 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3905 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3908 #ifndef NO_cast_peep
3909 /* if this is cast for intergral promotion then
3910 check if only use of the definition of the
3911 operand being casted/ if yes then replace
3912 the result of that arithmetic operation with
3913 this result and get rid of the cast */
3914 if (ic->op == CAST) {
3916 sym_link *fromType = operandType (IC_RIGHT (ic));
3917 sym_link *toType = operandType (IC_LEFT (ic));
3919 debugLog (" %d - casting\n", __LINE__);
3921 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3922 getSize (fromType) != getSize (toType)) {
3925 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3928 if (IS_ARITHMETIC_OP (dic)) {
3929 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3931 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3932 IC_RESULT (dic) = IC_RESULT (ic);
3933 remiCodeFromeBBlock (ebp, ic);
3934 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3935 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3936 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3940 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3944 /* if the type from and type to are the same
3945 then if this is the only use then packit */
3946 if (compareType (operandType (IC_RIGHT (ic)),
3947 operandType (IC_LEFT (ic))) == 1) {
3949 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3952 debugLog(" %d\n", __LINE__);
3954 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3955 IC_RESULT (dic) = IC_RESULT (ic);
3956 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3957 remiCodeFromeBBlock (ebp, ic);
3958 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3959 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3967 iTempNN := (some variable in farspace) V1
3972 if (ic->op == IPUSH)
3974 packForPush (ic, ebp);
3978 #ifndef NO_packRegsForAccUse
3979 /* pack registers for accumulator use, when the
3980 result of an arithmetic or bit wise operation
3981 has only one use, that use is immediately following
3982 the defintion and the using iCode has only one
3983 operand or has two operands but one is literal &
3984 the result of that operation is not on stack then
3985 we can leave the result of this operation in acc:b
3987 if ((IS_ARITHMETIC_OP (ic)
3989 || IS_BITWISE_OP (ic)
3991 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3994 IS_ITEMP (IC_RESULT (ic)) &&
3995 getSize (operandType (IC_RESULT (ic))) <= 1)
3997 packRegsForAccUse (ic);
4004 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4008 if (!pic16_ralloc_debug || !debugF)
4011 for (i = 0; i < count; i++)
4013 fprintf (debugF, "\n----------------------------------------------------------------\n");
4014 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4015 ebbs[i]->entryLabel->name,
4018 ebbs[i]->isLastInLoop);
4019 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4024 fprintf (debugF, "visited %d : hasFcall = %d\n",
4028 fprintf (debugF, "\ndefines bitVector :");
4029 bitVectDebugOn (ebbs[i]->defSet, debugF);
4030 fprintf (debugF, "\nlocal defines bitVector :");
4031 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4032 fprintf (debugF, "\npointers Set bitvector :");
4033 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4034 fprintf (debugF, "\nin pointers Set bitvector :");
4035 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4036 fprintf (debugF, "\ninDefs Set bitvector :");
4037 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4038 fprintf (debugF, "\noutDefs Set bitvector :");
4039 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4040 fprintf (debugF, "\nusesDefs Set bitvector :");
4041 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4042 fprintf (debugF, "\n----------------------------------------------------------------\n");
4043 printiCChain (ebbs[i]->sch, debugF);
4046 /*-----------------------------------------------------------------*/
4047 /* pic16_assignRegisters - assigns registers to each live range as need */
4048 /*-----------------------------------------------------------------*/
4050 pic16_assignRegisters (eBBlock ** ebbs, int count)
4055 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4056 debugLog ("\nebbs before optimizing:\n");
4057 dumpEbbsToDebug (ebbs, count);
4059 setToNull ((void *) &_G.funcrUsed);
4060 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4063 /* change assignments this will remove some
4064 live ranges reducing some register pressure */
4065 for (i = 0; i < count; i++)
4066 pic16_packRegisters (ebbs[i]);
4073 debugLog("dir registers allocated so far:\n");
4074 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4077 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4078 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4079 reg = hTabNextItem(dynDirectRegNames, &hkey);
4084 /* liveranges probably changed by register packing
4085 so we compute them again */
4086 recomputeLiveRanges (ebbs, count);
4088 if (options.dump_pack)
4089 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4091 /* first determine for each live range the number of
4092 registers & the type of registers required for each */
4095 /* and serially allocate registers */
4096 serialRegAssign (ebbs, count);
4098 // debugLog ("ebbs after serialRegAssign:\n");
4099 // dumpEbbsToDebug (ebbs, count);
4102 //pic16_freeAllRegs();
4104 /* if stack was extended then tell the user */
4107 /* werror(W_TOOMANY_SPILS,"stack", */
4108 /* _G.stackExtend,currFunc->name,""); */
4114 /* werror(W_TOOMANY_SPILS,"data space", */
4115 /* _G.dataExtend,currFunc->name,""); */
4119 /* after that create the register mask
4120 for each of the instruction */
4121 createRegMask (ebbs, count);
4123 /* redo that offsets for stacked automatic variables */
4124 redoStackOffsets ();
4126 if (options.dump_rassgn)
4127 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4129 /* now get back the chain */
4130 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4132 debugLog ("ebbs after optimizing:\n");
4133 dumpEbbsToDebug (ebbs, count);
4138 /* free up any _G.stackSpil locations allocated */
4139 applyToSet (_G.stackSpil, deallocStackSpil);
4141 setToNull ((void *) &_G.stackSpil);
4142 setToNull ((void *) &_G.spiltSet);
4143 /* mark all registers as free */
4144 pic16_freeAllRegs ();
4146 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");