1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
40 /*-----------------------------------------------------------------*/
41 /* At this point we start getting processor specific although */
42 /* some routines are non-processor specific & can be reused when */
43 /* targetting other processors. The decision for this will have */
44 /* to be made on a routine by routine basis */
45 /* routines used to pack registers are most definitely not reusable */
46 /* since the pack the registers depending strictly on the MCU */
47 /*-----------------------------------------------------------------*/
49 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
50 extern void genpic16Code (iCode *);
51 extern void pic16_assignConfigWordValue(int address, int value);
61 bitVect *funcrUsed; /* registers used in a function */
67 /* Shared with gen.c */
68 int pic16_ptrRegReq; /* one byte pointer register required */
71 set *pic16_dynAllocRegs=NULL;
72 set *pic16_dynStackRegs=NULL;
73 set *pic16_dynProcessorRegs=NULL;
74 set *pic16_dynDirectRegs=NULL;
75 set *pic16_dynDirectBitRegs=NULL;
76 set *pic16_dynInternalRegs=NULL;
78 static hTab *dynDirectRegNames= NULL;
79 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
81 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
82 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
83 set *pic16_equ_data=NULL; /* registers used by equates */
84 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
86 set *pic16_builtin_functions=NULL;
88 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
89 static int rDirectIdx=0;
91 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
93 int pic16_Gstack_base_addr=0; /* The starting address of registers that
94 * are used to pass and return parameters */
99 static void spillThis (symbol *);
100 int pic16_ralloc_debug = 0;
101 static FILE *debugF = NULL;
102 /*-----------------------------------------------------------------*/
103 /* debugLog - open a file for debugging information */
104 /*-----------------------------------------------------------------*/
105 //static void debugLog(char *inst,char *fmt, ...)
107 debugLog (char *fmt,...)
109 static int append = 0; // First time through, open the file without append.
112 //char *bufferP=buffer;
115 if (!pic16_ralloc_debug || !dstFileName)
121 /* create the file name */
122 strcpy (buffer, dstFileName);
123 strcat (buffer, ".d");
125 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
127 werror (E_FILE_OPEN_ERR, buffer);
130 append = 1; // Next time debubLog is called, we'll append the debug info
136 vsprintf (buffer, fmt, ap);
138 fprintf (debugF, "%s", buffer);
140 while (isspace(*bufferP)) bufferP++;
142 if (bufferP && *bufferP)
143 lineCurr = (lineCurr ?
144 connectLine(lineCurr,newLineNode(lb)) :
145 (lineHead = newLineNode(lb)));
146 lineCurr->isInline = _G.inLine;
147 lineCurr->isDebug = _G.debugLine;
156 if(!pic16_ralloc_debug)return;
159 fputc ('\n', debugF);
161 /*-----------------------------------------------------------------*/
162 /* debugLogClose - closes the debug log file (if opened) */
163 /*-----------------------------------------------------------------*/
173 #define AOP(op) op->aop
176 debugAopGet (char *str, operand * op)
178 if(!pic16_ralloc_debug)return NULL;
183 printOperand (op, debugF);
190 decodeOp (unsigned int op)
192 if (op < 128 && op > ' ') {
193 buffer[0] = (op & 0xff);
199 case IDENTIFIER: return "IDENTIFIER";
200 case TYPE_NAME: return "TYPE_NAME";
201 case CONSTANT: return "CONSTANT";
202 case STRING_LITERAL: return "STRING_LITERAL";
203 case SIZEOF: return "SIZEOF";
204 case PTR_OP: return "PTR_OP";
205 case INC_OP: return "INC_OP";
206 case DEC_OP: return "DEC_OP";
207 case LEFT_OP: return "LEFT_OP";
208 case RIGHT_OP: return "RIGHT_OP";
209 case LE_OP: return "LE_OP";
210 case GE_OP: return "GE_OP";
211 case EQ_OP: return "EQ_OP";
212 case NE_OP: return "NE_OP";
213 case AND_OP: return "AND_OP";
214 case OR_OP: return "OR_OP";
215 case MUL_ASSIGN: return "MUL_ASSIGN";
216 case DIV_ASSIGN: return "DIV_ASSIGN";
217 case MOD_ASSIGN: return "MOD_ASSIGN";
218 case ADD_ASSIGN: return "ADD_ASSIGN";
219 case SUB_ASSIGN: return "SUB_ASSIGN";
220 case LEFT_ASSIGN: return "LEFT_ASSIGN";
221 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
222 case AND_ASSIGN: return "AND_ASSIGN";
223 case XOR_ASSIGN: return "XOR_ASSIGN";
224 case OR_ASSIGN: return "OR_ASSIGN";
225 case TYPEDEF: return "TYPEDEF";
226 case EXTERN: return "EXTERN";
227 case STATIC: return "STATIC";
228 case AUTO: return "AUTO";
229 case REGISTER: return "REGISTER";
230 case CODE: return "CODE";
231 case EEPROM: return "EEPROM";
232 case INTERRUPT: return "INTERRUPT";
233 case SFR: return "SFR";
234 case AT: return "AT";
235 case SBIT: return "SBIT";
236 case REENTRANT: return "REENTRANT";
237 case USING: return "USING";
238 case XDATA: return "XDATA";
239 case DATA: return "DATA";
240 case IDATA: return "IDATA";
241 case PDATA: return "PDATA";
242 case VAR_ARGS: return "VAR_ARGS";
243 case CRITICAL: return "CRITICAL";
244 case NONBANKED: return "NONBANKED";
245 case BANKED: return "BANKED";
246 case CHAR: return "CHAR";
247 case SHORT: return "SHORT";
248 case INT: return "INT";
249 case LONG: return "LONG";
250 case SIGNED: return "SIGNED";
251 case UNSIGNED: return "UNSIGNED";
252 case FLOAT: return "FLOAT";
253 case DOUBLE: return "DOUBLE";
254 case CONST: return "CONST";
255 case VOLATILE: return "VOLATILE";
256 case VOID: return "VOID";
257 case BIT: return "BIT";
258 case STRUCT: return "STRUCT";
259 case UNION: return "UNION";
260 case ENUM: return "ENUM";
261 case ELIPSIS: return "ELIPSIS";
262 case RANGE: return "RANGE";
263 case FAR: return "FAR";
264 case CASE: return "CASE";
265 case DEFAULT: return "DEFAULT";
266 case IF: return "IF";
267 case ELSE: return "ELSE";
268 case SWITCH: return "SWITCH";
269 case WHILE: return "WHILE";
270 case DO: return "DO";
271 case FOR: return "FOR";
272 case GOTO: return "GOTO";
273 case CONTINUE: return "CONTINUE";
274 case BREAK: return "BREAK";
275 case RETURN: return "RETURN";
276 case INLINEASM: return "INLINEASM";
277 case IFX: return "IFX";
278 case ADDRESS_OF: return "ADDRESS_OF";
279 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
280 case SPIL: return "SPIL";
281 case UNSPIL: return "UNSPIL";
282 case GETHBIT: return "GETHBIT";
283 case BITWISEAND: return "BITWISEAND";
284 case UNARYMINUS: return "UNARYMINUS";
285 case IPUSH: return "IPUSH";
286 case IPOP: return "IPOP";
287 case PCALL: return "PCALL";
288 case ENDFUNCTION: return "ENDFUNCTION";
289 case JUMPTABLE: return "JUMPTABLE";
290 case RRC: return "RRC";
291 case RLC: return "RLC";
292 case CAST: return "CAST";
293 case CALL: return "CALL";
294 case PARAM: return "PARAM ";
295 case NULLOP: return "NULLOP";
296 case BLOCK: return "BLOCK";
297 case LABEL: return "LABEL";
298 case RECEIVE: return "RECEIVE";
299 case SEND: return "SEND";
301 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
305 /*-----------------------------------------------------------------*/
306 /*-----------------------------------------------------------------*/
308 debugLogRegType (short type)
310 if(!pic16_ralloc_debug)return NULL;
312 case REG_GPR: return "REG_GPR";
313 case REG_PTR: return "REG_PTR";
314 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
321 /*-----------------------------------------------------------------*/
322 /*-----------------------------------------------------------------*/
323 static int regname2key(char const *name)
332 key += (*name++) + 1;
336 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
348 dReg = Safe_calloc(1,sizeof(regs));
350 dReg->pc_type = pc_type;
353 dReg->name = Safe_strdup(name);
355 sprintf(buffer,"r0x%02X", dReg->rIdx);
358 dReg->name = Safe_strdup(buffer);
365 // dReg->isMapped = 0;
368 if(type == REG_SFR) {
370 dReg->address = rIdx;
371 dReg->accessBank = 1;
375 dReg->accessBank = 0;
378 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
382 dReg->reg_alias = NULL;
383 dReg->reglives.usedpFlows = newSet();
384 dReg->reglives.assignedpFlows = newSet();
387 if(!(type == REG_SFR && alias == 0x80))
388 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
393 /*-----------------------------------------------------------------*/
394 /* regWithIdx - Search through a set of registers that matches idx */
395 /*-----------------------------------------------------------------*/
397 regWithIdx (set *dRegs, int idx, int fixed)
401 for (dReg = setFirstItem(dRegs) ; dReg ;
402 dReg = setNextItem(dRegs)) {
404 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
412 /*-----------------------------------------------------------------*/
413 /* regFindFree - Search for a free register in a set of registers */
414 /*-----------------------------------------------------------------*/
416 regFindFree (set *dRegs)
420 for (dReg = setFirstItem(dRegs) ; dReg ;
421 dReg = setNextItem(dRegs)) {
423 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
424 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
433 /*-----------------------------------------------------------------*/
434 /* pic16_initStack - allocate registers for a pseudo stack */
435 /*-----------------------------------------------------------------*/
436 void pic16_initStack(int base_address, int size)
441 pic16_Gstack_base_addr = base_address;
442 //fprintf(stderr,"initStack");
444 for(i = 0; i<size; i++)
445 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
448 /*-----------------------------------------------------------------*
449 *-----------------------------------------------------------------*/
451 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
453 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
455 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
457 reg->wasUsed = 0; // we do not know if they are going to be used at all
458 reg->accessBank = 1; // implicit add access Bank
460 return addSet(&pic16_dynProcessorRegs, reg);
463 /*-----------------------------------------------------------------*
464 *-----------------------------------------------------------------*/
467 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
469 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
471 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
475 return addSet(&pic16_dynInternalRegs,reg);
480 /*-----------------------------------------------------------------*/
481 /* allocReg - allocates register of given type */
482 /*-----------------------------------------------------------------*/
484 allocReg (short type)
489 if(dynrIdx > pic16_nRegs)
493 /* try to reuse some unused registers */
494 reg = regFindFree( pic16_dynAllocRegs );
497 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
498 addSet(&pic16_dynAllocRegs, reg);
502 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
504 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
505 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
508 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
509 reg->isLocal = 1; /* this is a local frame register */
513 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
514 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
517 return (reg); // addSet(&pic16_dynAllocRegs,reg);
522 /*-----------------------------------------------------------------*/
523 /* pic16_dirregWithName - search for register by name */
524 /*-----------------------------------------------------------------*/
526 pic16_dirregWithName (char *name)
534 /* hash the name to get a key */
536 hkey = regname2key(name);
538 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
540 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
544 if(STRCASECMP(reg->name, name) == 0) {
548 reg = hTabNextItemWK (dynDirectRegNames);
552 return NULL; // name wasn't found in the hash table
555 static int IS_CONFIG_ADDRESS(int address)
558 return address >= 0x300000 && address <= 0x300000d;
561 /*-----------------------------------------------------------------*/
562 /* pic16_allocDirReg - allocates register of given type */
563 /*-----------------------------------------------------------------*/
565 pic16_allocDirReg (operand *op )
571 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
572 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
576 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
578 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { // patch 13
579 if(pic16_debug_verbose) //
581 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, //
582 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname); //
587 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
588 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
591 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
592 debugLog(" %d const char\n",__LINE__);
593 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
594 // fprintf(stderr, " %d const char\n",__LINE__);
595 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
599 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
600 if (IS_CODE ( OP_SYM_ETYPE(op)) )
601 debugLog(" %d code space\n",__LINE__);
603 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
604 debugLog(" %d integral\n",__LINE__);
606 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
607 debugLog(" %d literal\n",__LINE__);
609 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
610 debugLog(" %d specifier\n",__LINE__);
612 debugAopGet(NULL, op);
615 if (IS_CODE ( OP_SYM_ETYPE(op)) )
618 /* First, search the hash table to see if there is a register with this name */
619 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
621 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
625 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
626 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
628 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
629 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
632 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
634 reg = pic16_dirregWithName(name);
639 int regtype = REG_GPR;
641 /* if this is at an absolute address, then get the address. */
642 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
643 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
644 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
647 /* Register wasn't found in hash, so let's create
648 * a new one and put it in the hash table AND in the
649 * dynDirectRegNames set */
650 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);
654 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
658 if(!IS_CONFIG_ADDRESS(address)) {
659 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
661 /* this is an error, why added? -- VR */
662 // if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
664 if(OP_SYMBOL(op)->onStack) {
665 // fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
666 OP_SYMBOL(op)->onStack = 0;
667 SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
671 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13
672 if(pic16_debug_verbose) //
674 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d\n",
675 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
676 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
677 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
678 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
679 IN_STACK( OP_SYM_ETYPE(op)));
681 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
682 OP_SYMBOL(op)->name); //
687 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
688 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
690 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
692 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
693 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
694 // reg->type = REG_SFR;
697 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
698 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
699 addSet(&pic16_dynDirectBitRegs, reg);
702 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
703 // addSet(&pic16_dynDirectRegs, reg);
704 checkAddReg(&pic16_dynDirectRegs, reg);
708 debugLog (" -- %s is declared at address 0x30000x\n",name);
709 fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
715 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
717 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
719 /* work around for user defined registers in access bank */
720 if((reg->address>= 0x00 && reg->address < 0x80)
721 || (reg->address >= 0xf80 && reg->address <= 0xfff))
724 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
730 /*-----------------------------------------------------------------*/
731 /* pic16_allocRegByName - allocates register of given type */
732 /*-----------------------------------------------------------------*/
734 pic16_allocRegByName (char *name, int size)
740 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
744 /* First, search the hash table to see if there is a register with this name */
745 reg = pic16_dirregWithName(name);
749 /* Register wasn't found in hash, so let's create
750 * a new one and put it in the hash table AND in the
751 * dynDirectRegNames set */
752 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
753 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
755 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
756 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
758 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
759 addSet(&pic16_dynDirectRegs, reg);
765 /*-----------------------------------------------------------------*/
766 /* RegWithIdx - returns pointer to register with index number */
767 /*-----------------------------------------------------------------*/
768 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
773 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
774 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
779 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
781 debugLog ("Found a Dynamic Register!\n");
784 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
785 debugLog ("Found a Direct Register!\n");
791 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
792 debugLog ("Found a Stack Register!\n");
797 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
798 debugLog ("Found a Processor Register!\n");
812 /*-----------------------------------------------------------------*/
813 /* pic16_regWithIdx - returns pointer to register with index number*/
814 /*-----------------------------------------------------------------*/
816 pic16_regWithIdx (int idx)
820 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
823 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
826 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
832 /*-----------------------------------------------------------------*/
833 /* pic16_regWithIdx - returns pointer to register with index number */
834 /*-----------------------------------------------------------------*/
836 pic16_allocWithIdx (int idx)
841 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
842 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
844 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
846 debugLog ("Found a Dynamic Register!\n");
847 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
848 debugLog ("Found a Stack Register!\n");
849 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
850 debugLog ("Found a Processor Register!\n");
851 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
852 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
853 debugLog ("Found an Internal Register!\n");
856 debugLog ("Dynamic Register not found\n");
859 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
860 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
861 "regWithIdx not found");
871 /*-----------------------------------------------------------------*/
872 /*-----------------------------------------------------------------*/
874 pic16_findFreeReg(short type)
881 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
883 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
887 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
899 /*-----------------------------------------------------------------*/
900 /* freeReg - frees a register */
901 /*-----------------------------------------------------------------*/
905 debugLog ("%s\n", __FUNCTION__);
906 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
911 /*-----------------------------------------------------------------*/
912 /* nFreeRegs - returns number of free registers */
913 /*-----------------------------------------------------------------*/
921 /* although I fixed the register allocation/freeing scheme
922 * the for loop below doesn't give valid results. I do not
923 * know why yet. -- VR 10-Jan-2003 */
928 /* dynamically allocate as many as we need and worry about
929 * fitting them into a PIC later */
931 debugLog ("%s\n", __FUNCTION__);
933 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
934 if((reg->type == type) && reg->isFree)nfr++;
936 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
940 /*-----------------------------------------------------------------*/
941 /* nfreeRegsType - free registers with type */
942 /*-----------------------------------------------------------------*/
944 nfreeRegsType (int type)
947 debugLog ("%s\n", __FUNCTION__);
950 if ((nfr = nFreeRegs (type)) == 0)
951 return nFreeRegs (REG_GPR);
954 return nFreeRegs (type);
957 static void writeSetUsedRegs(FILE *of, set *dRegs)
962 for (dReg = setFirstItem(dRegs) ; dReg ;
963 dReg = setNextItem(dRegs)) {
966 fprintf (of, "\t%s\n",dReg->name);
972 extern void pic16_groupRegistersInSection(set *regset);
974 extern void pic16_dump_equates(FILE *of, set *equs);
975 //extern void pic16_dump_map(void);
976 extern void pic16_dump_section(FILE *of, set *section, int fix);
977 extern void pic16_dump_int_registers(FILE *of, set *section);
978 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
980 static void packBits(set *bregs)
985 regs *relocbitfield=NULL;
991 for (regset = bregs ; regset ;
992 regset = regset->next) {
995 breg->isBitField = 1;
996 //fprintf(stderr,"bit reg: %s\n",breg->name);
999 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1001 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1002 breg->rIdx = breg->address & 7;
1003 breg->address >>= 3;
1006 sprintf (buffer, "fbitfield%02x", breg->address);
1007 //fprintf(stderr,"new bit field\n");
1008 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1009 bitfield->isBitField = 1;
1010 bitfield->isFixed = 1;
1011 bitfield->address = breg->address;
1012 addSet(&pic16_dynDirectRegs,bitfield);
1013 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1015 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1018 breg->reg_alias = bitfield;
1022 if(!relocbitfield || bit_no >7) {
1025 sprintf (buffer, "bitfield%d", byte_no);
1026 //fprintf(stderr,"new relocatable bit field\n");
1027 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1028 relocbitfield->isBitField = 1;
1029 addSet(&pic16_dynDirectRegs,relocbitfield);
1030 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1034 breg->reg_alias = relocbitfield;
1035 breg->address = rDirectIdx; /* byte_no; */
1036 breg->rIdx = bit_no++;
1045 static void bitEQUs(FILE *of, set *bregs)
1047 regs *breg,*bytereg;
1050 //fprintf(stderr," %s\n",__FUNCTION__);
1051 for (breg = setFirstItem(bregs) ; breg ;
1052 breg = setNextItem(bregs)) {
1054 //fprintf(stderr,"bit reg: %s\n",breg->name);
1056 bytereg = breg->reg_alias;
1058 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1061 breg->rIdx & 0x0007);
1064 fprintf(stderr, "bit field is not assigned to a register\n");
1065 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1076 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1081 for (reg = setFirstItem(fregs) ; reg ;
1082 reg = setNextItem(fregs)) {
1084 if(!reg->isEmitted && reg->wasUsed) {
1086 if (reg->type != REG_SFR) {
1087 fprintf (of, "%s\tEQU\t0x%03x\n",
1093 fprintf (of, "%s\tEQU\t0x%03x\n",
1102 void pic16_writeUsedRegs(FILE *of)
1104 packBits(pic16_dynDirectBitRegs);
1106 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1107 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1108 pic16_groupRegistersInSection(pic16_dynStackRegs);
1109 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1110 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1111 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1115 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1116 pic16_assignFixedRegisters(pic16_dynStackRegs);
1117 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1118 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1120 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1121 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1122 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1123 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1124 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1127 // pic16_dump_map();
1128 // pic16_dump_cblock(of);
1131 pic16_dump_equates(of, pic16_equ_data);
1133 /* dump initialised data */
1134 pic16_dump_idata(of, idataSymSet);
1136 /* dump internal registers */
1137 pic16_dump_int_registers(of, pic16_int_regs);
1139 /* dump other variables */
1140 pic16_dump_section(of, pic16_rel_udata, 0);
1141 pic16_dump_section(of, pic16_fix_udata, 1);
1146 /*-----------------------------------------------------------------*/
1147 /* allDefsOutOfRange - all definitions are out of a range */
1148 /*-----------------------------------------------------------------*/
1150 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1154 debugLog ("%s\n", __FUNCTION__);
1158 for (i = 0; i < defs->size; i++)
1162 if (bitVectBitValue (defs, i) &&
1163 (ic = hTabItemWithKey (iCodehTab, i)) &&
1164 (ic->seq >= fseq && ic->seq <= toseq))
1174 /*-----------------------------------------------------------------*/
1175 /* computeSpillable - given a point find the spillable live ranges */
1176 /*-----------------------------------------------------------------*/
1178 computeSpillable (iCode * ic)
1182 debugLog ("%s\n", __FUNCTION__);
1183 /* spillable live ranges are those that are live at this
1184 point . the following categories need to be subtracted
1186 a) - those that are already spilt
1187 b) - if being used by this one
1188 c) - defined by this one */
1190 spillable = bitVectCopy (ic->rlive);
1192 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1194 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1195 bitVectUnSetBit (spillable, ic->defKey);
1196 spillable = bitVectIntersect (spillable, _G.regAssigned);
1201 /*-----------------------------------------------------------------*/
1202 /* noSpilLoc - return true if a variable has no spil location */
1203 /*-----------------------------------------------------------------*/
1205 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1207 debugLog ("%s\n", __FUNCTION__);
1208 return (sym->usl.spillLoc ? 0 : 1);
1211 /*-----------------------------------------------------------------*/
1212 /* hasSpilLoc - will return 1 if the symbol has spil location */
1213 /*-----------------------------------------------------------------*/
1215 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1217 debugLog ("%s\n", __FUNCTION__);
1218 return (sym->usl.spillLoc ? 1 : 0);
1221 /*-----------------------------------------------------------------*/
1222 /* directSpilLoc - will return 1 if the splilocation is in direct */
1223 /*-----------------------------------------------------------------*/
1225 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1227 debugLog ("%s\n", __FUNCTION__);
1228 if (sym->usl.spillLoc &&
1229 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1235 /*-----------------------------------------------------------------*/
1236 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1237 /* but is not used as a pointer */
1238 /*-----------------------------------------------------------------*/
1240 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1242 debugLog ("%s\n", __FUNCTION__);
1243 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1246 /*-----------------------------------------------------------------*/
1247 /* rematable - will return 1 if the remat flag is set */
1248 /*-----------------------------------------------------------------*/
1250 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1252 debugLog ("%s\n", __FUNCTION__);
1256 /*-----------------------------------------------------------------*/
1257 /* notUsedInRemaining - not used or defined in remain of the block */
1258 /*-----------------------------------------------------------------*/
1260 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1262 debugLog ("%s\n", __FUNCTION__);
1263 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1264 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1267 /*-----------------------------------------------------------------*/
1268 /* allLRs - return true for all */
1269 /*-----------------------------------------------------------------*/
1271 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1273 debugLog ("%s\n", __FUNCTION__);
1277 /*-----------------------------------------------------------------*/
1278 /* liveRangesWith - applies function to a given set of live range */
1279 /*-----------------------------------------------------------------*/
1281 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1282 eBBlock * ebp, iCode * ic)
1287 debugLog ("%s\n", __FUNCTION__);
1288 if (!lrs || !lrs->size)
1291 for (i = 1; i < lrs->size; i++)
1294 if (!bitVectBitValue (lrs, i))
1297 /* if we don't find it in the live range
1298 hash table we are in serious trouble */
1299 if (!(sym = hTabItemWithKey (liveRanges, i)))
1301 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1302 "liveRangesWith could not find liveRange");
1306 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1307 addSetHead (&rset, sym);
1314 /*-----------------------------------------------------------------*/
1315 /* leastUsedLR - given a set determines which is the least used */
1316 /*-----------------------------------------------------------------*/
1318 leastUsedLR (set * sset)
1320 symbol *sym = NULL, *lsym = NULL;
1322 debugLog ("%s\n", __FUNCTION__);
1323 sym = lsym = setFirstItem (sset);
1328 for (; lsym; lsym = setNextItem (sset))
1331 /* if usage is the same then prefer
1332 the spill the smaller of the two */
1333 if (lsym->used == sym->used)
1334 if (getSize (lsym->type) < getSize (sym->type))
1338 if (lsym->used < sym->used)
1343 setToNull ((void *) &sset);
1348 /*-----------------------------------------------------------------*/
1349 /* noOverLap - will iterate through the list looking for over lap */
1350 /*-----------------------------------------------------------------*/
1352 noOverLap (set * itmpStack, symbol * fsym)
1355 debugLog ("%s\n", __FUNCTION__);
1358 for (sym = setFirstItem (itmpStack); sym;
1359 sym = setNextItem (itmpStack))
1361 if (sym->liveTo > fsym->liveFrom)
1369 /*-----------------------------------------------------------------*/
1370 /* isFree - will return 1 if the a free spil location is found */
1371 /*-----------------------------------------------------------------*/
1376 V_ARG (symbol **, sloc);
1377 V_ARG (symbol *, fsym);
1379 debugLog ("%s\n", __FUNCTION__);
1380 /* if already found */
1384 /* if it is free && and the itmp assigned to
1385 this does not have any overlapping live ranges
1386 with the one currently being assigned and
1387 the size can be accomodated */
1389 noOverLap (sym->usl.itmpStack, fsym) &&
1390 getSize (sym->type) >= getSize (fsym->type))
1399 /*-----------------------------------------------------------------*/
1400 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1401 /*-----------------------------------------------------------------*/
1403 spillLRWithPtrReg (symbol * forSym)
1409 debugLog ("%s\n", __FUNCTION__);
1410 if (!_G.regAssigned ||
1411 bitVectIsZero (_G.regAssigned))
1414 r0 = pic16_regWithIdx (R0_IDX);
1415 r1 = pic16_regWithIdx (R1_IDX);
1417 /* for all live ranges */
1418 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1419 lrsym = hTabNextItem (liveRanges, &k))
1423 /* if no registers assigned to it or
1425 /* if it does not overlap with this then
1426 not need to spill it */
1428 if (lrsym->isspilt || !lrsym->nRegs ||
1429 (lrsym->liveTo < forSym->liveFrom))
1432 /* go thru the registers : if it is either
1433 r0 or r1 then spil it */
1434 for (j = 0; j < lrsym->nRegs; j++)
1435 if (lrsym->regs[j] == r0 ||
1436 lrsym->regs[j] == r1)
1445 /*-----------------------------------------------------------------*/
1446 /* createStackSpil - create a location on the stack to spil */
1447 /*-----------------------------------------------------------------*/
1449 createStackSpil (symbol * sym)
1451 symbol *sloc = NULL;
1452 int useXstack, model, noOverlay;
1454 char slocBuffer[30];
1455 debugLog ("%s\n", __FUNCTION__);
1457 /* first go try and find a free one that is already
1458 existing on the stack */
1459 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1461 /* found a free one : just update & return */
1462 sym->usl.spillLoc = sloc;
1465 addSetHead (&sloc->usl.itmpStack, sym);
1469 /* could not then have to create one , this is the hard part
1470 we need to allocate this on the stack : this is really a
1471 hack!! but cannot think of anything better at this time */
1473 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1475 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1476 __FILE__, __LINE__);
1480 sloc = newiTemp (slocBuffer);
1482 /* set the type to the spilling symbol */
1483 sloc->type = copyLinkChain (sym->type);
1484 sloc->etype = getSpec (sloc->type);
1485 SPEC_SCLS (sloc->etype) = S_DATA;
1486 SPEC_EXTR (sloc->etype) = 0;
1487 SPEC_STAT (sloc->etype) = 0;
1489 /* we don't allow it to be allocated`
1490 onto the external stack since : so we
1491 temporarily turn it off ; we also
1492 turn off memory model to prevent
1493 the spil from going to the external storage
1494 and turn off overlaying
1497 useXstack = options.useXstack;
1498 model = options.model;
1499 noOverlay = options.noOverlay;
1500 options.noOverlay = 1;
1501 options.model = options.useXstack = 0;
1505 options.useXstack = useXstack;
1506 options.model = model;
1507 options.noOverlay = noOverlay;
1508 sloc->isref = 1; /* to prevent compiler warning */
1510 /* if it is on the stack then update the stack */
1511 if (IN_STACK (sloc->etype))
1513 currFunc->stack += getSize (sloc->type);
1514 _G.stackExtend += getSize (sloc->type);
1517 _G.dataExtend += getSize (sloc->type);
1519 /* add it to the _G.stackSpil set */
1520 addSetHead (&_G.stackSpil, sloc);
1521 sym->usl.spillLoc = sloc;
1524 /* add it to the set of itempStack set
1525 of the spill location */
1526 addSetHead (&sloc->usl.itmpStack, sym);
1530 /*-----------------------------------------------------------------*/
1531 /* isSpiltOnStack - returns true if the spil location is on stack */
1532 /*-----------------------------------------------------------------*/
1534 isSpiltOnStack (symbol * sym)
1538 debugLog ("%s\n", __FUNCTION__);
1545 /* if (sym->_G.stackSpil) */
1548 if (!sym->usl.spillLoc)
1551 etype = getSpec (sym->usl.spillLoc->type);
1552 if (IN_STACK (etype))
1558 /*-----------------------------------------------------------------*/
1559 /* spillThis - spils a specific operand */
1560 /*-----------------------------------------------------------------*/
1562 spillThis (symbol * sym)
1565 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1567 /* if this is rematerializable or has a spillLocation
1568 we are okay, else we need to create a spillLocation
1570 if (!(sym->remat || sym->usl.spillLoc))
1571 createStackSpil (sym);
1574 /* mark it has spilt & put it in the spilt set */
1576 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1578 bitVectUnSetBit (_G.regAssigned, sym->key);
1580 for (i = 0; i < sym->nRegs; i++)
1584 freeReg (sym->regs[i]);
1585 sym->regs[i] = NULL;
1588 /* if spilt on stack then free up r0 & r1
1589 if they could have been assigned to some
1591 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1594 spillLRWithPtrReg (sym);
1597 if (sym->usl.spillLoc && !sym->remat)
1598 sym->usl.spillLoc->allocreq = 1;
1602 /*-----------------------------------------------------------------*/
1603 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1604 /*-----------------------------------------------------------------*/
1606 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1608 bitVect *lrcs = NULL;
1612 debugLog ("%s\n", __FUNCTION__);
1613 /* get the spillable live ranges */
1614 lrcs = computeSpillable (ic);
1616 /* get all live ranges that are rematerizable */
1617 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1620 /* return the least used of these */
1621 return leastUsedLR (selectS);
1624 /* get live ranges with spillLocations in direct space */
1625 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1627 sym = leastUsedLR (selectS);
1628 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1629 sym->usl.spillLoc->rname :
1630 sym->usl.spillLoc->name));
1632 /* mark it as allocation required */
1633 sym->usl.spillLoc->allocreq = 1;
1637 /* if the symbol is local to the block then */
1638 if (forSym->liveTo < ebp->lSeq)
1641 /* check if there are any live ranges allocated
1642 to registers that are not used in this block */
1643 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1645 sym = leastUsedLR (selectS);
1646 /* if this is not rematerializable */
1655 /* check if there are any live ranges that not
1656 used in the remainder of the block */
1657 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1659 sym = leastUsedLR (selectS);
1662 sym->remainSpil = 1;
1669 /* find live ranges with spillocation && not used as pointers */
1670 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1673 sym = leastUsedLR (selectS);
1674 /* mark this as allocation required */
1675 sym->usl.spillLoc->allocreq = 1;
1679 /* find live ranges with spillocation */
1680 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1683 sym = leastUsedLR (selectS);
1684 sym->usl.spillLoc->allocreq = 1;
1688 /* couldn't find then we need to create a spil
1689 location on the stack , for which one? the least
1691 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1694 /* return a created spil location */
1695 sym = createStackSpil (leastUsedLR (selectS));
1696 sym->usl.spillLoc->allocreq = 1;
1700 /* this is an extreme situation we will spill
1701 this one : happens very rarely but it does happen */
1707 /*-----------------------------------------------------------------*/
1708 /* spilSomething - spil some variable & mark registers as free */
1709 /*-----------------------------------------------------------------*/
1711 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1716 debugLog ("%s\n", __FUNCTION__);
1717 /* get something we can spil */
1718 ssym = selectSpil (ic, ebp, forSym);
1720 /* mark it as spilt */
1722 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1724 /* mark it as not register assigned &
1725 take it away from the set */
1726 bitVectUnSetBit (_G.regAssigned, ssym->key);
1728 /* mark the registers as free */
1729 for (i = 0; i < ssym->nRegs; i++)
1731 freeReg (ssym->regs[i]);
1733 /* if spilt on stack then free up r0 & r1
1734 if they could have been assigned to as gprs */
1735 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1738 spillLRWithPtrReg (ssym);
1741 /* if this was a block level spil then insert push & pop
1742 at the start & end of block respectively */
1743 if (ssym->blockSpil)
1745 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1746 /* add push to the start of the block */
1747 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1748 ebp->sch->next : ebp->sch));
1749 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1750 /* add pop to the end of the block */
1751 addiCodeToeBBlock (ebp, nic, NULL);
1754 /* if spilt because not used in the remainder of the
1755 block then add a push before this instruction and
1756 a pop at the end of the block */
1757 if (ssym->remainSpil)
1760 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1761 /* add push just before this instruction */
1762 addiCodeToeBBlock (ebp, nic, ic);
1764 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1765 /* add pop to the end of the block */
1766 addiCodeToeBBlock (ebp, nic, NULL);
1775 /*-----------------------------------------------------------------*/
1776 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1777 /*-----------------------------------------------------------------*/
1779 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1784 debugLog ("%s\n", __FUNCTION__);
1786 /* try for a ptr type */
1787 if ((reg = allocReg (REG_PTR)))
1790 /* try for gpr type */
1791 if ((reg = allocReg (REG_GPR)))
1794 /* we have to spil */
1795 if (!spilSomething (ic, ebp, sym))
1798 /* make sure partially assigned registers aren't reused */
1799 for (j=0; j<=sym->nRegs; j++)
1801 sym->regs[j]->isFree = 0;
1803 /* this looks like an infinite loop but
1804 in really selectSpil will abort */
1808 /*-----------------------------------------------------------------*/
1809 /* getRegGpr - will try for GPR if not spil */
1810 /*-----------------------------------------------------------------*/
1812 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1817 debugLog ("%s\n", __FUNCTION__);
1819 /* try for gpr type */
1820 if ((reg = allocReg (REG_GPR)))
1823 if (!pic16_ptrRegReq)
1824 if ((reg = allocReg (REG_PTR)))
1827 /* we have to spil */
1828 if (!spilSomething (ic, ebp, sym))
1831 /* make sure partially assigned registers aren't reused */
1832 for (j=0; j<=sym->nRegs; j++)
1834 sym->regs[j]->isFree = 0;
1836 /* this looks like an infinite loop but
1837 in really selectSpil will abort */
1841 /*-----------------------------------------------------------------*/
1842 /* symHasReg - symbol has a given register */
1843 /*-----------------------------------------------------------------*/
1845 symHasReg (symbol * sym, regs * reg)
1849 debugLog ("%s\n", __FUNCTION__);
1850 for (i = 0; i < sym->nRegs; i++)
1851 if (sym->regs[i] == reg)
1857 /*-----------------------------------------------------------------*/
1858 /* deassignLRs - check the live to and if they have registers & are */
1859 /* not spilt then free up the registers */
1860 /*-----------------------------------------------------------------*/
1862 deassignLRs (iCode * ic, eBBlock * ebp)
1868 debugLog ("%s\n", __FUNCTION__);
1869 for (sym = hTabFirstItem (liveRanges, &k); sym;
1870 sym = hTabNextItem (liveRanges, &k))
1873 symbol *psym = NULL;
1874 /* if it does not end here */
1875 if (sym->liveTo > ic->seq)
1878 /* if it was spilt on stack then we can
1879 mark the stack spil location as free */
1884 sym->usl.spillLoc->isFree = 1;
1890 if (!bitVectBitValue (_G.regAssigned, sym->key))
1893 /* special case check if this is an IFX &
1894 the privious one was a pop and the
1895 previous one was not spilt then keep track
1897 if (ic->op == IFX && ic->prev &&
1898 ic->prev->op == IPOP &&
1899 !ic->prev->parmPush &&
1900 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1901 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1907 bitVectUnSetBit (_G.regAssigned, sym->key);
1909 /* if the result of this one needs registers
1910 and does not have it then assign it right
1912 if (IC_RESULT (ic) &&
1913 !(SKIP_IC2 (ic) || /* not a special icode */
1914 ic->op == JUMPTABLE ||
1919 POINTER_SET (ic)) &&
1920 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1921 result->liveTo > ic->seq && /* and will live beyond this */
1922 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1923 result->regType == sym->regType && /* same register types */
1924 result->nRegs && /* which needs registers */
1925 !result->isspilt && /* and does not already have them */
1927 !bitVectBitValue (_G.regAssigned, result->key) &&
1928 /* the number of free regs + number of regs in this LR
1929 can accomodate the what result Needs */
1930 ((nfreeRegsType (result->regType) +
1931 sym->nRegs) >= result->nRegs)
1935 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1937 result->regs[i] = sym->regs[i];
1939 result->regs[i] = getRegGpr (ic, ebp, result);
1941 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1945 /* free the remaining */
1946 for (; i < sym->nRegs; i++)
1950 if (!symHasReg (psym, sym->regs[i]))
1951 freeReg (sym->regs[i]);
1954 freeReg (sym->regs[i]);
1961 /*-----------------------------------------------------------------*/
1962 /* reassignLR - reassign this to registers */
1963 /*-----------------------------------------------------------------*/
1965 reassignLR (operand * op)
1967 symbol *sym = OP_SYMBOL (op);
1970 debugLog ("%s\n", __FUNCTION__);
1971 /* not spilt any more */
1972 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1973 bitVectUnSetBit (_G.spiltSet, sym->key);
1975 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1979 for (i = 0; i < sym->nRegs; i++)
1980 sym->regs[i]->isFree = 0;
1983 /*-----------------------------------------------------------------*/
1984 /* willCauseSpill - determines if allocating will cause a spill */
1985 /*-----------------------------------------------------------------*/
1987 willCauseSpill (int nr, int rt)
1989 debugLog ("%s\n", __FUNCTION__);
1990 /* first check if there are any avlb registers
1991 of te type required */
1994 /* special case for pointer type
1995 if pointer type not avlb then
1996 check for type gpr */
1997 if (nFreeRegs (rt) >= nr)
1999 if (nFreeRegs (REG_GPR) >= nr)
2004 if (pic16_ptrRegReq)
2006 if (nFreeRegs (rt) >= nr)
2011 if (nFreeRegs (REG_PTR) +
2012 nFreeRegs (REG_GPR) >= nr)
2017 debugLog (" ... yep it will (cause a spill)\n");
2018 /* it will cause a spil */
2022 /*-----------------------------------------------------------------*/
2023 /* positionRegs - the allocator can allocate same registers to res- */
2024 /* ult and operand, if this happens make sure they are in the same */
2025 /* position as the operand otherwise chaos results */
2026 /*-----------------------------------------------------------------*/
2028 positionRegs (symbol * result, symbol * opsym, int lineno)
2030 int count = min (result->nRegs, opsym->nRegs);
2031 int i, j = 0, shared = 0;
2033 debugLog ("%s\n", __FUNCTION__);
2034 /* if the result has been spilt then cannot share */
2039 /* first make sure that they actually share */
2040 for (i = 0; i < count; i++)
2042 for (j = 0; j < count; j++)
2044 if (result->regs[i] == opsym->regs[j] && i != j)
2054 regs *tmp = result->regs[i];
2055 result->regs[i] = result->regs[j];
2056 result->regs[j] = tmp;
2061 /*------------------------------------------------------------------*/
2062 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2063 /* it should either have registers or have beed spilled. Otherwise, */
2064 /* there was an uninitialized variable, so just spill this to get */
2065 /* the operand in a valid state. */
2066 /*------------------------------------------------------------------*/
2068 verifyRegsAssigned (operand *op, iCode * ic)
2073 if (!IS_ITEMP (op)) return;
2075 sym = OP_SYMBOL (op);
2076 if (sym->isspilt) return;
2077 if (!sym->nRegs) return;
2078 if (sym->regs[0]) return;
2080 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2081 sym->prereqv ? sym->prereqv->name : sym->name);
2086 /*-----------------------------------------------------------------*/
2087 /* serialRegAssign - serially allocate registers to the variables */
2088 /*-----------------------------------------------------------------*/
2090 serialRegAssign (eBBlock ** ebbs, int count)
2094 debugLog ("%s\n", __FUNCTION__);
2095 /* for all blocks */
2096 for (i = 0; i < count; i++)
2101 if (ebbs[i]->noPath &&
2102 (ebbs[i]->entryLabel != entryLabel &&
2103 ebbs[i]->entryLabel != returnLabel))
2106 /* of all instructions do */
2107 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2110 debugLog (" op: %s\n", decodeOp (ic->op));
2112 /* if this is an ipop that means some live
2113 range will have to be assigned again */
2115 reassignLR (IC_LEFT (ic));
2117 /* if result is present && is a true symbol */
2118 if (IC_RESULT (ic) && ic->op != IFX &&
2119 IS_TRUE_SYMOP (IC_RESULT (ic)))
2120 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2122 /* take away registers from live
2123 ranges that end at this instruction */
2124 deassignLRs (ic, ebbs[i]);
2126 /* some don't need registers */
2127 if (SKIP_IC2 (ic) ||
2128 ic->op == JUMPTABLE ||
2132 (IC_RESULT (ic) && POINTER_SET (ic)))
2135 /* now we need to allocate registers
2136 only for the result */
2139 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2145 /* if it does not need or is spilt
2146 or is already assigned to registers
2147 or will not live beyond this instructions */
2150 bitVectBitValue (_G.regAssigned, sym->key) ||
2151 sym->liveTo <= ic->seq)
2154 /* if some liverange has been spilt at the block level
2155 and this one live beyond this block then spil this
2157 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2162 /* if trying to allocate this will cause
2163 a spill and there is nothing to spill
2164 or this one is rematerializable then
2166 willCS = willCauseSpill (sym->nRegs, sym->regType);
2167 spillable = computeSpillable (ic);
2169 (willCS && bitVectIsZero (spillable)))
2177 /* if it has a spillocation & is used less than
2178 all other live ranges then spill this */
2180 if (sym->usl.spillLoc) {
2181 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2182 allLRs, ebbs[i], ic));
2183 if (leastUsed && leastUsed->used > sym->used) {
2188 /* if none of the liveRanges have a spillLocation then better
2189 to spill this one than anything else already assigned to registers */
2190 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2191 /* if this is local to this block then we might find a block spil */
2192 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2200 if (ic->op == RECEIVE)
2201 debugLog ("When I get clever, I'll optimize the receive logic\n");
2203 /* if we need ptr regs for the right side
2205 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2206 <= (unsigned) PTRSIZE)
2211 /* else we assign registers to it */
2212 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2214 debugLog (" %d - \n", __LINE__);
2216 bitVectDebugOn(_G.regAssigned, debugF);
2218 for (j = 0; j < sym->nRegs; j++)
2220 if (sym->regType == REG_PTR)
2221 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2223 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2225 /* if the allocation falied which means
2226 this was spilt then break */
2230 debugLog (" %d - \n", __LINE__);
2232 /* if it shares registers with operands make sure
2233 that they are in the same position */
2234 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2235 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2236 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2237 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2238 /* do the same for the right operand */
2239 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2240 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2241 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2242 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2244 debugLog (" %d - \n", __LINE__);
2247 debugLog (" %d - \n", __LINE__);
2256 /* Check for and fix any problems with uninitialized operands */
2257 for (i = 0; i < count; i++)
2261 if (ebbs[i]->noPath &&
2262 (ebbs[i]->entryLabel != entryLabel &&
2263 ebbs[i]->entryLabel != returnLabel))
2266 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2273 verifyRegsAssigned (IC_COND (ic), ic);
2277 if (ic->op == JUMPTABLE)
2279 verifyRegsAssigned (IC_JTCOND (ic), ic);
2283 verifyRegsAssigned (IC_RESULT (ic), ic);
2284 verifyRegsAssigned (IC_LEFT (ic), ic);
2285 verifyRegsAssigned (IC_RIGHT (ic), ic);
2291 /*-----------------------------------------------------------------*/
2292 /* rUmaskForOp :- returns register mask for an operand */
2293 /*-----------------------------------------------------------------*/
2295 rUmaskForOp (operand * op)
2301 debugLog ("%s\n", __FUNCTION__);
2302 /* only temporaries are assigned registers */
2306 sym = OP_SYMBOL (op);
2308 /* if spilt or no registers assigned to it
2310 if (sym->isspilt || !sym->nRegs)
2313 rumask = newBitVect (pic16_nRegs);
2315 for (j = 0; j < sym->nRegs; j++)
2317 rumask = bitVectSetBit (rumask,
2318 sym->regs[j]->rIdx);
2324 /*-----------------------------------------------------------------*/
2325 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2326 /*-----------------------------------------------------------------*/
2328 regsUsedIniCode (iCode * ic)
2330 bitVect *rmask = newBitVect (pic16_nRegs);
2332 debugLog ("%s\n", __FUNCTION__);
2333 /* do the special cases first */
2336 rmask = bitVectUnion (rmask,
2337 rUmaskForOp (IC_COND (ic)));
2341 /* for the jumptable */
2342 if (ic->op == JUMPTABLE)
2344 rmask = bitVectUnion (rmask,
2345 rUmaskForOp (IC_JTCOND (ic)));
2350 /* of all other cases */
2352 rmask = bitVectUnion (rmask,
2353 rUmaskForOp (IC_LEFT (ic)));
2357 rmask = bitVectUnion (rmask,
2358 rUmaskForOp (IC_RIGHT (ic)));
2361 rmask = bitVectUnion (rmask,
2362 rUmaskForOp (IC_RESULT (ic)));
2368 /*-----------------------------------------------------------------*/
2369 /* createRegMask - for each instruction will determine the regsUsed */
2370 /*-----------------------------------------------------------------*/
2372 createRegMask (eBBlock ** ebbs, int count)
2376 debugLog ("%s\n", __FUNCTION__);
2377 /* for all blocks */
2378 for (i = 0; i < count; i++)
2382 if (ebbs[i]->noPath &&
2383 (ebbs[i]->entryLabel != entryLabel &&
2384 ebbs[i]->entryLabel != returnLabel))
2387 /* for all instructions */
2388 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2393 if (SKIP_IC2 (ic) || !ic->rlive)
2396 /* first mark the registers used in this
2398 ic->rUsed = regsUsedIniCode (ic);
2399 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2401 /* now create the register mask for those
2402 registers that are in use : this is a
2403 super set of ic->rUsed */
2404 ic->rMask = newBitVect (pic16_nRegs + 1);
2406 /* for all live Ranges alive at this point */
2407 for (j = 1; j < ic->rlive->size; j++)
2412 /* if not alive then continue */
2413 if (!bitVectBitValue (ic->rlive, j))
2416 /* find the live range we are interested in */
2417 if (!(sym = hTabItemWithKey (liveRanges, j)))
2419 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2420 "createRegMask cannot find live range");
2424 /* if no register assigned to it */
2425 if (!sym->nRegs || sym->isspilt)
2428 /* for all the registers allocated to it */
2429 for (k = 0; k < sym->nRegs; k++)
2432 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2438 /*-----------------------------------------------------------------*/
2439 /* rematStr - returns the rematerialized string for a remat var */
2440 /*-----------------------------------------------------------------*/
2442 rematStr (symbol * sym)
2445 iCode *ic = sym->rematiCode;
2446 symbol *psym = NULL;
2448 debugLog ("%s\n", __FUNCTION__);
2450 //printf ("%s\n", s);
2452 /* if plus or minus print the right hand side */
2454 if (ic->op == '+' || ic->op == '-') {
2456 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2458 sprintf (s, "(%s %c 0x%04x)",
2459 OP_SYMBOL (IC_LEFT (ric))->rname,
2461 (int) operandLitValue (IC_RIGHT (ic)));
2464 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2466 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2467 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2472 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2473 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2475 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2480 /*-----------------------------------------------------------------*/
2481 /* rematStr - returns the rematerialized string for a remat var */
2482 /*-----------------------------------------------------------------*/
2484 rematStr (symbol * sym)
2487 iCode *ic = sym->rematiCode;
2489 debugLog ("%s\n", __FUNCTION__);
2494 /* if plus or minus print the right hand side */
2496 if (ic->op == '+' || ic->op == '-') {
2497 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2500 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2504 if (ic->op == '+' || ic->op == '-')
2506 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2507 sprintf (s, "(%s %c 0x%04x)",
2508 OP_SYMBOL (IC_LEFT (ric))->rname,
2510 (int) operandLitValue (IC_RIGHT (ic)));
2513 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2515 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2519 /* we reached the end */
2520 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2524 printf ("%s\n", buffer);
2529 /*-----------------------------------------------------------------*/
2530 /* regTypeNum - computes the type & number of registers required */
2531 /*-----------------------------------------------------------------*/
2539 debugLog ("%s\n", __FUNCTION__);
2540 /* for each live range do */
2541 for (sym = hTabFirstItem (liveRanges, &k); sym;
2542 sym = hTabNextItem (liveRanges, &k)) {
2544 debugLog (" %d - %s\n", __LINE__, sym->rname);
2545 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2547 /* if used zero times then no registers needed */
2548 if ((sym->liveTo - sym->liveFrom) == 0)
2552 /* if the live range is a temporary */
2555 debugLog (" %d - itemp register\n", __LINE__);
2557 /* if the type is marked as a conditional */
2558 if (sym->regType == REG_CND)
2561 /* if used in return only then we don't
2563 if (sym->ruonly || sym->accuse) {
2564 if (IS_AGGREGATE (sym->type) || sym->isptr)
2565 sym->type = aggrToPtr (sym->type, FALSE);
2566 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2571 /* if the symbol has only one definition &
2572 that definition is a get_pointer and the
2573 pointer we are getting is rematerializable and
2576 if (bitVectnBitsOn (sym->defs) == 1 &&
2577 (ic = hTabItemWithKey (iCodehTab,
2578 bitVectFirstBit (sym->defs))) &&
2580 !IS_BITVAR (sym->etype) &&
2581 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2583 if (ptrPseudoSymSafe (sym, ic)) {
2585 debugLog (" %d - \n", __LINE__);
2587 /* create a psuedo symbol & force a spil */
2588 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2589 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2590 psym->type = sym->type;
2591 psym->etype = sym->etype;
2592 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2593 strcpy (psym->rname, psym->name);
2595 sym->usl.spillLoc = psym;
2599 /* if in data space or idata space then try to
2600 allocate pointer register */
2604 /* if not then we require registers */
2605 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2606 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2607 getSize (sym->type));
2611 if(IS_PTR_CONST (sym->type)) {
2613 if(IS_CODEPTR (sym->type)) {
2615 // what IS this ???? (HJD)
2616 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2617 sym->nRegs = 3; // patch 14
2620 if (sym->nRegs > 4) {
2621 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2622 printTypeChain (sym->type, stderr);
2623 fprintf (stderr, "\n");
2626 /* determine the type of register required */
2627 if (sym->nRegs == 1 &&
2628 IS_PTR (sym->type) &&
2630 sym->regType = REG_PTR;
2632 sym->regType = REG_GPR;
2635 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2639 /* for the first run we don't provide */
2640 /* registers for true symbols we will */
2641 /* see how things go */
2646 static DEFSETFUNC (markRegFree)
2648 ((regs *)item)->isFree = 1;
2653 DEFSETFUNC (pic16_deallocReg)
2655 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2656 ((regs *)item)->isFree = 1;
2657 ((regs *)item)->wasUsed = 0;
2661 /*-----------------------------------------------------------------*/
2662 /* freeAllRegs - mark all registers as free */
2663 /*-----------------------------------------------------------------*/
2665 pic16_freeAllRegs ()
2667 debugLog ("%s\n", __FUNCTION__);
2669 applyToSet(pic16_dynAllocRegs,markRegFree);
2670 applyToSet(pic16_dynStackRegs,markRegFree);
2673 /*-----------------------------------------------------------------*/
2674 /*-----------------------------------------------------------------*/
2676 pic16_deallocateAllRegs ()
2678 debugLog ("%s\n", __FUNCTION__);
2680 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2684 /*-----------------------------------------------------------------*/
2685 /* deallocStackSpil - this will set the stack pointer back */
2686 /*-----------------------------------------------------------------*/
2688 DEFSETFUNC (deallocStackSpil)
2692 debugLog ("%s\n", __FUNCTION__);
2697 /*-----------------------------------------------------------------*/
2698 /* farSpacePackable - returns the packable icode for far variables */
2699 /*-----------------------------------------------------------------*/
2701 farSpacePackable (iCode * ic)
2705 debugLog ("%s\n", __FUNCTION__);
2706 /* go thru till we find a definition for the
2707 symbol on the right */
2708 for (dic = ic->prev; dic; dic = dic->prev)
2711 /* if the definition is a call then no */
2712 if ((dic->op == CALL || dic->op == PCALL) &&
2713 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2718 /* if shift by unknown amount then not */
2719 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2720 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2723 /* if pointer get and size > 1 */
2724 if (POINTER_GET (dic) &&
2725 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2728 if (POINTER_SET (dic) &&
2729 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2732 /* if any three is a true symbol in far space */
2733 if (IC_RESULT (dic) &&
2734 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2735 isOperandInFarSpace (IC_RESULT (dic)))
2738 if (IC_RIGHT (dic) &&
2739 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2740 isOperandInFarSpace (IC_RIGHT (dic)) &&
2741 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2744 if (IC_LEFT (dic) &&
2745 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2746 isOperandInFarSpace (IC_LEFT (dic)) &&
2747 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2750 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2752 if ((dic->op == LEFT_OP ||
2753 dic->op == RIGHT_OP ||
2755 IS_OP_LITERAL (IC_RIGHT (dic)))
2765 /*-----------------------------------------------------------------*/
2766 /* packRegsForAssign - register reduction for assignment */
2767 /*-----------------------------------------------------------------*/
2769 packRegsForAssign (iCode * ic, eBBlock * ebp)
2774 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2775 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2776 debugAopGet (" result:", IC_RESULT (ic));
2777 debugAopGet (" left:", IC_LEFT (ic));
2778 debugAopGet (" right:", IC_RIGHT (ic));
2780 /* if this is at an absolute address, then get the address. */
2781 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2782 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2783 debugLog (" %d - found config word declaration\n", __LINE__);
2784 if(IS_VALOP(IC_RIGHT(ic))) {
2785 debugLog (" setting config word to %x\n",
2786 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2787 fprintf(stderr, " setting config word to %x\n",
2788 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2789 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2790 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2794 debugLog(" %d\n", __LINE__);
2796 /* remove the assignment from the iCode chain. */
2798 remiCodeFromeBBlock (ebp, ic);
2799 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2800 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2806 debugLog(" %d - actuall processing\n", __LINE__ );
2808 if (!IS_ITEMP (IC_RESULT (ic))) {
2809 pic16_allocDirReg(IC_RESULT (ic));
2810 debugLog (" %d - result is not temp\n", __LINE__);
2814 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2815 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2816 pic16_allocDirReg(IC_LEFT (ic));
2820 /* See BUGLOG0001 - VR */
2822 if (!IS_ITEMP (IC_RIGHT (ic))) {
2823 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2824 pic16_allocDirReg(IC_RIGHT (ic));
2829 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2830 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2832 debugLog (" %d - not packing - right side fails \n", __LINE__);
2836 /* if the true symbol is defined in far space or on stack
2837 then we should not since this will increase register pressure */
2838 if (isOperandInFarSpace (IC_RESULT (ic)))
2840 if ((dic = farSpacePackable (ic)))
2847 /* find the definition of iTempNN scanning backwards if we find a
2848 a use of the true symbol before we find the definition then
2850 for (dic = ic->prev; dic; dic = dic->prev)
2853 /* if there is a function call and this is
2854 a parameter & not my parameter then don't pack it */
2855 if ((dic->op == CALL || dic->op == PCALL) &&
2856 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2857 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2859 debugLog (" %d - \n", __LINE__);
2868 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2871 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2872 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2873 debugAopGet(" result is ", IC_RESULT(dic));
2875 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2876 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2877 debugAopGet(" left is ", IC_LEFT(dic));
2879 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2880 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2881 debugAopGet(" right is ", IC_RIGHT(dic));
2885 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2886 IS_OP_VOLATILE (IC_RESULT (dic)))
2888 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2894 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2895 IS_OP_VOLATILE (IC_RIGHT(dic)))
2897 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2904 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2905 IS_OP_VOLATILE (IC_LEFT(dic)))
2907 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2915 if( IS_SYMOP( IC_RESULT(dic)) &&
2916 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2918 debugLog (" %d - result is bitfield\n", __LINE__);
2924 if (IS_SYMOP (IC_RESULT (dic)) &&
2925 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2927 /* A previous result was assigned to the same register - we'll our definition */
2928 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2929 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2930 if (POINTER_SET (dic))
2936 if (IS_SYMOP (IC_RIGHT (dic)) &&
2937 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2938 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2940 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2945 if (IS_SYMOP (IC_LEFT (dic)) &&
2946 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2947 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2949 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2954 if (POINTER_SET (dic) &&
2955 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2957 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2965 return 0; /* did not find */
2968 /* This code is taken from the hc08 port. Do not know
2969 * if it fits for pic16, but I leave it here just in case */
2971 /* if assignment then check that right is not a bit */
2972 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2973 sym_link *etype = operandType (IC_RIGHT (dic));
2975 if (IS_BITFIELD (etype)) {
2976 /* if result is a bit too then it's ok */
2977 etype = operandType (IC_RESULT (dic));
2978 if (!IS_BITFIELD (etype)) {
2979 debugLog(" %d bitfields\n");
2986 /* if the result is on stack or iaccess then it must be
2987 the same atleast one of the operands */
2988 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2989 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2993 /* clear the onStack flag, the port doesn't support it yet! FIXME */
2994 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2995 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2999 /* the operation has only one symbol
3000 operator then we can pack */
3001 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3002 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3005 if (!((IC_LEFT (dic) &&
3006 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3008 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3012 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3013 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3014 /* found the definition */
3015 /* replace the result with the result of */
3016 /* this assignment and remove this assignment */
3017 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3018 IC_RESULT (dic) = IC_RESULT (ic);
3020 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3022 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3024 /* delete from liverange table also
3025 delete from all the points inbetween and the new
3027 for (sic = dic; sic != ic; sic = sic->next)
3029 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3030 if (IS_ITEMP (IC_RESULT (dic)))
3031 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3034 remiCodeFromeBBlock (ebp, ic);
3035 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3037 debugLog(" %d\n", __LINE__ );
3038 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3039 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3047 #define NO_packRegsForAccUse
3048 #define NO_packRegsForSupport
3049 #define NO_packRegsForOneuse
3050 #define NO_cast_peep
3055 #ifndef NO_packRegsForSupport
3056 /*-----------------------------------------------------------------*/
3057 /* findAssignToSym : scanning backwards looks for first assig found */
3058 /*-----------------------------------------------------------------*/
3060 findAssignToSym (operand * op, iCode * ic)
3064 debugLog ("%s\n", __FUNCTION__);
3065 for (dic = ic->prev; dic; dic = dic->prev)
3068 /* if definition by assignment */
3069 if (dic->op == '=' &&
3070 !POINTER_SET (dic) &&
3071 IC_RESULT (dic)->key == op->key
3072 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3076 /* we are interested only if defined in far space */
3077 /* or in stack space in case of + & - */
3079 /* if assigned to a non-symbol then return
3081 if (!IS_SYMOP (IC_RIGHT (dic)))
3084 /* if the symbol is in far space then
3086 if (isOperandInFarSpace (IC_RIGHT (dic)))
3089 /* for + & - operations make sure that
3090 if it is on the stack it is the same
3091 as one of the three operands */
3092 if ((ic->op == '+' || ic->op == '-') &&
3093 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3097 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3098 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3101 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3102 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3103 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3111 /* if we find an usage then we cannot delete it */
3112 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3115 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3118 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3122 /* now make sure that the right side of dic
3123 is not defined between ic & dic */
3126 iCode *sic = dic->next;
3128 for (; sic != ic; sic = sic->next)
3129 if (IC_RESULT (sic) &&
3130 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3141 #ifndef NO_packRegsForSupport
3142 /*-----------------------------------------------------------------*/
3143 /* packRegsForSupport :- reduce some registers for support calls */
3144 /*-----------------------------------------------------------------*/
3146 packRegsForSupport (iCode * ic, eBBlock * ebp)
3150 debugLog ("%s\n", __FUNCTION__);
3151 /* for the left & right operand :- look to see if the
3152 left was assigned a true symbol in far space in that
3153 case replace them */
3154 if (IS_ITEMP (IC_LEFT (ic)) &&
3155 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3157 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3163 debugAopGet ("removing left:", IC_LEFT (ic));
3165 /* found it we need to remove it from the
3167 for (sic = dic; sic != ic; sic = sic->next)
3168 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3170 IC_LEFT (ic)->operand.symOperand =
3171 IC_RIGHT (dic)->operand.symOperand;
3172 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3173 remiCodeFromeBBlock (ebp, dic);
3174 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3175 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3179 /* do the same for the right operand */
3182 IS_ITEMP (IC_RIGHT (ic)) &&
3183 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3185 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3191 /* if this is a subtraction & the result
3192 is a true symbol in far space then don't pack */
3193 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3195 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3196 if (IN_FARSPACE (SPEC_OCLS (etype)))
3200 debugAopGet ("removing right:", IC_RIGHT (ic));
3202 /* found it we need to remove it from the
3204 for (sic = dic; sic != ic; sic = sic->next)
3205 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3207 IC_RIGHT (ic)->operand.symOperand =
3208 IC_RIGHT (dic)->operand.symOperand;
3209 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3211 remiCodeFromeBBlock (ebp, dic);
3212 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3213 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3222 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3224 #ifndef NO_packRegsForOneuse
3225 /*-----------------------------------------------------------------*/
3226 /* packRegsForOneuse : - will reduce some registers for single Use */
3227 /*-----------------------------------------------------------------*/
3229 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3234 debugLog ("%s\n", __FUNCTION__);
3235 /* if returning a literal then do nothing */
3239 /* only upto 2 bytes since we cannot predict
3240 the usage of b, & acc */
3241 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3246 /* this routine will mark the a symbol as used in one
3247 instruction use only && if the definition is local
3248 (ie. within the basic block) && has only one definition &&
3249 that definition is either a return value from a
3250 function or does not contain any variables in
3252 uses = bitVectCopy (OP_USES (op));
3253 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3254 if (!bitVectIsZero (uses)) /* has other uses */
3257 /* if it has only one defintion */
3258 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3259 return NULL; /* has more than one definition */
3261 /* get that definition */
3263 hTabItemWithKey (iCodehTab,
3264 bitVectFirstBit (OP_DEFS (op)))))
3267 /* found the definition now check if it is local */
3268 if (dic->seq < ebp->fSeq ||
3269 dic->seq > ebp->lSeq)
3270 return NULL; /* non-local */
3272 /* now check if it is the return from
3274 if (dic->op == CALL || dic->op == PCALL)
3276 if (ic->op != SEND && ic->op != RETURN &&
3277 !POINTER_SET(ic) && !POINTER_GET(ic))
3279 OP_SYMBOL (op)->ruonly = 1;
3286 /* otherwise check that the definition does
3287 not contain any symbols in far space */
3288 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3289 isOperandInFarSpace (IC_RIGHT (dic)) ||
3290 IS_OP_RUONLY (IC_LEFT (ic)) ||
3291 IS_OP_RUONLY (IC_RIGHT (ic)))
3296 /* if pointer set then make sure the pointer
3298 if (POINTER_SET (dic) &&
3299 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3302 if (POINTER_GET (dic) &&
3303 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3308 /* also make sure the intervenening instructions
3309 don't have any thing in far space */
3310 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3313 /* if there is an intervening function call then no */
3314 if (dic->op == CALL || dic->op == PCALL)
3316 /* if pointer set then make sure the pointer
3318 if (POINTER_SET (dic) &&
3319 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3322 if (POINTER_GET (dic) &&
3323 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3326 /* if address of & the result is remat then okay */
3327 if (dic->op == ADDRESS_OF &&
3328 OP_SYMBOL (IC_RESULT (dic))->remat)
3331 /* if operand has size of three or more & this
3332 operation is a '*','/' or '%' then 'b' may
3334 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3335 getSize (operandType (op)) >= 3)
3338 /* if left or right or result is in far space */
3339 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3340 isOperandInFarSpace (IC_RIGHT (dic)) ||
3341 isOperandInFarSpace (IC_RESULT (dic)) ||
3342 IS_OP_RUONLY (IC_LEFT (dic)) ||
3343 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3344 IS_OP_RUONLY (IC_RESULT (dic)))
3350 OP_SYMBOL (op)->ruonly = 1;
3357 /*-----------------------------------------------------------------*/
3358 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3359 /*-----------------------------------------------------------------*/
3361 isBitwiseOptimizable (iCode * ic)
3363 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3364 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3366 debugLog ("%s\n", __FUNCTION__);
3367 /* bitwise operations are considered optimizable
3368 under the following conditions (Jean-Louis VERN)
3380 if (IS_LITERAL (rtype) ||
3381 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3388 #ifndef NO_packRegsForAccUse
3390 /*-----------------------------------------------------------------*/
3391 /* packRegsForAccUse - pack registers for acc use */
3392 /*-----------------------------------------------------------------*/
3394 packRegsForAccUse (iCode * ic)
3398 debugLog ("%s\n", __FUNCTION__);
3400 /* if this is an aggregate, e.g. a one byte char array */
3401 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3404 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3406 /* if + or - then it has to be one byte result */
3407 if ((ic->op == '+' || ic->op == '-')
3408 && getSize (operandType (IC_RESULT (ic))) > 1)
3411 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3412 /* if shift operation make sure right side is not a literal */
3413 if (ic->op == RIGHT_OP &&
3414 (isOperandLiteral (IC_RIGHT (ic)) ||
3415 getSize (operandType (IC_RESULT (ic))) > 1))
3418 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3419 if (ic->op == LEFT_OP &&
3420 (isOperandLiteral (IC_RIGHT (ic)) ||
3421 getSize (operandType (IC_RESULT (ic))) > 1))
3424 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3425 if (IS_BITWISE_OP (ic) &&
3426 getSize (operandType (IC_RESULT (ic))) > 1)
3430 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3431 /* has only one definition */
3432 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3435 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3436 /* has only one use */
3437 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3440 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3441 /* and the usage immediately follows this iCode */
3442 if (!(uic = hTabItemWithKey (iCodehTab,
3443 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3446 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3447 if (ic->next != uic)
3450 /* if it is a conditional branch then we definitely can */
3454 if (uic->op == JUMPTABLE)
3457 /* if the usage is not is an assignment
3458 or an arithmetic / bitwise / shift operation then not */
3459 if (POINTER_SET (uic) &&
3460 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3463 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3464 if (uic->op != '=' &&
3465 !IS_ARITHMETIC_OP (uic) &&
3466 !IS_BITWISE_OP (uic) &&
3467 uic->op != LEFT_OP &&
3468 uic->op != RIGHT_OP)
3471 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3472 /* if used in ^ operation then make sure right is not a
3474 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3477 /* if shift operation make sure right side is not a literal */
3478 if (uic->op == RIGHT_OP &&
3479 (isOperandLiteral (IC_RIGHT (uic)) ||
3480 getSize (operandType (IC_RESULT (uic))) > 1))
3483 if (uic->op == LEFT_OP &&
3484 (isOperandLiteral (IC_RIGHT (uic)) ||
3485 getSize (operandType (IC_RESULT (uic))) > 1))
3488 /* make sure that the result of this icode is not on the
3489 stack, since acc is used to compute stack offset */
3490 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3491 OP_SYMBOL (IC_RESULT (uic))->onStack)
3494 /* if either one of them in far space then we cannot */
3495 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3496 isOperandInFarSpace (IC_LEFT (uic))) ||
3497 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3498 isOperandInFarSpace (IC_RIGHT (uic))))
3501 /* if the usage has only one operand then we can */
3502 if (IC_LEFT (uic) == NULL ||
3503 IC_RIGHT (uic) == NULL)
3506 /* make sure this is on the left side if not
3507 a '+' since '+' is commutative */
3508 if (ic->op != '+' &&
3509 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3513 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3514 /* if one of them is a literal then we can */
3515 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3516 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3517 (getSize (operandType (IC_RESULT (uic))) <= 1))
3519 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3524 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3525 /* if the other one is not on stack then we can */
3526 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3527 (IS_ITEMP (IC_RIGHT (uic)) ||
3528 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3529 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3532 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3533 (IS_ITEMP (IC_LEFT (uic)) ||
3534 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3535 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3541 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3542 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3549 /*-----------------------------------------------------------------*/
3550 /* packForPush - hueristics to reduce iCode for pushing */
3551 /*-----------------------------------------------------------------*/
3553 packForReceive (iCode * ic, eBBlock * ebp)
3557 debugLog ("%s\n", __FUNCTION__);
3558 debugAopGet (" result:", IC_RESULT (ic));
3559 debugAopGet (" left:", IC_LEFT (ic));
3560 debugAopGet (" right:", IC_RIGHT (ic));
3565 for (dic = ic->next; dic; dic = dic->next)
3570 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3571 debugLog (" used on left\n");
3572 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3573 debugLog (" used on right\n");
3574 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3575 debugLog (" used on result\n");
3577 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3578 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3583 debugLog (" hey we can remove this unnecessary assign\n");
3585 /*-----------------------------------------------------------------*/
3586 /* packForPush - hueristics to reduce iCode for pushing */
3587 /*-----------------------------------------------------------------*/
3589 packForPush (iCode * ic, eBBlock * ebp)
3593 debugLog ("%s\n", __FUNCTION__);
3594 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3597 /* must have only definition & one usage */
3598 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3599 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3602 /* find the definition */
3603 if (!(dic = hTabItemWithKey (iCodehTab,
3604 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3607 if (dic->op != '=' || POINTER_SET (dic))
3610 /* we now we know that it has one & only one def & use
3611 and the that the definition is an assignment */
3612 IC_LEFT (ic) = IC_RIGHT (dic);
3614 remiCodeFromeBBlock (ebp, dic);
3615 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3616 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3619 static void printSymType(char * str, sym_link *sl)
3621 if(!pic16_ralloc_debug)return;
3623 debugLog (" %s Symbol type: ",str);
3624 printTypeChain( sl, debugF);
3628 /*-----------------------------------------------------------------*/
3629 /* some debug code to print the symbol S_TYPE. Note that
3630 * the function checkSClass in src/SDCCsymt.c dinks with
3631 * the S_TYPE in ways the PIC port doesn't fully like...*/
3632 /*-----------------------------------------------------------------*/
3633 static void isData(sym_link *sl)
3637 if(!pic16_ralloc_debug)return;
3644 for ( ; sl; sl=sl->next) {
3646 switch (SPEC_SCLS(sl)) {
3647 case S_DATA: fprintf (of, "data "); break;
3648 case S_XDATA: fprintf (of, "xdata "); break;
3649 case S_SFR: fprintf (of, "sfr "); break;
3650 case S_SBIT: fprintf (of, "sbit "); break;
3651 case S_CODE: fprintf (of, "code "); break;
3652 case S_IDATA: fprintf (of, "idata "); break;
3653 case S_PDATA: fprintf (of, "pdata "); break;
3654 case S_LITERAL: fprintf (of, "literal "); break;
3655 case S_STACK: fprintf (of, "stack "); break;
3656 case S_XSTACK: fprintf (of, "xstack "); break;
3657 case S_BIT: fprintf (of, "bit "); break;
3658 case S_EEPROM: fprintf (of, "eeprom "); break;
3667 /*--------------------------------------------------------------------*/
3668 /* pic16_packRegisters - does some transformations to reduce */
3669 /* register pressure */
3671 /*--------------------------------------------------------------------*/
3673 pic16_packRegisters (eBBlock * ebp)
3678 debugLog ("%s\n", __FUNCTION__);
3684 /* look for assignments of the form */
3685 /* iTempNN = TRueSym (someoperation) SomeOperand */
3687 /* TrueSym := iTempNN:1 */
3688 for (ic = ebp->sch; ic; ic = ic->next)
3690 // debugLog("%d\n", __LINE__);
3691 /* find assignment of the form TrueSym := iTempNN:1 */
3692 /* see BUGLOG0001 for workaround with the CAST - VR */
3693 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3694 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3695 change += packRegsForAssign (ic, ebp);
3699 if (POINTER_SET (ic))
3700 debugLog ("pointer is set\n");
3701 debugAopGet (" result:", IC_RESULT (ic));
3702 debugAopGet (" left:", IC_LEFT (ic));
3703 debugAopGet (" right:", IC_RIGHT (ic));
3712 for (ic = ebp->sch; ic; ic = ic->next) {
3714 if(IS_SYMOP ( IC_LEFT(ic))) {
3715 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3717 debugAopGet ("x left:", IC_LEFT (ic));
3719 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3721 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3723 debugLog (" is a pointer\n");
3725 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3726 debugLog (" is a ptr\n");
3728 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3729 debugLog (" is volatile\n");
3733 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3734 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3735 pic16_allocDirReg(IC_LEFT (ic));
3738 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3741 if(IS_SYMOP ( IC_RIGHT(ic))) {
3742 debugAopGet (" right:", IC_RIGHT (ic));
3743 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3746 if(IS_SYMOP ( IC_RESULT(ic))) {
3747 debugAopGet (" result:", IC_RESULT (ic));
3748 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3751 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3752 debugAopGet (" right:", IC_RIGHT (ic));
3753 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3754 // pic16_allocDirReg(IC_RIGHT(ic));
3757 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3758 debugAopGet (" result:", IC_RESULT (ic));
3759 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3760 // pic16_allocDirReg(IC_RESULT(ic));
3764 if (POINTER_SET (ic))
3765 debugLog (" %d - Pointer set\n", __LINE__);
3768 /* if this is an itemp & result of a address of a true sym
3769 then mark this as rematerialisable */
3770 if (ic->op == ADDRESS_OF &&
3771 IS_ITEMP (IC_RESULT (ic)) &&
3772 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3773 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3774 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3777 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3779 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3780 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3781 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3785 /* if straight assignment then carry remat flag if
3786 this is the only definition */
3787 if (ic->op == '=' &&
3788 !POINTER_SET (ic) &&
3789 IS_SYMOP (IC_RIGHT (ic)) &&
3790 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3791 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3793 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3795 OP_SYMBOL (IC_RESULT (ic))->remat =
3796 OP_SYMBOL (IC_RIGHT (ic))->remat;
3797 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3798 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3801 /* if this is a +/- operation with a rematerizable
3802 then mark this as rematerializable as well */
3803 if ((ic->op == '+' || ic->op == '-') &&
3804 (IS_SYMOP (IC_LEFT (ic)) &&
3805 IS_ITEMP (IC_RESULT (ic)) &&
3806 OP_SYMBOL (IC_LEFT (ic))->remat &&
3807 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3808 IS_OP_LITERAL (IC_RIGHT (ic))))
3810 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3812 operandLitValue (IC_RIGHT (ic));
3813 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3814 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3815 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3818 /* mark the pointer usages */
3819 if (POINTER_SET (ic))
3821 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3822 debugLog (" marking as a pointer (set) =>");
3823 debugAopGet (" result:", IC_RESULT (ic));
3825 if (POINTER_GET (ic))
3827 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3828 debugLog (" marking as a pointer (get) =>");
3829 debugAopGet (" left:", IC_LEFT (ic));
3832 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3836 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3837 /* if we are using a symbol on the stack
3838 then we should say pic16_ptrRegReq */
3839 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3840 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3841 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3842 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3843 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3844 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3848 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3849 if (IS_SYMOP (IC_LEFT (ic)))
3850 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3851 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3852 if (IS_SYMOP (IC_RIGHT (ic)))
3853 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3854 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3855 if (IS_SYMOP (IC_RESULT (ic)))
3856 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3857 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3860 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3864 /* if the condition of an if instruction
3865 is defined in the previous instruction then
3866 mark the itemp as a conditional */
3867 if ((IS_CONDITIONAL (ic) ||
3868 ((ic->op == BITWISEAND ||
3871 isBitwiseOptimizable (ic))) &&
3872 ic->next && ic->next->op == IFX &&
3873 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3874 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3877 debugLog (" %d\n", __LINE__);
3878 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3882 debugLog(" %d\n", __LINE__);
3884 #ifndef NO_packRegsForSupport
3885 /* reduce for support function calls */
3886 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3887 packRegsForSupport (ic, ebp);
3890 /* if a parameter is passed, it's in W, so we may not
3891 need to place a copy in a register */
3892 if (ic->op == RECEIVE)
3893 packForReceive (ic, ebp);
3895 #ifndef NO_packRegsForOneuse
3896 /* some cases the redundant moves can
3897 can be eliminated for return statements */
3898 if ((ic->op == RETURN || ic->op == SEND) &&
3899 !isOperandInFarSpace (IC_LEFT (ic)) &&
3901 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3904 #ifndef NO_packRegsForOneuse
3905 /* if pointer set & left has a size more than
3906 one and right is not in far space */
3907 if (POINTER_SET (ic) &&
3908 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3909 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3910 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3911 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3913 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3916 #ifndef NO_packRegsForOneuse
3917 /* if pointer get */
3918 if (POINTER_GET (ic) &&
3919 !isOperandInFarSpace (IC_RESULT (ic)) &&
3920 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3921 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3922 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3924 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3925 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3928 #ifndef NO_cast_peep
3929 /* if this is cast for intergral promotion then
3930 check if only use of the definition of the
3931 operand being casted/ if yes then replace
3932 the result of that arithmetic operation with
3933 this result and get rid of the cast */
3934 if (ic->op == CAST) {
3936 sym_link *fromType = operandType (IC_RIGHT (ic));
3937 sym_link *toType = operandType (IC_LEFT (ic));
3939 debugLog (" %d - casting\n", __LINE__);
3941 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3942 getSize (fromType) != getSize (toType)) {
3945 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3948 if (IS_ARITHMETIC_OP (dic)) {
3949 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3951 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3952 IC_RESULT (dic) = IC_RESULT (ic);
3953 remiCodeFromeBBlock (ebp, ic);
3954 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3955 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3956 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3960 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3964 /* if the type from and type to are the same
3965 then if this is the only use then packit */
3966 if (compareType (operandType (IC_RIGHT (ic)),
3967 operandType (IC_LEFT (ic))) == 1) {
3969 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3972 debugLog(" %d\n", __LINE__);
3974 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3975 IC_RESULT (dic) = IC_RESULT (ic);
3976 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3977 remiCodeFromeBBlock (ebp, ic);
3978 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3979 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3987 iTempNN := (some variable in farspace) V1
3992 if (ic->op == IPUSH)
3994 packForPush (ic, ebp);
3998 #ifndef NO_packRegsForAccUse
3999 /* pack registers for accumulator use, when the
4000 result of an arithmetic or bit wise operation
4001 has only one use, that use is immediately following
4002 the defintion and the using iCode has only one
4003 operand or has two operands but one is literal &
4004 the result of that operation is not on stack then
4005 we can leave the result of this operation in acc:b
4007 if ((IS_ARITHMETIC_OP (ic)
4009 || IS_BITWISE_OP (ic)
4011 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4014 IS_ITEMP (IC_RESULT (ic)) &&
4015 getSize (operandType (IC_RESULT (ic))) <= 1)
4017 packRegsForAccUse (ic);
4024 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4028 if (!pic16_ralloc_debug || !debugF)
4031 for (i = 0; i < count; i++)
4033 fprintf (debugF, "\n----------------------------------------------------------------\n");
4034 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4035 ebbs[i]->entryLabel->name,
4038 ebbs[i]->isLastInLoop);
4039 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4044 fprintf (debugF, "visited %d : hasFcall = %d\n",
4048 fprintf (debugF, "\ndefines bitVector :");
4049 bitVectDebugOn (ebbs[i]->defSet, debugF);
4050 fprintf (debugF, "\nlocal defines bitVector :");
4051 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4052 fprintf (debugF, "\npointers Set bitvector :");
4053 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4054 fprintf (debugF, "\nin pointers Set bitvector :");
4055 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4056 fprintf (debugF, "\ninDefs Set bitvector :");
4057 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4058 fprintf (debugF, "\noutDefs Set bitvector :");
4059 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4060 fprintf (debugF, "\nusesDefs Set bitvector :");
4061 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4062 fprintf (debugF, "\n----------------------------------------------------------------\n");
4063 printiCChain (ebbs[i]->sch, debugF);
4066 /*-----------------------------------------------------------------*/
4067 /* pic16_assignRegisters - assigns registers to each live range as need */
4068 /*-----------------------------------------------------------------*/
4070 pic16_assignRegisters (eBBlock ** ebbs, int count)
4075 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4076 debugLog ("\nebbs before optimizing:\n");
4077 dumpEbbsToDebug (ebbs, count);
4079 setToNull ((void *) &_G.funcrUsed);
4080 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4083 /* change assignments this will remove some
4084 live ranges reducing some register pressure */
4085 for (i = 0; i < count; i++)
4086 pic16_packRegisters (ebbs[i]);
4093 debugLog("dir registers allocated so far:\n");
4094 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4097 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4098 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4099 reg = hTabNextItem(dynDirectRegNames, &hkey);
4104 /* liveranges probably changed by register packing
4105 so we compute them again */
4106 recomputeLiveRanges (ebbs, count);
4108 if (options.dump_pack)
4109 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4111 /* first determine for each live range the number of
4112 registers & the type of registers required for each */
4115 /* and serially allocate registers */
4116 serialRegAssign (ebbs, count);
4118 // debugLog ("ebbs after serialRegAssign:\n");
4119 // dumpEbbsToDebug (ebbs, count);
4122 //pic16_freeAllRegs();
4124 /* if stack was extended then tell the user */
4127 /* werror(W_TOOMANY_SPILS,"stack", */
4128 /* _G.stackExtend,currFunc->name,""); */
4134 /* werror(W_TOOMANY_SPILS,"data space", */
4135 /* _G.dataExtend,currFunc->name,""); */
4139 /* after that create the register mask
4140 for each of the instruction */
4141 createRegMask (ebbs, count);
4143 /* redo that offsets for stacked automatic variables */
4144 redoStackOffsets ();
4146 if (options.dump_rassgn)
4147 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4149 /* now get back the chain */
4150 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4152 debugLog ("ebbs after optimizing:\n");
4153 dumpEbbsToDebug (ebbs, count);
4158 /* free up any _G.stackSpil locations allocated */
4159 applyToSet (_G.stackSpil, deallocStackSpil);
4161 setToNull ((void *) &_G.stackSpil);
4162 setToNull ((void *) &_G.spiltSet);
4163 /* mark all registers as free */
4164 pic16_freeAllRegs ();
4166 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");