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 */
754 // fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
756 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
758 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
759 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
761 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
762 addSet(&pic16_dynDirectRegs, reg);
768 /*-----------------------------------------------------------------*/
769 /* RegWithIdx - returns pointer to register with index number */
770 /*-----------------------------------------------------------------*/
771 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
776 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
777 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
782 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
784 debugLog ("Found a Dynamic Register!\n");
787 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
788 debugLog ("Found a Direct Register!\n");
794 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
795 debugLog ("Found a Stack Register!\n");
800 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
801 debugLog ("Found a Processor Register!\n");
815 /*-----------------------------------------------------------------*/
816 /* pic16_regWithIdx - returns pointer to register with index number*/
817 /*-----------------------------------------------------------------*/
819 pic16_regWithIdx (int idx)
823 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
826 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
829 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
835 /*-----------------------------------------------------------------*/
836 /* pic16_regWithIdx - returns pointer to register with index number */
837 /*-----------------------------------------------------------------*/
839 pic16_allocWithIdx (int idx)
844 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
845 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
847 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
849 debugLog ("Found a Dynamic Register!\n");
850 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
851 debugLog ("Found a Stack Register!\n");
852 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
853 debugLog ("Found a Processor Register!\n");
854 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
855 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
856 debugLog ("Found an Internal Register!\n");
859 debugLog ("Dynamic Register not found\n");
862 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
863 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
864 "regWithIdx not found");
874 /*-----------------------------------------------------------------*/
875 /*-----------------------------------------------------------------*/
877 pic16_findFreeReg(short type)
884 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
886 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
890 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
902 /*-----------------------------------------------------------------*/
903 /* freeReg - frees a register */
904 /*-----------------------------------------------------------------*/
908 debugLog ("%s\n", __FUNCTION__);
909 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
914 /*-----------------------------------------------------------------*/
915 /* nFreeRegs - returns number of free registers */
916 /*-----------------------------------------------------------------*/
924 /* although I fixed the register allocation/freeing scheme
925 * the for loop below doesn't give valid results. I do not
926 * know why yet. -- VR 10-Jan-2003 */
931 /* dynamically allocate as many as we need and worry about
932 * fitting them into a PIC later */
934 debugLog ("%s\n", __FUNCTION__);
936 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
937 if((reg->type == type) && reg->isFree)nfr++;
939 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
943 /*-----------------------------------------------------------------*/
944 /* nfreeRegsType - free registers with type */
945 /*-----------------------------------------------------------------*/
947 nfreeRegsType (int type)
950 debugLog ("%s\n", __FUNCTION__);
953 if ((nfr = nFreeRegs (type)) == 0)
954 return nFreeRegs (REG_GPR);
957 return nFreeRegs (type);
960 static void writeSetUsedRegs(FILE *of, set *dRegs)
965 for (dReg = setFirstItem(dRegs) ; dReg ;
966 dReg = setNextItem(dRegs)) {
969 fprintf (of, "\t%s\n",dReg->name);
975 extern void pic16_groupRegistersInSection(set *regset);
977 extern void pic16_dump_equates(FILE *of, set *equs);
978 //extern void pic16_dump_map(void);
979 extern void pic16_dump_usection(FILE *of, set *section, int fix);
980 extern void pic16_dump_isection(FILE *of, set *section, int fix);
981 extern void pic16_dump_int_registers(FILE *of, set *section);
982 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
984 static void packBits(set *bregs)
989 regs *relocbitfield=NULL;
995 for (regset = bregs ; regset ;
996 regset = regset->next) {
999 breg->isBitField = 1;
1000 //fprintf(stderr,"bit reg: %s\n",breg->name);
1003 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1005 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1006 breg->rIdx = breg->address & 7;
1007 breg->address >>= 3;
1010 sprintf (buffer, "fbitfield%02x", breg->address);
1011 //fprintf(stderr,"new bit field\n");
1012 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1013 bitfield->isBitField = 1;
1014 bitfield->isFixed = 1;
1015 bitfield->address = breg->address;
1016 addSet(&pic16_dynDirectRegs,bitfield);
1017 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1019 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1022 breg->reg_alias = bitfield;
1026 if(!relocbitfield || bit_no >7) {
1029 sprintf (buffer, "bitfield%d", byte_no);
1030 //fprintf(stderr,"new relocatable bit field\n");
1031 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1032 relocbitfield->isBitField = 1;
1033 addSet(&pic16_dynDirectRegs,relocbitfield);
1034 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1038 breg->reg_alias = relocbitfield;
1039 breg->address = rDirectIdx; /* byte_no; */
1040 breg->rIdx = bit_no++;
1049 static void bitEQUs(FILE *of, set *bregs)
1051 regs *breg,*bytereg;
1054 //fprintf(stderr," %s\n",__FUNCTION__);
1055 for (breg = setFirstItem(bregs) ; breg ;
1056 breg = setNextItem(bregs)) {
1058 //fprintf(stderr,"bit reg: %s\n",breg->name);
1060 bytereg = breg->reg_alias;
1062 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1065 breg->rIdx & 0x0007);
1068 fprintf(stderr, "bit field is not assigned to a register\n");
1069 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1080 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1085 for (reg = setFirstItem(fregs) ; reg ;
1086 reg = setNextItem(fregs)) {
1088 if(!reg->isEmitted && reg->wasUsed) {
1090 if (reg->type != REG_SFR) {
1091 fprintf (of, "%s\tEQU\t0x%03x\n",
1097 fprintf (of, "%s\tEQU\t0x%03x\n",
1106 void pic16_writeUsedRegs(FILE *of)
1108 packBits(pic16_dynDirectBitRegs);
1110 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1111 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1112 pic16_groupRegistersInSection(pic16_dynStackRegs);
1113 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1114 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1115 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1119 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1120 pic16_assignFixedRegisters(pic16_dynStackRegs);
1121 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1122 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1124 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1125 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1126 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1127 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1128 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1131 // pic16_dump_map();
1132 // pic16_dump_cblock(of);
1135 pic16_dump_equates(of, pic16_equ_data);
1137 /* dump initialised data */
1138 pic16_dump_isection(of, rel_idataSymSet, 0);
1139 pic16_dump_isection(of, fix_idataSymSet, 1);
1141 // pic16_dump_idata(of, idataSymSet);
1143 /* dump internal registers */
1144 pic16_dump_int_registers(of, pic16_int_regs);
1146 /* dump other variables */
1147 pic16_dump_usection(of, pic16_rel_udata, 0);
1148 pic16_dump_usection(of, pic16_fix_udata, 1);
1153 /*-----------------------------------------------------------------*/
1154 /* allDefsOutOfRange - all definitions are out of a range */
1155 /*-----------------------------------------------------------------*/
1157 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1161 debugLog ("%s\n", __FUNCTION__);
1165 for (i = 0; i < defs->size; i++)
1169 if (bitVectBitValue (defs, i) &&
1170 (ic = hTabItemWithKey (iCodehTab, i)) &&
1171 (ic->seq >= fseq && ic->seq <= toseq))
1181 /*-----------------------------------------------------------------*/
1182 /* computeSpillable - given a point find the spillable live ranges */
1183 /*-----------------------------------------------------------------*/
1185 computeSpillable (iCode * ic)
1189 debugLog ("%s\n", __FUNCTION__);
1190 /* spillable live ranges are those that are live at this
1191 point . the following categories need to be subtracted
1193 a) - those that are already spilt
1194 b) - if being used by this one
1195 c) - defined by this one */
1197 spillable = bitVectCopy (ic->rlive);
1199 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1201 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1202 bitVectUnSetBit (spillable, ic->defKey);
1203 spillable = bitVectIntersect (spillable, _G.regAssigned);
1208 /*-----------------------------------------------------------------*/
1209 /* noSpilLoc - return true if a variable has no spil location */
1210 /*-----------------------------------------------------------------*/
1212 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1214 debugLog ("%s\n", __FUNCTION__);
1215 return (sym->usl.spillLoc ? 0 : 1);
1218 /*-----------------------------------------------------------------*/
1219 /* hasSpilLoc - will return 1 if the symbol has spil location */
1220 /*-----------------------------------------------------------------*/
1222 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1224 debugLog ("%s\n", __FUNCTION__);
1225 return (sym->usl.spillLoc ? 1 : 0);
1228 /*-----------------------------------------------------------------*/
1229 /* directSpilLoc - will return 1 if the splilocation is in direct */
1230 /*-----------------------------------------------------------------*/
1232 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1234 debugLog ("%s\n", __FUNCTION__);
1235 if (sym->usl.spillLoc &&
1236 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1242 /*-----------------------------------------------------------------*/
1243 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1244 /* but is not used as a pointer */
1245 /*-----------------------------------------------------------------*/
1247 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1249 debugLog ("%s\n", __FUNCTION__);
1250 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1253 /*-----------------------------------------------------------------*/
1254 /* rematable - will return 1 if the remat flag is set */
1255 /*-----------------------------------------------------------------*/
1257 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1259 debugLog ("%s\n", __FUNCTION__);
1263 /*-----------------------------------------------------------------*/
1264 /* notUsedInRemaining - not used or defined in remain of the block */
1265 /*-----------------------------------------------------------------*/
1267 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1269 debugLog ("%s\n", __FUNCTION__);
1270 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1271 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1274 /*-----------------------------------------------------------------*/
1275 /* allLRs - return true for all */
1276 /*-----------------------------------------------------------------*/
1278 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1280 debugLog ("%s\n", __FUNCTION__);
1284 /*-----------------------------------------------------------------*/
1285 /* liveRangesWith - applies function to a given set of live range */
1286 /*-----------------------------------------------------------------*/
1288 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1289 eBBlock * ebp, iCode * ic)
1294 debugLog ("%s\n", __FUNCTION__);
1295 if (!lrs || !lrs->size)
1298 for (i = 1; i < lrs->size; i++)
1301 if (!bitVectBitValue (lrs, i))
1304 /* if we don't find it in the live range
1305 hash table we are in serious trouble */
1306 if (!(sym = hTabItemWithKey (liveRanges, i)))
1308 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1309 "liveRangesWith could not find liveRange");
1313 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1314 addSetHead (&rset, sym);
1321 /*-----------------------------------------------------------------*/
1322 /* leastUsedLR - given a set determines which is the least used */
1323 /*-----------------------------------------------------------------*/
1325 leastUsedLR (set * sset)
1327 symbol *sym = NULL, *lsym = NULL;
1329 debugLog ("%s\n", __FUNCTION__);
1330 sym = lsym = setFirstItem (sset);
1335 for (; lsym; lsym = setNextItem (sset))
1338 /* if usage is the same then prefer
1339 the spill the smaller of the two */
1340 if (lsym->used == sym->used)
1341 if (getSize (lsym->type) < getSize (sym->type))
1345 if (lsym->used < sym->used)
1350 setToNull ((void *) &sset);
1355 /*-----------------------------------------------------------------*/
1356 /* noOverLap - will iterate through the list looking for over lap */
1357 /*-----------------------------------------------------------------*/
1359 noOverLap (set * itmpStack, symbol * fsym)
1362 debugLog ("%s\n", __FUNCTION__);
1365 for (sym = setFirstItem (itmpStack); sym;
1366 sym = setNextItem (itmpStack))
1368 if (sym->liveTo > fsym->liveFrom)
1376 /*-----------------------------------------------------------------*/
1377 /* isFree - will return 1 if the a free spil location is found */
1378 /*-----------------------------------------------------------------*/
1383 V_ARG (symbol **, sloc);
1384 V_ARG (symbol *, fsym);
1386 debugLog ("%s\n", __FUNCTION__);
1387 /* if already found */
1391 /* if it is free && and the itmp assigned to
1392 this does not have any overlapping live ranges
1393 with the one currently being assigned and
1394 the size can be accomodated */
1396 noOverLap (sym->usl.itmpStack, fsym) &&
1397 getSize (sym->type) >= getSize (fsym->type))
1406 /*-----------------------------------------------------------------*/
1407 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1408 /*-----------------------------------------------------------------*/
1410 spillLRWithPtrReg (symbol * forSym)
1416 debugLog ("%s\n", __FUNCTION__);
1417 if (!_G.regAssigned ||
1418 bitVectIsZero (_G.regAssigned))
1421 r0 = pic16_regWithIdx (R0_IDX);
1422 r1 = pic16_regWithIdx (R1_IDX);
1424 /* for all live ranges */
1425 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1426 lrsym = hTabNextItem (liveRanges, &k))
1430 /* if no registers assigned to it or
1432 /* if it does not overlap with this then
1433 not need to spill it */
1435 if (lrsym->isspilt || !lrsym->nRegs ||
1436 (lrsym->liveTo < forSym->liveFrom))
1439 /* go thru the registers : if it is either
1440 r0 or r1 then spil it */
1441 for (j = 0; j < lrsym->nRegs; j++)
1442 if (lrsym->regs[j] == r0 ||
1443 lrsym->regs[j] == r1)
1452 /*-----------------------------------------------------------------*/
1453 /* createStackSpil - create a location on the stack to spil */
1454 /*-----------------------------------------------------------------*/
1456 createStackSpil (symbol * sym)
1458 symbol *sloc = NULL;
1459 int useXstack, model, noOverlay;
1461 char slocBuffer[30];
1462 debugLog ("%s\n", __FUNCTION__);
1464 /* first go try and find a free one that is already
1465 existing on the stack */
1466 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1468 /* found a free one : just update & return */
1469 sym->usl.spillLoc = sloc;
1472 addSetHead (&sloc->usl.itmpStack, sym);
1476 /* could not then have to create one , this is the hard part
1477 we need to allocate this on the stack : this is really a
1478 hack!! but cannot think of anything better at this time */
1480 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1482 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1483 __FILE__, __LINE__);
1487 sloc = newiTemp (slocBuffer);
1489 /* set the type to the spilling symbol */
1490 sloc->type = copyLinkChain (sym->type);
1491 sloc->etype = getSpec (sloc->type);
1492 SPEC_SCLS (sloc->etype) = S_DATA;
1493 SPEC_EXTR (sloc->etype) = 0;
1494 SPEC_STAT (sloc->etype) = 0;
1496 /* we don't allow it to be allocated`
1497 onto the external stack since : so we
1498 temporarily turn it off ; we also
1499 turn off memory model to prevent
1500 the spil from going to the external storage
1501 and turn off overlaying
1504 useXstack = options.useXstack;
1505 model = options.model;
1506 noOverlay = options.noOverlay;
1507 options.noOverlay = 1;
1508 options.model = options.useXstack = 0;
1512 options.useXstack = useXstack;
1513 options.model = model;
1514 options.noOverlay = noOverlay;
1515 sloc->isref = 1; /* to prevent compiler warning */
1517 /* if it is on the stack then update the stack */
1518 if (IN_STACK (sloc->etype))
1520 currFunc->stack += getSize (sloc->type);
1521 _G.stackExtend += getSize (sloc->type);
1524 _G.dataExtend += getSize (sloc->type);
1526 /* add it to the _G.stackSpil set */
1527 addSetHead (&_G.stackSpil, sloc);
1528 sym->usl.spillLoc = sloc;
1531 /* add it to the set of itempStack set
1532 of the spill location */
1533 addSetHead (&sloc->usl.itmpStack, sym);
1537 /*-----------------------------------------------------------------*/
1538 /* isSpiltOnStack - returns true if the spil location is on stack */
1539 /*-----------------------------------------------------------------*/
1541 isSpiltOnStack (symbol * sym)
1545 debugLog ("%s\n", __FUNCTION__);
1552 /* if (sym->_G.stackSpil) */
1555 if (!sym->usl.spillLoc)
1558 etype = getSpec (sym->usl.spillLoc->type);
1559 if (IN_STACK (etype))
1565 /*-----------------------------------------------------------------*/
1566 /* spillThis - spils a specific operand */
1567 /*-----------------------------------------------------------------*/
1569 spillThis (symbol * sym)
1572 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1574 /* if this is rematerializable or has a spillLocation
1575 we are okay, else we need to create a spillLocation
1577 if (!(sym->remat || sym->usl.spillLoc))
1578 createStackSpil (sym);
1581 /* mark it has spilt & put it in the spilt set */
1583 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1585 bitVectUnSetBit (_G.regAssigned, sym->key);
1587 for (i = 0; i < sym->nRegs; i++)
1591 freeReg (sym->regs[i]);
1592 sym->regs[i] = NULL;
1595 /* if spilt on stack then free up r0 & r1
1596 if they could have been assigned to some
1598 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1601 spillLRWithPtrReg (sym);
1604 if (sym->usl.spillLoc && !sym->remat)
1605 sym->usl.spillLoc->allocreq = 1;
1609 /*-----------------------------------------------------------------*/
1610 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1611 /*-----------------------------------------------------------------*/
1613 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1615 bitVect *lrcs = NULL;
1619 debugLog ("%s\n", __FUNCTION__);
1620 /* get the spillable live ranges */
1621 lrcs = computeSpillable (ic);
1623 /* get all live ranges that are rematerizable */
1624 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1627 /* return the least used of these */
1628 return leastUsedLR (selectS);
1631 /* get live ranges with spillLocations in direct space */
1632 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1634 sym = leastUsedLR (selectS);
1635 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1636 sym->usl.spillLoc->rname :
1637 sym->usl.spillLoc->name));
1639 /* mark it as allocation required */
1640 sym->usl.spillLoc->allocreq = 1;
1644 /* if the symbol is local to the block then */
1645 if (forSym->liveTo < ebp->lSeq)
1648 /* check if there are any live ranges allocated
1649 to registers that are not used in this block */
1650 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1652 sym = leastUsedLR (selectS);
1653 /* if this is not rematerializable */
1662 /* check if there are any live ranges that not
1663 used in the remainder of the block */
1664 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1666 sym = leastUsedLR (selectS);
1669 sym->remainSpil = 1;
1676 /* find live ranges with spillocation && not used as pointers */
1677 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1680 sym = leastUsedLR (selectS);
1681 /* mark this as allocation required */
1682 sym->usl.spillLoc->allocreq = 1;
1686 /* find live ranges with spillocation */
1687 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1690 sym = leastUsedLR (selectS);
1691 sym->usl.spillLoc->allocreq = 1;
1695 /* couldn't find then we need to create a spil
1696 location on the stack , for which one? the least
1698 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1701 /* return a created spil location */
1702 sym = createStackSpil (leastUsedLR (selectS));
1703 sym->usl.spillLoc->allocreq = 1;
1707 /* this is an extreme situation we will spill
1708 this one : happens very rarely but it does happen */
1714 /*-----------------------------------------------------------------*/
1715 /* spilSomething - spil some variable & mark registers as free */
1716 /*-----------------------------------------------------------------*/
1718 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1723 debugLog ("%s\n", __FUNCTION__);
1724 /* get something we can spil */
1725 ssym = selectSpil (ic, ebp, forSym);
1727 /* mark it as spilt */
1729 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1731 /* mark it as not register assigned &
1732 take it away from the set */
1733 bitVectUnSetBit (_G.regAssigned, ssym->key);
1735 /* mark the registers as free */
1736 for (i = 0; i < ssym->nRegs; i++)
1738 freeReg (ssym->regs[i]);
1740 /* if spilt on stack then free up r0 & r1
1741 if they could have been assigned to as gprs */
1742 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1745 spillLRWithPtrReg (ssym);
1748 /* if this was a block level spil then insert push & pop
1749 at the start & end of block respectively */
1750 if (ssym->blockSpil)
1752 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1753 /* add push to the start of the block */
1754 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1755 ebp->sch->next : ebp->sch));
1756 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1757 /* add pop to the end of the block */
1758 addiCodeToeBBlock (ebp, nic, NULL);
1761 /* if spilt because not used in the remainder of the
1762 block then add a push before this instruction and
1763 a pop at the end of the block */
1764 if (ssym->remainSpil)
1767 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1768 /* add push just before this instruction */
1769 addiCodeToeBBlock (ebp, nic, ic);
1771 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1772 /* add pop to the end of the block */
1773 addiCodeToeBBlock (ebp, nic, NULL);
1782 /*-----------------------------------------------------------------*/
1783 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1784 /*-----------------------------------------------------------------*/
1786 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1791 debugLog ("%s\n", __FUNCTION__);
1793 /* try for a ptr type */
1794 if ((reg = allocReg (REG_PTR)))
1797 /* try for gpr type */
1798 if ((reg = allocReg (REG_GPR)))
1801 /* we have to spil */
1802 if (!spilSomething (ic, ebp, sym))
1805 /* make sure partially assigned registers aren't reused */
1806 for (j=0; j<=sym->nRegs; j++)
1808 sym->regs[j]->isFree = 0;
1810 /* this looks like an infinite loop but
1811 in really selectSpil will abort */
1815 /*-----------------------------------------------------------------*/
1816 /* getRegGpr - will try for GPR if not spil */
1817 /*-----------------------------------------------------------------*/
1819 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1824 debugLog ("%s\n", __FUNCTION__);
1826 /* try for gpr type */
1827 if ((reg = allocReg (REG_GPR)))
1830 if (!pic16_ptrRegReq)
1831 if ((reg = allocReg (REG_PTR)))
1834 /* we have to spil */
1835 if (!spilSomething (ic, ebp, sym))
1838 /* make sure partially assigned registers aren't reused */
1839 for (j=0; j<=sym->nRegs; j++)
1841 sym->regs[j]->isFree = 0;
1843 /* this looks like an infinite loop but
1844 in really selectSpil will abort */
1848 /*-----------------------------------------------------------------*/
1849 /* symHasReg - symbol has a given register */
1850 /*-----------------------------------------------------------------*/
1852 symHasReg (symbol * sym, regs * reg)
1856 debugLog ("%s\n", __FUNCTION__);
1857 for (i = 0; i < sym->nRegs; i++)
1858 if (sym->regs[i] == reg)
1864 /*-----------------------------------------------------------------*/
1865 /* deassignLRs - check the live to and if they have registers & are */
1866 /* not spilt then free up the registers */
1867 /*-----------------------------------------------------------------*/
1869 deassignLRs (iCode * ic, eBBlock * ebp)
1875 debugLog ("%s\n", __FUNCTION__);
1876 for (sym = hTabFirstItem (liveRanges, &k); sym;
1877 sym = hTabNextItem (liveRanges, &k))
1880 symbol *psym = NULL;
1881 /* if it does not end here */
1882 if (sym->liveTo > ic->seq)
1885 /* if it was spilt on stack then we can
1886 mark the stack spil location as free */
1891 sym->usl.spillLoc->isFree = 1;
1897 if (!bitVectBitValue (_G.regAssigned, sym->key))
1900 /* special case check if this is an IFX &
1901 the privious one was a pop and the
1902 previous one was not spilt then keep track
1904 if (ic->op == IFX && ic->prev &&
1905 ic->prev->op == IPOP &&
1906 !ic->prev->parmPush &&
1907 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1908 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1914 bitVectUnSetBit (_G.regAssigned, sym->key);
1916 /* if the result of this one needs registers
1917 and does not have it then assign it right
1919 if (IC_RESULT (ic) &&
1920 !(SKIP_IC2 (ic) || /* not a special icode */
1921 ic->op == JUMPTABLE ||
1926 POINTER_SET (ic)) &&
1927 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1928 result->liveTo > ic->seq && /* and will live beyond this */
1929 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1930 result->regType == sym->regType && /* same register types */
1931 result->nRegs && /* which needs registers */
1932 !result->isspilt && /* and does not already have them */
1934 !bitVectBitValue (_G.regAssigned, result->key) &&
1935 /* the number of free regs + number of regs in this LR
1936 can accomodate the what result Needs */
1937 ((nfreeRegsType (result->regType) +
1938 sym->nRegs) >= result->nRegs)
1942 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1944 result->regs[i] = sym->regs[i];
1946 result->regs[i] = getRegGpr (ic, ebp, result);
1948 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1952 /* free the remaining */
1953 for (; i < sym->nRegs; i++)
1957 if (!symHasReg (psym, sym->regs[i]))
1958 freeReg (sym->regs[i]);
1961 freeReg (sym->regs[i]);
1968 /*-----------------------------------------------------------------*/
1969 /* reassignLR - reassign this to registers */
1970 /*-----------------------------------------------------------------*/
1972 reassignLR (operand * op)
1974 symbol *sym = OP_SYMBOL (op);
1977 debugLog ("%s\n", __FUNCTION__);
1978 /* not spilt any more */
1979 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1980 bitVectUnSetBit (_G.spiltSet, sym->key);
1982 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1986 for (i = 0; i < sym->nRegs; i++)
1987 sym->regs[i]->isFree = 0;
1990 /*-----------------------------------------------------------------*/
1991 /* willCauseSpill - determines if allocating will cause a spill */
1992 /*-----------------------------------------------------------------*/
1994 willCauseSpill (int nr, int rt)
1996 debugLog ("%s\n", __FUNCTION__);
1997 /* first check if there are any avlb registers
1998 of te type required */
2001 /* special case for pointer type
2002 if pointer type not avlb then
2003 check for type gpr */
2004 if (nFreeRegs (rt) >= nr)
2006 if (nFreeRegs (REG_GPR) >= nr)
2011 if (pic16_ptrRegReq)
2013 if (nFreeRegs (rt) >= nr)
2018 if (nFreeRegs (REG_PTR) +
2019 nFreeRegs (REG_GPR) >= nr)
2024 debugLog (" ... yep it will (cause a spill)\n");
2025 /* it will cause a spil */
2029 /*-----------------------------------------------------------------*/
2030 /* positionRegs - the allocator can allocate same registers to res- */
2031 /* ult and operand, if this happens make sure they are in the same */
2032 /* position as the operand otherwise chaos results */
2033 /*-----------------------------------------------------------------*/
2035 positionRegs (symbol * result, symbol * opsym, int lineno)
2037 int count = min (result->nRegs, opsym->nRegs);
2038 int i, j = 0, shared = 0;
2040 debugLog ("%s\n", __FUNCTION__);
2041 /* if the result has been spilt then cannot share */
2046 /* first make sure that they actually share */
2047 for (i = 0; i < count; i++)
2049 for (j = 0; j < count; j++)
2051 if (result->regs[i] == opsym->regs[j] && i != j)
2061 regs *tmp = result->regs[i];
2062 result->regs[i] = result->regs[j];
2063 result->regs[j] = tmp;
2068 /*------------------------------------------------------------------*/
2069 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2070 /* it should either have registers or have beed spilled. Otherwise, */
2071 /* there was an uninitialized variable, so just spill this to get */
2072 /* the operand in a valid state. */
2073 /*------------------------------------------------------------------*/
2075 verifyRegsAssigned (operand *op, iCode * ic)
2080 if (!IS_ITEMP (op)) return;
2082 sym = OP_SYMBOL (op);
2083 if (sym->isspilt) return;
2084 if (!sym->nRegs) return;
2085 if (sym->regs[0]) return;
2087 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2088 sym->prereqv ? sym->prereqv->name : sym->name);
2093 /*-----------------------------------------------------------------*/
2094 /* serialRegAssign - serially allocate registers to the variables */
2095 /*-----------------------------------------------------------------*/
2097 serialRegAssign (eBBlock ** ebbs, int count)
2101 debugLog ("%s\n", __FUNCTION__);
2102 /* for all blocks */
2103 for (i = 0; i < count; i++)
2108 if (ebbs[i]->noPath &&
2109 (ebbs[i]->entryLabel != entryLabel &&
2110 ebbs[i]->entryLabel != returnLabel))
2113 /* of all instructions do */
2114 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2117 debugLog (" op: %s\n", decodeOp (ic->op));
2119 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2120 pic16_allocDirReg(IC_RESULT(ic));
2122 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2123 pic16_allocDirReg(IC_LEFT(ic));
2125 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2126 pic16_allocDirReg(IC_RIGHT(ic));
2128 /* if this is an ipop that means some live
2129 range will have to be assigned again */
2131 reassignLR (IC_LEFT (ic));
2133 /* if result is present && is a true symbol */
2134 if (IC_RESULT (ic) && ic->op != IFX &&
2135 IS_TRUE_SYMOP (IC_RESULT (ic)))
2136 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2138 /* take away registers from live
2139 ranges that end at this instruction */
2140 deassignLRs (ic, ebbs[i]);
2142 /* some don't need registers */
2143 if (SKIP_IC2 (ic) ||
2144 ic->op == JUMPTABLE ||
2148 (IC_RESULT (ic) && POINTER_SET (ic)))
2151 /* now we need to allocate registers
2152 only for the result */
2155 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2161 /* if it does not need or is spilt
2162 or is already assigned to registers
2163 or will not live beyond this instructions */
2166 bitVectBitValue (_G.regAssigned, sym->key) ||
2167 sym->liveTo <= ic->seq)
2170 /* if some liverange has been spilt at the block level
2171 and this one live beyond this block then spil this
2173 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2178 /* if trying to allocate this will cause
2179 a spill and there is nothing to spill
2180 or this one is rematerializable then
2182 willCS = willCauseSpill (sym->nRegs, sym->regType);
2183 spillable = computeSpillable (ic);
2185 (willCS && bitVectIsZero (spillable)))
2193 /* If the live range preceeds the point of definition
2194 then ideally we must take into account registers that
2195 have been allocated after sym->liveFrom but freed
2196 before ic->seq. This is complicated, so spill this
2197 symbol instead and let fillGaps handle the allocation. */
2198 if (sym->liveFrom < ic->seq)
2204 /* if it has a spillocation & is used less than
2205 all other live ranges then spill this */
2207 if (sym->usl.spillLoc) {
2208 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2209 allLRs, ebbs[i], ic));
2210 if (leastUsed && leastUsed->used > sym->used) {
2215 /* if none of the liveRanges have a spillLocation then better
2216 to spill this one than anything else already assigned to registers */
2217 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2218 /* if this is local to this block then we might find a block spil */
2219 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2227 if (ic->op == RECEIVE)
2228 debugLog ("When I get clever, I'll optimize the receive logic\n");
2230 /* if we need ptr regs for the right side
2232 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2233 <= (unsigned) PTRSIZE)
2238 /* else we assign registers to it */
2239 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2241 debugLog (" %d - \n", __LINE__);
2243 bitVectDebugOn(_G.regAssigned, debugF);
2245 for (j = 0; j < sym->nRegs; j++)
2247 if (sym->regType == REG_PTR)
2248 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2250 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2252 /* if the allocation falied which means
2253 this was spilt then break */
2257 debugLog (" %d - \n", __LINE__);
2259 /* if it shares registers with operands make sure
2260 that they are in the same position */
2261 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2262 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2263 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2264 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2265 /* do the same for the right operand */
2266 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2267 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2268 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2269 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2271 debugLog (" %d - \n", __LINE__);
2274 debugLog (" %d - \n", __LINE__);
2283 /* Check for and fix any problems with uninitialized operands */
2284 for (i = 0; i < count; i++)
2288 if (ebbs[i]->noPath &&
2289 (ebbs[i]->entryLabel != entryLabel &&
2290 ebbs[i]->entryLabel != returnLabel))
2293 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2300 verifyRegsAssigned (IC_COND (ic), ic);
2304 if (ic->op == JUMPTABLE)
2306 verifyRegsAssigned (IC_JTCOND (ic), ic);
2310 verifyRegsAssigned (IC_RESULT (ic), ic);
2311 verifyRegsAssigned (IC_LEFT (ic), ic);
2312 verifyRegsAssigned (IC_RIGHT (ic), ic);
2318 /*-----------------------------------------------------------------*/
2319 /* rUmaskForOp :- returns register mask for an operand */
2320 /*-----------------------------------------------------------------*/
2322 rUmaskForOp (operand * op)
2328 debugLog ("%s\n", __FUNCTION__);
2329 /* only temporaries are assigned registers */
2333 sym = OP_SYMBOL (op);
2335 /* if spilt or no registers assigned to it
2337 if (sym->isspilt || !sym->nRegs)
2340 rumask = newBitVect (pic16_nRegs);
2342 for (j = 0; j < sym->nRegs; j++)
2344 rumask = bitVectSetBit (rumask,
2345 sym->regs[j]->rIdx);
2351 /*-----------------------------------------------------------------*/
2352 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2353 /*-----------------------------------------------------------------*/
2355 regsUsedIniCode (iCode * ic)
2357 bitVect *rmask = newBitVect (pic16_nRegs);
2359 debugLog ("%s\n", __FUNCTION__);
2360 /* do the special cases first */
2363 rmask = bitVectUnion (rmask,
2364 rUmaskForOp (IC_COND (ic)));
2368 /* for the jumptable */
2369 if (ic->op == JUMPTABLE)
2371 rmask = bitVectUnion (rmask,
2372 rUmaskForOp (IC_JTCOND (ic)));
2377 /* of all other cases */
2379 rmask = bitVectUnion (rmask,
2380 rUmaskForOp (IC_LEFT (ic)));
2384 rmask = bitVectUnion (rmask,
2385 rUmaskForOp (IC_RIGHT (ic)));
2388 rmask = bitVectUnion (rmask,
2389 rUmaskForOp (IC_RESULT (ic)));
2395 /*-----------------------------------------------------------------*/
2396 /* createRegMask - for each instruction will determine the regsUsed */
2397 /*-----------------------------------------------------------------*/
2399 createRegMask (eBBlock ** ebbs, int count)
2403 debugLog ("%s\n", __FUNCTION__);
2404 /* for all blocks */
2405 for (i = 0; i < count; i++)
2409 if (ebbs[i]->noPath &&
2410 (ebbs[i]->entryLabel != entryLabel &&
2411 ebbs[i]->entryLabel != returnLabel))
2414 /* for all instructions */
2415 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2420 if (SKIP_IC2 (ic) || !ic->rlive)
2423 /* first mark the registers used in this
2425 ic->rUsed = regsUsedIniCode (ic);
2426 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2428 /* now create the register mask for those
2429 registers that are in use : this is a
2430 super set of ic->rUsed */
2431 ic->rMask = newBitVect (pic16_nRegs + 1);
2433 /* for all live Ranges alive at this point */
2434 for (j = 1; j < ic->rlive->size; j++)
2439 /* if not alive then continue */
2440 if (!bitVectBitValue (ic->rlive, j))
2443 /* find the live range we are interested in */
2444 if (!(sym = hTabItemWithKey (liveRanges, j)))
2446 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2447 "createRegMask cannot find live range");
2451 /* if no register assigned to it */
2452 if (!sym->nRegs || sym->isspilt)
2455 /* for all the registers allocated to it */
2456 for (k = 0; k < sym->nRegs; k++)
2459 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2465 /*-----------------------------------------------------------------*/
2466 /* rematStr - returns the rematerialized string for a remat var */
2467 /*-----------------------------------------------------------------*/
2469 rematStr (symbol * sym)
2472 iCode *ic = sym->rematiCode;
2473 symbol *psym = NULL;
2475 debugLog ("%s\n", __FUNCTION__);
2477 //printf ("%s\n", s);
2479 /* if plus or minus print the right hand side */
2481 if (ic->op == '+' || ic->op == '-') {
2483 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2485 sprintf (s, "(%s %c 0x%04x)",
2486 OP_SYMBOL (IC_LEFT (ric))->rname,
2488 (int) operandLitValue (IC_RIGHT (ic)));
2491 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2493 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2494 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2499 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2500 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2502 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2507 /*-----------------------------------------------------------------*/
2508 /* rematStr - returns the rematerialized string for a remat var */
2509 /*-----------------------------------------------------------------*/
2511 rematStr (symbol * sym)
2514 iCode *ic = sym->rematiCode;
2516 debugLog ("%s\n", __FUNCTION__);
2521 /* if plus or minus print the right hand side */
2523 if (ic->op == '+' || ic->op == '-') {
2524 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2527 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2531 if (ic->op == '+' || ic->op == '-')
2533 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2534 sprintf (s, "(%s %c 0x%04x)",
2535 OP_SYMBOL (IC_LEFT (ric))->rname,
2537 (int) operandLitValue (IC_RIGHT (ic)));
2540 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2542 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2546 /* we reached the end */
2547 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2551 printf ("%s\n", buffer);
2556 /*-----------------------------------------------------------------*/
2557 /* regTypeNum - computes the type & number of registers required */
2558 /*-----------------------------------------------------------------*/
2566 debugLog ("%s\n", __FUNCTION__);
2567 /* for each live range do */
2568 for (sym = hTabFirstItem (liveRanges, &k); sym;
2569 sym = hTabNextItem (liveRanges, &k)) {
2571 debugLog (" %d - %s\n", __LINE__, sym->rname);
2572 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2574 /* if used zero times then no registers needed */
2575 if ((sym->liveTo - sym->liveFrom) == 0)
2579 /* if the live range is a temporary */
2582 debugLog (" %d - itemp register\n", __LINE__);
2584 /* if the type is marked as a conditional */
2585 if (sym->regType == REG_CND)
2588 /* if used in return only then we don't
2590 if (sym->ruonly || sym->accuse) {
2591 if (IS_AGGREGATE (sym->type) || sym->isptr)
2592 sym->type = aggrToPtr (sym->type, FALSE);
2593 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2598 /* if the symbol has only one definition &
2599 that definition is a get_pointer and the
2600 pointer we are getting is rematerializable and
2603 if (bitVectnBitsOn (sym->defs) == 1 &&
2604 (ic = hTabItemWithKey (iCodehTab,
2605 bitVectFirstBit (sym->defs))) &&
2607 !IS_BITVAR (sym->etype) &&
2608 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2610 if (ptrPseudoSymSafe (sym, ic)) {
2614 debugLog (" %d - \n", __LINE__);
2616 /* create a psuedo symbol & force a spil */
2617 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2618 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2619 psym->type = sym->type;
2620 psym->etype = sym->etype;
2621 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2622 strcpy (psym->rname, psym->name);
2624 sym->usl.spillLoc = psym;
2628 /* if in data space or idata space then try to
2629 allocate pointer register */
2633 /* if not then we require registers */
2634 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2635 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2636 getSize (sym->type));
2640 if(IS_PTR_CONST (sym->type)) {
2642 if(IS_CODEPTR (sym->type)) {
2644 // what IS this ???? (HJD)
2645 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2646 sym->nRegs = 3; // patch 14
2649 if (sym->nRegs > 4) {
2650 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2651 printTypeChain (sym->type, stderr);
2652 fprintf (stderr, "\n");
2655 /* determine the type of register required */
2656 if (sym->nRegs == 1 &&
2657 IS_PTR (sym->type) &&
2659 sym->regType = REG_PTR;
2661 sym->regType = REG_GPR;
2664 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2668 /* for the first run we don't provide */
2669 /* registers for true symbols we will */
2670 /* see how things go */
2675 static DEFSETFUNC (markRegFree)
2677 ((regs *)item)->isFree = 1;
2682 DEFSETFUNC (pic16_deallocReg)
2684 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2685 ((regs *)item)->isFree = 1;
2686 ((regs *)item)->wasUsed = 0;
2690 /*-----------------------------------------------------------------*/
2691 /* freeAllRegs - mark all registers as free */
2692 /*-----------------------------------------------------------------*/
2694 pic16_freeAllRegs ()
2696 debugLog ("%s\n", __FUNCTION__);
2698 applyToSet(pic16_dynAllocRegs,markRegFree);
2699 applyToSet(pic16_dynStackRegs,markRegFree);
2702 /*-----------------------------------------------------------------*/
2703 /*-----------------------------------------------------------------*/
2705 pic16_deallocateAllRegs ()
2707 debugLog ("%s\n", __FUNCTION__);
2709 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2713 /*-----------------------------------------------------------------*/
2714 /* deallocStackSpil - this will set the stack pointer back */
2715 /*-----------------------------------------------------------------*/
2717 DEFSETFUNC (deallocStackSpil)
2721 debugLog ("%s\n", __FUNCTION__);
2726 /*-----------------------------------------------------------------*/
2727 /* farSpacePackable - returns the packable icode for far variables */
2728 /*-----------------------------------------------------------------*/
2730 farSpacePackable (iCode * ic)
2734 debugLog ("%s\n", __FUNCTION__);
2735 /* go thru till we find a definition for the
2736 symbol on the right */
2737 for (dic = ic->prev; dic; dic = dic->prev)
2740 /* if the definition is a call then no */
2741 if ((dic->op == CALL || dic->op == PCALL) &&
2742 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2747 /* if shift by unknown amount then not */
2748 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2749 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2752 /* if pointer get and size > 1 */
2753 if (POINTER_GET (dic) &&
2754 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2757 if (POINTER_SET (dic) &&
2758 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2761 /* if any three is a true symbol in far space */
2762 if (IC_RESULT (dic) &&
2763 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2764 isOperandInFarSpace (IC_RESULT (dic)))
2767 if (IC_RIGHT (dic) &&
2768 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2769 isOperandInFarSpace (IC_RIGHT (dic)) &&
2770 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2773 if (IC_LEFT (dic) &&
2774 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2775 isOperandInFarSpace (IC_LEFT (dic)) &&
2776 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2779 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2781 if ((dic->op == LEFT_OP ||
2782 dic->op == RIGHT_OP ||
2784 IS_OP_LITERAL (IC_RIGHT (dic)))
2794 /*-----------------------------------------------------------------*/
2795 /* packRegsForAssign - register reduction for assignment */
2796 /*-----------------------------------------------------------------*/
2798 packRegsForAssign (iCode * ic, eBBlock * ebp)
2803 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2804 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2805 debugAopGet (" result:", IC_RESULT (ic));
2806 debugAopGet (" left:", IC_LEFT (ic));
2807 debugAopGet (" right:", IC_RIGHT (ic));
2809 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2812 /* if this is at an absolute address, then get the address. */
2813 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2814 if(PIC16_IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2815 debugLog (" %d - found config word declaration\n", __LINE__);
2816 if(IS_VALOP(IC_RIGHT(ic))) {
2817 debugLog (" setting config word to %x\n",
2818 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2820 fprintf(stderr, "%s:%d setting config word to %x\n", __FILE__, __LINE__,
2821 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2823 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2824 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2828 debugLog(" %d\n", __LINE__);
2830 /* remove the assignment from the iCode chain. */
2832 remiCodeFromeBBlock (ebp, ic);
2833 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2834 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2841 debugLog(" %d - actuall processing\n", __LINE__ );
2843 if (!IS_ITEMP (IC_RESULT (ic))) {
2844 pic16_allocDirReg(IC_RESULT (ic));
2845 debugLog (" %d - result is not temp\n", __LINE__);
2849 /* See BUGLOG0001 - VR */
2851 if (!IS_ITEMP (IC_RIGHT (ic))) {
2852 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2853 pic16_allocDirReg(IC_RIGHT (ic));
2858 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2859 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2861 debugLog (" %d - not packing - right side fails \n", __LINE__);
2865 /* if the true symbol is defined in far space or on stack
2866 then we should not since this will increase register pressure */
2867 if (isOperandInFarSpace (IC_RESULT (ic)))
2869 if ((dic = farSpacePackable (ic)))
2876 /* find the definition of iTempNN scanning backwards if we find a
2877 a use of the true symbol before we find the definition then
2879 for (dic = ic->prev; dic; dic = dic->prev)
2882 /* if there is a function call and this is
2883 a parameter & not my parameter then don't pack it */
2884 if ((dic->op == CALL || dic->op == PCALL) &&
2885 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2886 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2888 debugLog (" %d - \n", __LINE__);
2897 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2899 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2900 IS_OP_VOLATILE (IC_RESULT (dic)))
2902 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2908 if( IS_SYMOP( IC_RESULT(dic)) &&
2909 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2911 debugLog (" %d - result is bitfield\n", __LINE__);
2917 if (IS_SYMOP (IC_RESULT (dic)) &&
2918 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2920 /* A previous result was assigned to the same register - we'll our definition */
2921 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2922 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2923 if (POINTER_SET (dic))
2929 if (IS_SYMOP (IC_RIGHT (dic)) &&
2930 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2931 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2933 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2938 if (IS_SYMOP (IC_LEFT (dic)) &&
2939 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2940 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2942 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2947 if (POINTER_SET (dic) &&
2948 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2950 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2958 return 0; /* did not find */
2961 /* This code is taken from the hc08 port. Do not know
2962 * if it fits for pic16, but I leave it here just in case */
2964 /* if assignment then check that right is not a bit */
2965 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2966 sym_link *etype = operandType (IC_RIGHT (dic));
2968 if (IS_BITFIELD (etype)) {
2969 /* if result is a bit too then it's ok */
2970 etype = operandType (IC_RESULT (dic));
2971 if (!IS_BITFIELD (etype)) {
2972 debugLog(" %d bitfields\n");
2979 /* if the result is on stack or iaccess then it must be
2980 the same atleast one of the operands */
2981 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2982 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2986 /* clear the onStack flag, the port doesn't support it yet! FIXME */
2987 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2988 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2992 /* the operation has only one symbol
2993 operator then we can pack */
2994 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2995 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2998 if (!((IC_LEFT (dic) &&
2999 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3001 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3005 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3006 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3007 /* found the definition */
3008 /* replace the result with the result of */
3009 /* this assignment and remove this assignment */
3010 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3011 IC_RESULT (dic) = IC_RESULT (ic);
3013 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3015 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3017 /* delete from liverange table also
3018 delete from all the points inbetween and the new
3020 for (sic = dic; sic != ic; sic = sic->next)
3022 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3023 if (IS_ITEMP (IC_RESULT (dic)))
3024 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3027 remiCodeFromeBBlock (ebp, ic);
3028 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3030 debugLog(" %d\n", __LINE__ );
3031 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3032 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3040 #define NO_packRegsForAccUse
3041 #define NO_packRegsForSupport
3042 #define NO_packRegsForOneuse
3043 #define NO_cast_peep
3048 #ifndef NO_packRegsForSupport
3049 /*-----------------------------------------------------------------*/
3050 /* findAssignToSym : scanning backwards looks for first assig found */
3051 /*-----------------------------------------------------------------*/
3053 findAssignToSym (operand * op, iCode * ic)
3057 debugLog ("%s\n", __FUNCTION__);
3058 for (dic = ic->prev; dic; dic = dic->prev)
3061 /* if definition by assignment */
3062 if (dic->op == '=' &&
3063 !POINTER_SET (dic) &&
3064 IC_RESULT (dic)->key == op->key
3065 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3069 /* we are interested only if defined in far space */
3070 /* or in stack space in case of + & - */
3072 /* if assigned to a non-symbol then return
3074 if (!IS_SYMOP (IC_RIGHT (dic)))
3077 /* if the symbol is in far space then
3079 if (isOperandInFarSpace (IC_RIGHT (dic)))
3082 /* for + & - operations make sure that
3083 if it is on the stack it is the same
3084 as one of the three operands */
3085 if ((ic->op == '+' || ic->op == '-') &&
3086 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3090 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3091 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3094 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3095 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3096 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3104 /* if we find an usage then we cannot delete it */
3105 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3108 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3111 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3115 /* now make sure that the right side of dic
3116 is not defined between ic & dic */
3119 iCode *sic = dic->next;
3121 for (; sic != ic; sic = sic->next)
3122 if (IC_RESULT (sic) &&
3123 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3134 #ifndef NO_packRegsForSupport
3135 /*-----------------------------------------------------------------*/
3136 /* packRegsForSupport :- reduce some registers for support calls */
3137 /*-----------------------------------------------------------------*/
3139 packRegsForSupport (iCode * ic, eBBlock * ebp)
3143 debugLog ("%s\n", __FUNCTION__);
3144 /* for the left & right operand :- look to see if the
3145 left was assigned a true symbol in far space in that
3146 case replace them */
3147 if (IS_ITEMP (IC_LEFT (ic)) &&
3148 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3150 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3156 debugAopGet ("removing left:", IC_LEFT (ic));
3158 /* found it we need to remove it from the
3160 for (sic = dic; sic != ic; sic = sic->next)
3161 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3163 IC_LEFT (ic)->operand.symOperand =
3164 IC_RIGHT (dic)->operand.symOperand;
3165 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3166 remiCodeFromeBBlock (ebp, dic);
3167 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3168 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3172 /* do the same for the right operand */
3175 IS_ITEMP (IC_RIGHT (ic)) &&
3176 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3178 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3184 /* if this is a subtraction & the result
3185 is a true symbol in far space then don't pack */
3186 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3188 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3189 if (IN_FARSPACE (SPEC_OCLS (etype)))
3193 debugAopGet ("removing right:", IC_RIGHT (ic));
3195 /* found it we need to remove it from the
3197 for (sic = dic; sic != ic; sic = sic->next)
3198 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3200 IC_RIGHT (ic)->operand.symOperand =
3201 IC_RIGHT (dic)->operand.symOperand;
3202 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3204 remiCodeFromeBBlock (ebp, dic);
3205 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3206 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3215 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3217 #ifndef NO_packRegsForOneuse
3218 /*-----------------------------------------------------------------*/
3219 /* packRegsForOneuse : - will reduce some registers for single Use */
3220 /*-----------------------------------------------------------------*/
3222 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3227 debugLog ("%s\n", __FUNCTION__);
3228 /* if returning a literal then do nothing */
3232 /* only upto 2 bytes since we cannot predict
3233 the usage of b, & acc */
3234 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3239 /* this routine will mark the a symbol as used in one
3240 instruction use only && if the definition is local
3241 (ie. within the basic block) && has only one definition &&
3242 that definition is either a return value from a
3243 function or does not contain any variables in
3245 uses = bitVectCopy (OP_USES (op));
3246 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3247 if (!bitVectIsZero (uses)) /* has other uses */
3250 /* if it has only one defintion */
3251 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3252 return NULL; /* has more than one definition */
3254 /* get that definition */
3256 hTabItemWithKey (iCodehTab,
3257 bitVectFirstBit (OP_DEFS (op)))))
3260 /* found the definition now check if it is local */
3261 if (dic->seq < ebp->fSeq ||
3262 dic->seq > ebp->lSeq)
3263 return NULL; /* non-local */
3265 /* now check if it is the return from
3267 if (dic->op == CALL || dic->op == PCALL)
3269 if (ic->op != SEND && ic->op != RETURN &&
3270 !POINTER_SET(ic) && !POINTER_GET(ic))
3272 OP_SYMBOL (op)->ruonly = 1;
3279 /* otherwise check that the definition does
3280 not contain any symbols in far space */
3281 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3282 isOperandInFarSpace (IC_RIGHT (dic)) ||
3283 IS_OP_RUONLY (IC_LEFT (ic)) ||
3284 IS_OP_RUONLY (IC_RIGHT (ic)))
3289 /* if pointer set then make sure the pointer
3291 if (POINTER_SET (dic) &&
3292 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3295 if (POINTER_GET (dic) &&
3296 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3301 /* also make sure the intervenening instructions
3302 don't have any thing in far space */
3303 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3306 /* if there is an intervening function call then no */
3307 if (dic->op == CALL || dic->op == PCALL)
3309 /* if pointer set then make sure the pointer
3311 if (POINTER_SET (dic) &&
3312 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3315 if (POINTER_GET (dic) &&
3316 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3319 /* if address of & the result is remat then okay */
3320 if (dic->op == ADDRESS_OF &&
3321 OP_SYMBOL (IC_RESULT (dic))->remat)
3324 /* if operand has size of three or more & this
3325 operation is a '*','/' or '%' then 'b' may
3327 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3328 getSize (operandType (op)) >= 3)
3331 /* if left or right or result is in far space */
3332 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3333 isOperandInFarSpace (IC_RIGHT (dic)) ||
3334 isOperandInFarSpace (IC_RESULT (dic)) ||
3335 IS_OP_RUONLY (IC_LEFT (dic)) ||
3336 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3337 IS_OP_RUONLY (IC_RESULT (dic)))
3343 OP_SYMBOL (op)->ruonly = 1;
3350 /*-----------------------------------------------------------------*/
3351 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3352 /*-----------------------------------------------------------------*/
3354 isBitwiseOptimizable (iCode * ic)
3356 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3357 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3359 debugLog ("%s\n", __FUNCTION__);
3360 /* bitwise operations are considered optimizable
3361 under the following conditions (Jean-Louis VERN)
3373 if (IS_LITERAL (rtype) ||
3374 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3381 #ifndef NO_packRegsForAccUse
3383 /*-----------------------------------------------------------------*/
3384 /* packRegsForAccUse - pack registers for acc use */
3385 /*-----------------------------------------------------------------*/
3387 packRegsForAccUse (iCode * ic)
3391 debugLog ("%s\n", __FUNCTION__);
3393 /* if this is an aggregate, e.g. a one byte char array */
3394 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3397 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3399 /* if + or - then it has to be one byte result */
3400 if ((ic->op == '+' || ic->op == '-')
3401 && getSize (operandType (IC_RESULT (ic))) > 1)
3404 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3405 /* if shift operation make sure right side is not a literal */
3406 if (ic->op == RIGHT_OP &&
3407 (isOperandLiteral (IC_RIGHT (ic)) ||
3408 getSize (operandType (IC_RESULT (ic))) > 1))
3411 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3412 if (ic->op == LEFT_OP &&
3413 (isOperandLiteral (IC_RIGHT (ic)) ||
3414 getSize (operandType (IC_RESULT (ic))) > 1))
3417 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3418 if (IS_BITWISE_OP (ic) &&
3419 getSize (operandType (IC_RESULT (ic))) > 1)
3423 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3424 /* has only one definition */
3425 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3428 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3429 /* has only one use */
3430 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3433 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3434 /* and the usage immediately follows this iCode */
3435 if (!(uic = hTabItemWithKey (iCodehTab,
3436 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3439 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3440 if (ic->next != uic)
3443 /* if it is a conditional branch then we definitely can */
3447 if (uic->op == JUMPTABLE)
3450 /* if the usage is not is an assignment
3451 or an arithmetic / bitwise / shift operation then not */
3452 if (POINTER_SET (uic) &&
3453 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3456 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3457 if (uic->op != '=' &&
3458 !IS_ARITHMETIC_OP (uic) &&
3459 !IS_BITWISE_OP (uic) &&
3460 uic->op != LEFT_OP &&
3461 uic->op != RIGHT_OP)
3464 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3465 /* if used in ^ operation then make sure right is not a
3467 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3470 /* if shift operation make sure right side is not a literal */
3471 if (uic->op == RIGHT_OP &&
3472 (isOperandLiteral (IC_RIGHT (uic)) ||
3473 getSize (operandType (IC_RESULT (uic))) > 1))
3476 if (uic->op == LEFT_OP &&
3477 (isOperandLiteral (IC_RIGHT (uic)) ||
3478 getSize (operandType (IC_RESULT (uic))) > 1))
3481 /* make sure that the result of this icode is not on the
3482 stack, since acc is used to compute stack offset */
3483 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3484 OP_SYMBOL (IC_RESULT (uic))->onStack)
3487 /* if either one of them in far space then we cannot */
3488 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3489 isOperandInFarSpace (IC_LEFT (uic))) ||
3490 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3491 isOperandInFarSpace (IC_RIGHT (uic))))
3494 /* if the usage has only one operand then we can */
3495 if (IC_LEFT (uic) == NULL ||
3496 IC_RIGHT (uic) == NULL)
3499 /* make sure this is on the left side if not
3500 a '+' since '+' is commutative */
3501 if (ic->op != '+' &&
3502 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3506 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3507 /* if one of them is a literal then we can */
3508 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3509 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3510 (getSize (operandType (IC_RESULT (uic))) <= 1))
3512 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3517 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3518 /* if the other one is not on stack then we can */
3519 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3520 (IS_ITEMP (IC_RIGHT (uic)) ||
3521 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3522 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3525 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3526 (IS_ITEMP (IC_LEFT (uic)) ||
3527 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3528 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3534 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3535 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3542 /*-----------------------------------------------------------------*/
3543 /* packForPush - hueristics to reduce iCode for pushing */
3544 /*-----------------------------------------------------------------*/
3546 packForReceive (iCode * ic, eBBlock * ebp)
3550 debugLog ("%s\n", __FUNCTION__);
3551 debugAopGet (" result:", IC_RESULT (ic));
3552 debugAopGet (" left:", IC_LEFT (ic));
3553 debugAopGet (" right:", IC_RIGHT (ic));
3558 for (dic = ic->next; dic; dic = dic->next)
3563 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3564 debugLog (" used on left\n");
3565 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3566 debugLog (" used on right\n");
3567 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3568 debugLog (" used on result\n");
3570 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3571 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3576 debugLog (" hey we can remove this unnecessary assign\n");
3578 /*-----------------------------------------------------------------*/
3579 /* packForPush - hueristics to reduce iCode for pushing */
3580 /*-----------------------------------------------------------------*/
3582 packForPush (iCode * ic, eBBlock * ebp)
3586 debugLog ("%s\n", __FUNCTION__);
3587 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3590 /* must have only definition & one usage */
3591 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3592 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3595 /* find the definition */
3596 if (!(dic = hTabItemWithKey (iCodehTab,
3597 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3600 if (dic->op != '=' || POINTER_SET (dic))
3603 /* we now we know that it has one & only one def & use
3604 and the that the definition is an assignment */
3605 IC_LEFT (ic) = IC_RIGHT (dic);
3607 remiCodeFromeBBlock (ebp, dic);
3608 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3609 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3612 static void printSymType(char * str, sym_link *sl)
3614 if(!pic16_ralloc_debug)return;
3616 debugLog (" %s Symbol type: ",str);
3617 printTypeChain( sl, debugF);
3621 /*-----------------------------------------------------------------*/
3622 /* some debug code to print the symbol S_TYPE. Note that
3623 * the function checkSClass in src/SDCCsymt.c dinks with
3624 * the S_TYPE in ways the PIC port doesn't fully like...*/
3625 /*-----------------------------------------------------------------*/
3626 static void isData(sym_link *sl)
3630 if(!pic16_ralloc_debug)return;
3637 for ( ; sl; sl=sl->next) {
3639 switch (SPEC_SCLS(sl)) {
3640 case S_DATA: fprintf (of, "data "); break;
3641 case S_XDATA: fprintf (of, "xdata "); break;
3642 case S_SFR: fprintf (of, "sfr "); break;
3643 case S_SBIT: fprintf (of, "sbit "); break;
3644 case S_CODE: fprintf (of, "code "); break;
3645 case S_IDATA: fprintf (of, "idata "); break;
3646 case S_PDATA: fprintf (of, "pdata "); break;
3647 case S_LITERAL: fprintf (of, "literal "); break;
3648 case S_STACK: fprintf (of, "stack "); break;
3649 case S_XSTACK: fprintf (of, "xstack "); break;
3650 case S_BIT: fprintf (of, "bit "); break;
3651 case S_EEPROM: fprintf (of, "eeprom "); break;
3660 /*--------------------------------------------------------------------*/
3661 /* pic16_packRegisters - does some transformations to reduce */
3662 /* register pressure */
3664 /*--------------------------------------------------------------------*/
3666 pic16_packRegisters (eBBlock * ebp)
3671 debugLog ("%s\n", __FUNCTION__);
3677 /* look for assignments of the form */
3678 /* iTempNN = TRueSym (someoperation) SomeOperand */
3680 /* TrueSym := iTempNN:1 */
3681 for (ic = ebp->sch; ic; ic = ic->next)
3683 // debugLog("%d\n", __LINE__);
3684 /* find assignment of the form TrueSym := iTempNN:1 */
3685 /* see BUGLOG0001 for workaround with the CAST - VR */
3686 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3687 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3688 change += packRegsForAssign (ic, ebp);
3692 if (POINTER_SET (ic))
3693 debugLog ("pointer is set\n");
3694 debugAopGet (" result:", IC_RESULT (ic));
3695 debugAopGet (" left:", IC_LEFT (ic));
3696 debugAopGet (" right:", IC_RIGHT (ic));
3705 for (ic = ebp->sch; ic; ic = ic->next) {
3707 if(IS_SYMOP ( IC_LEFT(ic))) {
3708 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3710 debugAopGet ("x left:", IC_LEFT (ic));
3712 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3714 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3716 debugLog (" is a pointer\n");
3718 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3719 debugLog (" is a ptr\n");
3721 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3722 debugLog (" is volatile\n");
3726 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3727 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3728 pic16_allocDirReg(IC_LEFT (ic));
3731 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3734 if(IS_SYMOP ( IC_RIGHT(ic))) {
3735 debugAopGet (" right:", IC_RIGHT (ic));
3736 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3739 if(IS_SYMOP ( IC_RESULT(ic))) {
3740 debugAopGet (" result:", IC_RESULT (ic));
3741 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3744 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3745 debugAopGet (" right:", IC_RIGHT (ic));
3746 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3747 // pic16_allocDirReg(IC_RIGHT(ic));
3750 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3751 debugAopGet (" result:", IC_RESULT (ic));
3752 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3753 // pic16_allocDirReg(IC_RESULT(ic));
3757 if (POINTER_SET (ic))
3758 debugLog (" %d - Pointer set\n", __LINE__);
3761 /* if this is an itemp & result of a address of a true sym
3762 then mark this as rematerialisable */
3763 if (ic->op == ADDRESS_OF &&
3764 IS_ITEMP (IC_RESULT (ic)) &&
3765 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3766 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3767 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3770 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3772 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3773 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3774 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3778 /* if straight assignment then carry remat flag if
3779 this is the only definition */
3780 if (ic->op == '=' &&
3781 !POINTER_SET (ic) &&
3782 IS_SYMOP (IC_RIGHT (ic)) &&
3783 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3784 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3786 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3788 OP_SYMBOL (IC_RESULT (ic))->remat =
3789 OP_SYMBOL (IC_RIGHT (ic))->remat;
3790 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3791 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3794 /* if this is a +/- operation with a rematerizable
3795 then mark this as rematerializable as well */
3796 if ((ic->op == '+' || ic->op == '-') &&
3797 (IS_SYMOP (IC_LEFT (ic)) &&
3798 IS_ITEMP (IC_RESULT (ic)) &&
3799 OP_SYMBOL (IC_LEFT (ic))->remat &&
3800 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3801 IS_OP_LITERAL (IC_RIGHT (ic))))
3803 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3805 operandLitValue (IC_RIGHT (ic));
3806 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3807 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3808 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3811 /* mark the pointer usages */
3812 if (POINTER_SET (ic))
3814 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3815 debugLog (" marking as a pointer (set) =>");
3816 debugAopGet (" result:", IC_RESULT (ic));
3818 if (POINTER_GET (ic))
3820 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3821 debugLog (" marking as a pointer (get) =>");
3822 debugAopGet (" left:", IC_LEFT (ic));
3825 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3829 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3830 /* if we are using a symbol on the stack
3831 then we should say pic16_ptrRegReq */
3832 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3833 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3834 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3835 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3836 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3837 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3841 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3842 if (IS_SYMOP (IC_LEFT (ic)))
3843 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3844 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3845 if (IS_SYMOP (IC_RIGHT (ic)))
3846 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3847 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3848 if (IS_SYMOP (IC_RESULT (ic)))
3849 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3850 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3853 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3857 /* if the condition of an if instruction
3858 is defined in the previous instruction then
3859 mark the itemp as a conditional */
3860 if ((IS_CONDITIONAL (ic) ||
3861 ((ic->op == BITWISEAND ||
3864 isBitwiseOptimizable (ic))) &&
3865 ic->next && ic->next->op == IFX &&
3866 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3867 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3870 debugLog (" %d\n", __LINE__);
3871 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3875 debugLog(" %d\n", __LINE__);
3877 #ifndef NO_packRegsForSupport
3878 /* reduce for support function calls */
3879 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3880 packRegsForSupport (ic, ebp);
3883 /* if a parameter is passed, it's in W, so we may not
3884 need to place a copy in a register */
3885 if (ic->op == RECEIVE)
3886 packForReceive (ic, ebp);
3888 #ifndef NO_packRegsForOneuse
3889 /* some cases the redundant moves can
3890 can be eliminated for return statements */
3891 if ((ic->op == RETURN || ic->op == SEND) &&
3892 !isOperandInFarSpace (IC_LEFT (ic)) &&
3894 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3897 #ifndef NO_packRegsForOneuse
3898 /* if pointer set & left has a size more than
3899 one and right is not in far space */
3900 if (POINTER_SET (ic) &&
3901 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3902 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3903 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3904 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3906 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3909 #ifndef NO_packRegsForOneuse
3910 /* if pointer get */
3911 if (POINTER_GET (ic) &&
3912 !isOperandInFarSpace (IC_RESULT (ic)) &&
3913 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3914 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3915 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3917 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3918 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3921 #ifndef NO_cast_peep
3922 /* if this is cast for intergral promotion then
3923 check if only use of the definition of the
3924 operand being casted/ if yes then replace
3925 the result of that arithmetic operation with
3926 this result and get rid of the cast */
3927 if (ic->op == CAST) {
3929 sym_link *fromType = operandType (IC_RIGHT (ic));
3930 sym_link *toType = operandType (IC_LEFT (ic));
3932 debugLog (" %d - casting\n", __LINE__);
3934 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3935 getSize (fromType) != getSize (toType)) {
3938 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3941 if (IS_ARITHMETIC_OP (dic)) {
3942 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3944 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3945 IC_RESULT (dic) = IC_RESULT (ic);
3946 remiCodeFromeBBlock (ebp, ic);
3947 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3948 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3949 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3953 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3957 /* if the type from and type to are the same
3958 then if this is the only use then packit */
3959 if (compareType (operandType (IC_RIGHT (ic)),
3960 operandType (IC_LEFT (ic))) == 1) {
3962 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3965 debugLog(" %d\n", __LINE__);
3967 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3968 IC_RESULT (dic) = IC_RESULT (ic);
3969 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3970 remiCodeFromeBBlock (ebp, ic);
3971 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3972 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3980 iTempNN := (some variable in farspace) V1
3985 if (ic->op == IPUSH)
3987 packForPush (ic, ebp);
3991 #ifndef NO_packRegsForAccUse
3992 /* pack registers for accumulator use, when the
3993 result of an arithmetic or bit wise operation
3994 has only one use, that use is immediately following
3995 the defintion and the using iCode has only one
3996 operand or has two operands but one is literal &
3997 the result of that operation is not on stack then
3998 we can leave the result of this operation in acc:b
4000 if ((IS_ARITHMETIC_OP (ic)
4002 || IS_BITWISE_OP (ic)
4004 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4007 IS_ITEMP (IC_RESULT (ic)) &&
4008 getSize (operandType (IC_RESULT (ic))) <= 1)
4010 packRegsForAccUse (ic);
4017 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4021 if (!pic16_ralloc_debug || !debugF)
4024 for (i = 0; i < count; i++)
4026 fprintf (debugF, "\n----------------------------------------------------------------\n");
4027 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4028 ebbs[i]->entryLabel->name,
4031 ebbs[i]->isLastInLoop);
4032 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4037 fprintf (debugF, "visited %d : hasFcall = %d\n",
4041 fprintf (debugF, "\ndefines bitVector :");
4042 bitVectDebugOn (ebbs[i]->defSet, debugF);
4043 fprintf (debugF, "\nlocal defines bitVector :");
4044 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4045 fprintf (debugF, "\npointers Set bitvector :");
4046 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4047 fprintf (debugF, "\nin pointers Set bitvector :");
4048 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4049 fprintf (debugF, "\ninDefs Set bitvector :");
4050 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4051 fprintf (debugF, "\noutDefs Set bitvector :");
4052 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4053 fprintf (debugF, "\nusesDefs Set bitvector :");
4054 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4055 fprintf (debugF, "\n----------------------------------------------------------------\n");
4056 printiCChain (ebbs[i]->sch, debugF);
4059 /*-----------------------------------------------------------------*/
4060 /* pic16_assignRegisters - assigns registers to each live range as need */
4061 /*-----------------------------------------------------------------*/
4063 pic16_assignRegisters (eBBlock ** ebbs, int count)
4068 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4069 debugLog ("\nebbs before optimizing:\n");
4070 dumpEbbsToDebug (ebbs, count);
4072 setToNull ((void *) &_G.funcrUsed);
4073 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4076 /* change assignments this will remove some
4077 live ranges reducing some register pressure */
4078 for (i = 0; i < count; i++)
4079 pic16_packRegisters (ebbs[i]);
4086 debugLog("dir registers allocated so far:\n");
4087 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4090 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4091 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4092 reg = hTabNextItem(dynDirectRegNames, &hkey);
4097 /* liveranges probably changed by register packing
4098 so we compute them again */
4099 recomputeLiveRanges (ebbs, count);
4101 if (options.dump_pack)
4102 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4104 /* first determine for each live range the number of
4105 registers & the type of registers required for each */
4108 /* and serially allocate registers */
4109 serialRegAssign (ebbs, count);
4111 // debugLog ("ebbs after serialRegAssign:\n");
4112 // dumpEbbsToDebug (ebbs, count);
4115 //pic16_freeAllRegs();
4117 /* if stack was extended then tell the user */
4120 /* werror(W_TOOMANY_SPILS,"stack", */
4121 /* _G.stackExtend,currFunc->name,""); */
4127 /* werror(W_TOOMANY_SPILS,"data space", */
4128 /* _G.dataExtend,currFunc->name,""); */
4132 /* after that create the register mask
4133 for each of the instruction */
4134 createRegMask (ebbs, count);
4136 /* redo that offsets for stacked automatic variables */
4137 redoStackOffsets ();
4139 if (options.dump_rassgn)
4140 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4142 /* now get back the chain */
4143 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4145 debugLog ("ebbs after optimizing:\n");
4146 dumpEbbsToDebug (ebbs, count);
4151 /* free up any _G.stackSpil locations allocated */
4152 applyToSet (_G.stackSpil, deallocStackSpil);
4154 setToNull ((void *) &_G.stackSpil);
4155 setToNull ((void *) &_G.spiltSet);
4156 /* mark all registers as free */
4157 pic16_freeAllRegs ();
4159 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");