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);
366 if(type == REG_SFR) {
368 dReg->address = rIdx;
369 dReg->accessBank = 1;
373 dReg->accessBank = 0;
376 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
380 dReg->reg_alias = NULL;
381 dReg->reglives.usedpFlows = newSet();
382 dReg->reglives.assignedpFlows = newSet();
385 if(!(type == REG_SFR && alias == 0x80))
386 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
391 /*-----------------------------------------------------------------*/
392 /* regWithIdx - Search through a set of registers that matches idx */
393 /*-----------------------------------------------------------------*/
395 regWithIdx (set *dRegs, int idx, int fixed)
399 for (dReg = setFirstItem(dRegs) ; dReg ;
400 dReg = setNextItem(dRegs)) {
402 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
410 /*-----------------------------------------------------------------*/
411 /* regFindFree - Search for a free register in a set of registers */
412 /*-----------------------------------------------------------------*/
414 regFindFree (set *dRegs)
418 for (dReg = setFirstItem(dRegs) ; dReg ;
419 dReg = setNextItem(dRegs)) {
421 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
422 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
431 /*-----------------------------------------------------------------*/
432 /* pic16_initStack - allocate registers for a pseudo stack */
433 /*-----------------------------------------------------------------*/
434 void pic16_initStack(int base_address, int size)
439 pic16_Gstack_base_addr = base_address;
440 //fprintf(stderr,"initStack");
442 for(i = 0; i<size; i++)
443 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
446 /*-----------------------------------------------------------------*
447 *-----------------------------------------------------------------*/
449 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
451 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
453 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
455 reg->wasUsed = 0; // we do not know if they are going to be used at all
456 reg->accessBank = 1; // implicit add access Bank
458 return addSet(&pic16_dynProcessorRegs, reg);
461 /*-----------------------------------------------------------------*
462 *-----------------------------------------------------------------*/
465 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
467 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
469 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
473 return addSet(&pic16_dynInternalRegs,reg);
478 /*-----------------------------------------------------------------*/
479 /* allocReg - allocates register of given type */
480 /*-----------------------------------------------------------------*/
482 allocReg (short type)
487 if(dynrIdx > pic16_nRegs)
491 /* try to reuse some unused registers */
492 reg = regFindFree( pic16_dynAllocRegs );
495 // fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
499 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
500 // addSet(&pic16_dynAllocRegs, reg);
503 addSet(&pic16_dynAllocRegs, reg);
507 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
509 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
510 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
513 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
514 reg->isLocal = 1; /* this is a local frame register */
518 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
519 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
522 return (reg); // addSet(&pic16_dynAllocRegs,reg);
527 /*-----------------------------------------------------------------*/
528 /* pic16_dirregWithName - search for register by name */
529 /*-----------------------------------------------------------------*/
531 pic16_dirregWithName (char *name)
539 /* hash the name to get a key */
541 hkey = regname2key(name);
543 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
545 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
549 if(STRCASECMP(reg->name, name) == 0) {
553 reg = hTabNextItemWK (dynDirectRegNames);
557 return NULL; // name wasn't found in the hash table
560 int PIC16_IS_CONFIG_ADDRESS(int address)
563 return address >= 0x300000 && address <= 0x300000d;
566 /*-----------------------------------------------------------------*/
567 /* pic16_allocDirReg - allocates register of given type */
568 /*-----------------------------------------------------------------*/
570 pic16_allocDirReg (operand *op )
576 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
577 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
581 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
583 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { // patch 13
584 if(pic16_debug_verbose) //
586 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, //
587 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname); //
592 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
593 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
596 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
597 debugLog(" %d const char\n",__LINE__);
598 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
599 // fprintf(stderr, " %d const char\n",__LINE__);
600 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
604 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
605 if (IS_CODE ( OP_SYM_ETYPE(op)) )
606 debugLog(" %d code space\n",__LINE__);
608 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
609 debugLog(" %d integral\n",__LINE__);
611 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
612 debugLog(" %d literal\n",__LINE__);
614 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
615 debugLog(" %d specifier\n",__LINE__);
617 debugAopGet(NULL, op);
620 if (IS_CODE ( OP_SYM_ETYPE(op)) )
623 /* First, search the hash table to see if there is a register with this name */
624 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
626 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
630 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
631 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
633 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
634 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
637 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
639 reg = pic16_dirregWithName(name);
644 int regtype = REG_GPR;
646 /* if this is at an absolute address, then get the address. */
647 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
648 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
649 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
652 /* Register wasn't found in hash, so let's create
653 * a new one and put it in the hash table AND in the
654 * dynDirectRegNames set */
655 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
656 if(pic16_debug_verbose)
657 fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
658 OP_SYMBOL(op)->name);
659 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
663 if(!PIC16_IS_CONFIG_ADDRESS(address)) {
664 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
666 /* this is an error, why added? -- VR */
667 // if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
669 if(OP_SYMBOL(op)->onStack) {
670 // fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
671 OP_SYMBOL(op)->onStack = 0;
672 SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
676 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13
677 if(pic16_debug_verbose) //
679 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d\n",
680 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
681 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
682 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
683 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
684 IN_STACK( OP_SYM_ETYPE(op)));
686 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
687 OP_SYMBOL(op)->name); //
692 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
693 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
695 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
697 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
698 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
699 // reg->type = REG_SFR;
702 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
703 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
704 addSet(&pic16_dynDirectBitRegs, reg);
707 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
708 // addSet(&pic16_dynDirectRegs, reg);
709 checkAddReg(&pic16_dynDirectRegs, reg);
713 debugLog (" -- %s is declared at address 0x30000x\n",name);
714 // fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
720 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
722 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
724 /* work around for user defined registers in access bank */
725 if((reg->address>= 0x00 && reg->address < 0x80)
726 || (reg->address >= 0xf80 && reg->address <= 0xfff))
729 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
735 /*-----------------------------------------------------------------*/
736 /* pic16_allocRegByName - allocates register of given type */
737 /*-----------------------------------------------------------------*/
739 pic16_allocRegByName (char *name, int size)
745 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
749 /* First, search the hash table to see if there is a register with this name */
750 reg = pic16_dirregWithName(name);
754 /* Register wasn't found in hash, so let's create
755 * a new one and put it in the hash table AND in the
756 * dynDirectRegNames set */
757 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
758 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
760 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
761 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
763 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
764 addSet(&pic16_dynDirectRegs, reg);
770 /*-----------------------------------------------------------------*/
771 /* RegWithIdx - returns pointer to register with index number */
772 /*-----------------------------------------------------------------*/
773 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
778 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
779 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
784 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
786 debugLog ("Found a Dynamic Register!\n");
789 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
790 debugLog ("Found a Direct Register!\n");
796 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
797 debugLog ("Found a Stack Register!\n");
802 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
803 debugLog ("Found a Processor Register!\n");
817 /*-----------------------------------------------------------------*/
818 /* pic16_regWithIdx - returns pointer to register with index number*/
819 /*-----------------------------------------------------------------*/
821 pic16_regWithIdx (int idx)
825 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
828 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
831 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
837 /*-----------------------------------------------------------------*/
838 /* pic16_regWithIdx - returns pointer to register with index number */
839 /*-----------------------------------------------------------------*/
841 pic16_allocWithIdx (int idx)
846 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
847 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
849 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
851 debugLog ("Found a Dynamic Register!\n");
852 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
853 debugLog ("Found a Stack Register!\n");
854 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
855 debugLog ("Found a Processor Register!\n");
856 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
857 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
858 debugLog ("Found an Internal Register!\n");
861 debugLog ("Dynamic Register not found\n");
864 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
865 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
866 "regWithIdx not found");
876 /*-----------------------------------------------------------------*/
877 /*-----------------------------------------------------------------*/
879 pic16_findFreeReg(short type)
886 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
888 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
892 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
904 /*-----------------------------------------------------------------*/
905 /* freeReg - frees a register */
906 /*-----------------------------------------------------------------*/
910 debugLog ("%s\n", __FUNCTION__);
911 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
916 /*-----------------------------------------------------------------*/
917 /* nFreeRegs - returns number of free registers */
918 /*-----------------------------------------------------------------*/
926 /* although I fixed the register allocation/freeing scheme
927 * the for loop below doesn't give valid results. I do not
928 * know why yet. -- VR 10-Jan-2003 */
933 /* dynamically allocate as many as we need and worry about
934 * fitting them into a PIC later */
936 debugLog ("%s\n", __FUNCTION__);
938 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
939 if((reg->type == type) && reg->isFree)nfr++;
941 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
945 /*-----------------------------------------------------------------*/
946 /* nfreeRegsType - free registers with type */
947 /*-----------------------------------------------------------------*/
949 nfreeRegsType (int type)
952 debugLog ("%s\n", __FUNCTION__);
955 if ((nfr = nFreeRegs (type)) == 0)
956 return nFreeRegs (REG_GPR);
959 return nFreeRegs (type);
962 static void writeSetUsedRegs(FILE *of, set *dRegs)
967 for (dReg = setFirstItem(dRegs) ; dReg ;
968 dReg = setNextItem(dRegs)) {
971 fprintf (of, "\t%s\n",dReg->name);
977 extern void pic16_groupRegistersInSection(set *regset);
979 extern void pic16_dump_equates(FILE *of, set *equs);
980 //extern void pic16_dump_map(void);
981 extern void pic16_dump_section(FILE *of, set *section, int fix);
982 extern void pic16_dump_int_registers(FILE *of, set *section);
983 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
985 static void packBits(set *bregs)
990 regs *relocbitfield=NULL;
996 for (regset = bregs ; regset ;
997 regset = regset->next) {
1000 breg->isBitField = 1;
1001 //fprintf(stderr,"bit reg: %s\n",breg->name);
1004 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1006 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1007 breg->rIdx = breg->address & 7;
1008 breg->address >>= 3;
1011 sprintf (buffer, "fbitfield%02x", breg->address);
1012 //fprintf(stderr,"new bit field\n");
1013 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1014 bitfield->isBitField = 1;
1015 bitfield->isFixed = 1;
1016 bitfield->address = breg->address;
1017 addSet(&pic16_dynDirectRegs,bitfield);
1018 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1020 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1023 breg->reg_alias = bitfield;
1027 if(!relocbitfield || bit_no >7) {
1030 sprintf (buffer, "bitfield%d", byte_no);
1031 //fprintf(stderr,"new relocatable bit field\n");
1032 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1033 relocbitfield->isBitField = 1;
1034 addSet(&pic16_dynDirectRegs,relocbitfield);
1035 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1039 breg->reg_alias = relocbitfield;
1040 breg->address = rDirectIdx; /* byte_no; */
1041 breg->rIdx = bit_no++;
1050 static void bitEQUs(FILE *of, set *bregs)
1052 regs *breg,*bytereg;
1055 //fprintf(stderr," %s\n",__FUNCTION__);
1056 for (breg = setFirstItem(bregs) ; breg ;
1057 breg = setNextItem(bregs)) {
1059 //fprintf(stderr,"bit reg: %s\n",breg->name);
1061 bytereg = breg->reg_alias;
1063 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1066 breg->rIdx & 0x0007);
1069 fprintf(stderr, "bit field is not assigned to a register\n");
1070 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1081 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1086 for (reg = setFirstItem(fregs) ; reg ;
1087 reg = setNextItem(fregs)) {
1089 if(!reg->isEmitted && reg->wasUsed) {
1091 if (reg->type != REG_SFR) {
1092 fprintf (of, "%s\tEQU\t0x%03x\n",
1098 fprintf (of, "%s\tEQU\t0x%03x\n",
1107 void pic16_writeUsedRegs(FILE *of)
1109 packBits(pic16_dynDirectBitRegs);
1111 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1112 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1113 pic16_groupRegistersInSection(pic16_dynStackRegs);
1114 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1115 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1116 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1120 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1121 pic16_assignFixedRegisters(pic16_dynStackRegs);
1122 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1123 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1125 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1126 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1127 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1128 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1129 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1132 // pic16_dump_map();
1133 // pic16_dump_cblock(of);
1136 pic16_dump_equates(of, pic16_equ_data);
1138 /* dump initialised data */
1139 pic16_dump_idata(of, idataSymSet);
1141 /* dump internal registers */
1142 pic16_dump_int_registers(of, pic16_int_regs);
1144 /* dump other variables */
1145 pic16_dump_section(of, pic16_rel_udata, 0);
1146 pic16_dump_section(of, pic16_fix_udata, 1);
1151 /*-----------------------------------------------------------------*/
1152 /* allDefsOutOfRange - all definitions are out of a range */
1153 /*-----------------------------------------------------------------*/
1155 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1159 debugLog ("%s\n", __FUNCTION__);
1163 for (i = 0; i < defs->size; i++)
1167 if (bitVectBitValue (defs, i) &&
1168 (ic = hTabItemWithKey (iCodehTab, i)) &&
1169 (ic->seq >= fseq && ic->seq <= toseq))
1179 /*-----------------------------------------------------------------*/
1180 /* computeSpillable - given a point find the spillable live ranges */
1181 /*-----------------------------------------------------------------*/
1183 computeSpillable (iCode * ic)
1187 debugLog ("%s\n", __FUNCTION__);
1188 /* spillable live ranges are those that are live at this
1189 point . the following categories need to be subtracted
1191 a) - those that are already spilt
1192 b) - if being used by this one
1193 c) - defined by this one */
1195 spillable = bitVectCopy (ic->rlive);
1197 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1199 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1200 bitVectUnSetBit (spillable, ic->defKey);
1201 spillable = bitVectIntersect (spillable, _G.regAssigned);
1206 /*-----------------------------------------------------------------*/
1207 /* noSpilLoc - return true if a variable has no spil location */
1208 /*-----------------------------------------------------------------*/
1210 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1212 debugLog ("%s\n", __FUNCTION__);
1213 return (sym->usl.spillLoc ? 0 : 1);
1216 /*-----------------------------------------------------------------*/
1217 /* hasSpilLoc - will return 1 if the symbol has spil location */
1218 /*-----------------------------------------------------------------*/
1220 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1222 debugLog ("%s\n", __FUNCTION__);
1223 return (sym->usl.spillLoc ? 1 : 0);
1226 /*-----------------------------------------------------------------*/
1227 /* directSpilLoc - will return 1 if the splilocation is in direct */
1228 /*-----------------------------------------------------------------*/
1230 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1232 debugLog ("%s\n", __FUNCTION__);
1233 if (sym->usl.spillLoc &&
1234 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1240 /*-----------------------------------------------------------------*/
1241 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1242 /* but is not used as a pointer */
1243 /*-----------------------------------------------------------------*/
1245 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1247 debugLog ("%s\n", __FUNCTION__);
1248 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1251 /*-----------------------------------------------------------------*/
1252 /* rematable - will return 1 if the remat flag is set */
1253 /*-----------------------------------------------------------------*/
1255 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1257 debugLog ("%s\n", __FUNCTION__);
1261 /*-----------------------------------------------------------------*/
1262 /* notUsedInRemaining - not used or defined in remain of the block */
1263 /*-----------------------------------------------------------------*/
1265 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1267 debugLog ("%s\n", __FUNCTION__);
1268 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1269 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1272 /*-----------------------------------------------------------------*/
1273 /* allLRs - return true for all */
1274 /*-----------------------------------------------------------------*/
1276 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1278 debugLog ("%s\n", __FUNCTION__);
1282 /*-----------------------------------------------------------------*/
1283 /* liveRangesWith - applies function to a given set of live range */
1284 /*-----------------------------------------------------------------*/
1286 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1287 eBBlock * ebp, iCode * ic)
1292 debugLog ("%s\n", __FUNCTION__);
1293 if (!lrs || !lrs->size)
1296 for (i = 1; i < lrs->size; i++)
1299 if (!bitVectBitValue (lrs, i))
1302 /* if we don't find it in the live range
1303 hash table we are in serious trouble */
1304 if (!(sym = hTabItemWithKey (liveRanges, i)))
1306 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1307 "liveRangesWith could not find liveRange");
1311 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1312 addSetHead (&rset, sym);
1319 /*-----------------------------------------------------------------*/
1320 /* leastUsedLR - given a set determines which is the least used */
1321 /*-----------------------------------------------------------------*/
1323 leastUsedLR (set * sset)
1325 symbol *sym = NULL, *lsym = NULL;
1327 debugLog ("%s\n", __FUNCTION__);
1328 sym = lsym = setFirstItem (sset);
1333 for (; lsym; lsym = setNextItem (sset))
1336 /* if usage is the same then prefer
1337 the spill the smaller of the two */
1338 if (lsym->used == sym->used)
1339 if (getSize (lsym->type) < getSize (sym->type))
1343 if (lsym->used < sym->used)
1348 setToNull ((void *) &sset);
1353 /*-----------------------------------------------------------------*/
1354 /* noOverLap - will iterate through the list looking for over lap */
1355 /*-----------------------------------------------------------------*/
1357 noOverLap (set * itmpStack, symbol * fsym)
1360 debugLog ("%s\n", __FUNCTION__);
1363 for (sym = setFirstItem (itmpStack); sym;
1364 sym = setNextItem (itmpStack))
1366 if (sym->liveTo > fsym->liveFrom)
1374 /*-----------------------------------------------------------------*/
1375 /* isFree - will return 1 if the a free spil location is found */
1376 /*-----------------------------------------------------------------*/
1381 V_ARG (symbol **, sloc);
1382 V_ARG (symbol *, fsym);
1384 debugLog ("%s\n", __FUNCTION__);
1385 /* if already found */
1389 /* if it is free && and the itmp assigned to
1390 this does not have any overlapping live ranges
1391 with the one currently being assigned and
1392 the size can be accomodated */
1394 noOverLap (sym->usl.itmpStack, fsym) &&
1395 getSize (sym->type) >= getSize (fsym->type))
1404 /*-----------------------------------------------------------------*/
1405 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1406 /*-----------------------------------------------------------------*/
1408 spillLRWithPtrReg (symbol * forSym)
1414 debugLog ("%s\n", __FUNCTION__);
1415 if (!_G.regAssigned ||
1416 bitVectIsZero (_G.regAssigned))
1419 r0 = pic16_regWithIdx (R0_IDX);
1420 r1 = pic16_regWithIdx (R1_IDX);
1422 /* for all live ranges */
1423 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1424 lrsym = hTabNextItem (liveRanges, &k))
1428 /* if no registers assigned to it or
1430 /* if it does not overlap with this then
1431 not need to spill it */
1433 if (lrsym->isspilt || !lrsym->nRegs ||
1434 (lrsym->liveTo < forSym->liveFrom))
1437 /* go thru the registers : if it is either
1438 r0 or r1 then spil it */
1439 for (j = 0; j < lrsym->nRegs; j++)
1440 if (lrsym->regs[j] == r0 ||
1441 lrsym->regs[j] == r1)
1450 /*-----------------------------------------------------------------*/
1451 /* createStackSpil - create a location on the stack to spil */
1452 /*-----------------------------------------------------------------*/
1454 createStackSpil (symbol * sym)
1456 symbol *sloc = NULL;
1457 int useXstack, model, noOverlay;
1459 char slocBuffer[30];
1460 debugLog ("%s\n", __FUNCTION__);
1462 /* first go try and find a free one that is already
1463 existing on the stack */
1464 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1466 /* found a free one : just update & return */
1467 sym->usl.spillLoc = sloc;
1470 addSetHead (&sloc->usl.itmpStack, sym);
1474 /* could not then have to create one , this is the hard part
1475 we need to allocate this on the stack : this is really a
1476 hack!! but cannot think of anything better at this time */
1478 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1480 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1481 __FILE__, __LINE__);
1485 sloc = newiTemp (slocBuffer);
1487 /* set the type to the spilling symbol */
1488 sloc->type = copyLinkChain (sym->type);
1489 sloc->etype = getSpec (sloc->type);
1490 SPEC_SCLS (sloc->etype) = S_DATA;
1491 SPEC_EXTR (sloc->etype) = 0;
1492 SPEC_STAT (sloc->etype) = 0;
1494 /* we don't allow it to be allocated`
1495 onto the external stack since : so we
1496 temporarily turn it off ; we also
1497 turn off memory model to prevent
1498 the spil from going to the external storage
1499 and turn off overlaying
1502 useXstack = options.useXstack;
1503 model = options.model;
1504 noOverlay = options.noOverlay;
1505 options.noOverlay = 1;
1506 options.model = options.useXstack = 0;
1510 options.useXstack = useXstack;
1511 options.model = model;
1512 options.noOverlay = noOverlay;
1513 sloc->isref = 1; /* to prevent compiler warning */
1515 /* if it is on the stack then update the stack */
1516 if (IN_STACK (sloc->etype))
1518 currFunc->stack += getSize (sloc->type);
1519 _G.stackExtend += getSize (sloc->type);
1522 _G.dataExtend += getSize (sloc->type);
1524 /* add it to the _G.stackSpil set */
1525 addSetHead (&_G.stackSpil, sloc);
1526 sym->usl.spillLoc = sloc;
1529 /* add it to the set of itempStack set
1530 of the spill location */
1531 addSetHead (&sloc->usl.itmpStack, sym);
1535 /*-----------------------------------------------------------------*/
1536 /* isSpiltOnStack - returns true if the spil location is on stack */
1537 /*-----------------------------------------------------------------*/
1539 isSpiltOnStack (symbol * sym)
1543 debugLog ("%s\n", __FUNCTION__);
1550 /* if (sym->_G.stackSpil) */
1553 if (!sym->usl.spillLoc)
1556 etype = getSpec (sym->usl.spillLoc->type);
1557 if (IN_STACK (etype))
1563 /*-----------------------------------------------------------------*/
1564 /* spillThis - spils a specific operand */
1565 /*-----------------------------------------------------------------*/
1567 spillThis (symbol * sym)
1570 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1572 /* if this is rematerializable or has a spillLocation
1573 we are okay, else we need to create a spillLocation
1575 if (!(sym->remat || sym->usl.spillLoc))
1576 createStackSpil (sym);
1579 /* mark it has spilt & put it in the spilt set */
1581 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1583 bitVectUnSetBit (_G.regAssigned, sym->key);
1585 for (i = 0; i < sym->nRegs; i++)
1589 freeReg (sym->regs[i]);
1590 sym->regs[i] = NULL;
1593 /* if spilt on stack then free up r0 & r1
1594 if they could have been assigned to some
1596 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1599 spillLRWithPtrReg (sym);
1602 if (sym->usl.spillLoc && !sym->remat)
1603 sym->usl.spillLoc->allocreq = 1;
1607 /*-----------------------------------------------------------------*/
1608 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1609 /*-----------------------------------------------------------------*/
1611 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1613 bitVect *lrcs = NULL;
1617 debugLog ("%s\n", __FUNCTION__);
1618 /* get the spillable live ranges */
1619 lrcs = computeSpillable (ic);
1621 /* get all live ranges that are rematerizable */
1622 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1625 /* return the least used of these */
1626 return leastUsedLR (selectS);
1629 /* get live ranges with spillLocations in direct space */
1630 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1632 sym = leastUsedLR (selectS);
1633 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1634 sym->usl.spillLoc->rname :
1635 sym->usl.spillLoc->name));
1637 /* mark it as allocation required */
1638 sym->usl.spillLoc->allocreq = 1;
1642 /* if the symbol is local to the block then */
1643 if (forSym->liveTo < ebp->lSeq)
1646 /* check if there are any live ranges allocated
1647 to registers that are not used in this block */
1648 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1650 sym = leastUsedLR (selectS);
1651 /* if this is not rematerializable */
1660 /* check if there are any live ranges that not
1661 used in the remainder of the block */
1662 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1664 sym = leastUsedLR (selectS);
1667 sym->remainSpil = 1;
1674 /* find live ranges with spillocation && not used as pointers */
1675 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1678 sym = leastUsedLR (selectS);
1679 /* mark this as allocation required */
1680 sym->usl.spillLoc->allocreq = 1;
1684 /* find live ranges with spillocation */
1685 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1688 sym = leastUsedLR (selectS);
1689 sym->usl.spillLoc->allocreq = 1;
1693 /* couldn't find then we need to create a spil
1694 location on the stack , for which one? the least
1696 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1699 /* return a created spil location */
1700 sym = createStackSpil (leastUsedLR (selectS));
1701 sym->usl.spillLoc->allocreq = 1;
1705 /* this is an extreme situation we will spill
1706 this one : happens very rarely but it does happen */
1712 /*-----------------------------------------------------------------*/
1713 /* spilSomething - spil some variable & mark registers as free */
1714 /*-----------------------------------------------------------------*/
1716 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1721 debugLog ("%s\n", __FUNCTION__);
1722 /* get something we can spil */
1723 ssym = selectSpil (ic, ebp, forSym);
1725 /* mark it as spilt */
1727 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1729 /* mark it as not register assigned &
1730 take it away from the set */
1731 bitVectUnSetBit (_G.regAssigned, ssym->key);
1733 /* mark the registers as free */
1734 for (i = 0; i < ssym->nRegs; i++)
1736 freeReg (ssym->regs[i]);
1738 /* if spilt on stack then free up r0 & r1
1739 if they could have been assigned to as gprs */
1740 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1743 spillLRWithPtrReg (ssym);
1746 /* if this was a block level spil then insert push & pop
1747 at the start & end of block respectively */
1748 if (ssym->blockSpil)
1750 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1751 /* add push to the start of the block */
1752 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1753 ebp->sch->next : ebp->sch));
1754 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1755 /* add pop to the end of the block */
1756 addiCodeToeBBlock (ebp, nic, NULL);
1759 /* if spilt because not used in the remainder of the
1760 block then add a push before this instruction and
1761 a pop at the end of the block */
1762 if (ssym->remainSpil)
1765 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1766 /* add push just before this instruction */
1767 addiCodeToeBBlock (ebp, nic, ic);
1769 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1770 /* add pop to the end of the block */
1771 addiCodeToeBBlock (ebp, nic, NULL);
1780 /*-----------------------------------------------------------------*/
1781 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1782 /*-----------------------------------------------------------------*/
1784 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1789 debugLog ("%s\n", __FUNCTION__);
1791 /* try for a ptr type */
1792 if ((reg = allocReg (REG_PTR)))
1795 /* try for gpr type */
1796 if ((reg = allocReg (REG_GPR)))
1799 /* we have to spil */
1800 if (!spilSomething (ic, ebp, sym))
1803 /* make sure partially assigned registers aren't reused */
1804 for (j=0; j<=sym->nRegs; j++)
1806 sym->regs[j]->isFree = 0;
1808 /* this looks like an infinite loop but
1809 in really selectSpil will abort */
1813 /*-----------------------------------------------------------------*/
1814 /* getRegGpr - will try for GPR if not spil */
1815 /*-----------------------------------------------------------------*/
1817 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1822 debugLog ("%s\n", __FUNCTION__);
1824 /* try for gpr type */
1825 if ((reg = allocReg (REG_GPR)))
1828 if (!pic16_ptrRegReq)
1829 if ((reg = allocReg (REG_PTR)))
1832 /* we have to spil */
1833 if (!spilSomething (ic, ebp, sym))
1836 /* make sure partially assigned registers aren't reused */
1837 for (j=0; j<=sym->nRegs; j++)
1839 sym->regs[j]->isFree = 0;
1841 /* this looks like an infinite loop but
1842 in really selectSpil will abort */
1846 /*-----------------------------------------------------------------*/
1847 /* symHasReg - symbol has a given register */
1848 /*-----------------------------------------------------------------*/
1850 symHasReg (symbol * sym, regs * reg)
1854 debugLog ("%s\n", __FUNCTION__);
1855 for (i = 0; i < sym->nRegs; i++)
1856 if (sym->regs[i] == reg)
1862 /*-----------------------------------------------------------------*/
1863 /* deassignLRs - check the live to and if they have registers & are */
1864 /* not spilt then free up the registers */
1865 /*-----------------------------------------------------------------*/
1867 deassignLRs (iCode * ic, eBBlock * ebp)
1873 debugLog ("%s\n", __FUNCTION__);
1874 for (sym = hTabFirstItem (liveRanges, &k); sym;
1875 sym = hTabNextItem (liveRanges, &k))
1878 symbol *psym = NULL;
1879 /* if it does not end here */
1880 if (sym->liveTo > ic->seq)
1883 /* if it was spilt on stack then we can
1884 mark the stack spil location as free */
1889 sym->usl.spillLoc->isFree = 1;
1895 if (!bitVectBitValue (_G.regAssigned, sym->key))
1898 /* special case check if this is an IFX &
1899 the privious one was a pop and the
1900 previous one was not spilt then keep track
1902 if (ic->op == IFX && ic->prev &&
1903 ic->prev->op == IPOP &&
1904 !ic->prev->parmPush &&
1905 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1906 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1912 bitVectUnSetBit (_G.regAssigned, sym->key);
1914 /* if the result of this one needs registers
1915 and does not have it then assign it right
1917 if (IC_RESULT (ic) &&
1918 !(SKIP_IC2 (ic) || /* not a special icode */
1919 ic->op == JUMPTABLE ||
1924 POINTER_SET (ic)) &&
1925 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1926 result->liveTo > ic->seq && /* and will live beyond this */
1927 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1928 result->regType == sym->regType && /* same register types */
1929 result->nRegs && /* which needs registers */
1930 !result->isspilt && /* and does not already have them */
1932 !bitVectBitValue (_G.regAssigned, result->key) &&
1933 /* the number of free regs + number of regs in this LR
1934 can accomodate the what result Needs */
1935 ((nfreeRegsType (result->regType) +
1936 sym->nRegs) >= result->nRegs)
1940 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1942 result->regs[i] = sym->regs[i];
1944 result->regs[i] = getRegGpr (ic, ebp, result);
1946 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1950 /* free the remaining */
1951 for (; i < sym->nRegs; i++)
1955 if (!symHasReg (psym, sym->regs[i]))
1956 freeReg (sym->regs[i]);
1959 freeReg (sym->regs[i]);
1966 /*-----------------------------------------------------------------*/
1967 /* reassignLR - reassign this to registers */
1968 /*-----------------------------------------------------------------*/
1970 reassignLR (operand * op)
1972 symbol *sym = OP_SYMBOL (op);
1975 debugLog ("%s\n", __FUNCTION__);
1976 /* not spilt any more */
1977 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1978 bitVectUnSetBit (_G.spiltSet, sym->key);
1980 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1984 for (i = 0; i < sym->nRegs; i++)
1985 sym->regs[i]->isFree = 0;
1988 /*-----------------------------------------------------------------*/
1989 /* willCauseSpill - determines if allocating will cause a spill */
1990 /*-----------------------------------------------------------------*/
1992 willCauseSpill (int nr, int rt)
1994 debugLog ("%s\n", __FUNCTION__);
1995 /* first check if there are any avlb registers
1996 of te type required */
1999 /* special case for pointer type
2000 if pointer type not avlb then
2001 check for type gpr */
2002 if (nFreeRegs (rt) >= nr)
2004 if (nFreeRegs (REG_GPR) >= nr)
2009 if (pic16_ptrRegReq)
2011 if (nFreeRegs (rt) >= nr)
2016 if (nFreeRegs (REG_PTR) +
2017 nFreeRegs (REG_GPR) >= nr)
2022 debugLog (" ... yep it will (cause a spill)\n");
2023 /* it will cause a spil */
2027 /*-----------------------------------------------------------------*/
2028 /* positionRegs - the allocator can allocate same registers to res- */
2029 /* ult and operand, if this happens make sure they are in the same */
2030 /* position as the operand otherwise chaos results */
2031 /*-----------------------------------------------------------------*/
2033 positionRegs (symbol * result, symbol * opsym, int lineno)
2035 int count = min (result->nRegs, opsym->nRegs);
2036 int i, j = 0, shared = 0;
2038 debugLog ("%s\n", __FUNCTION__);
2039 /* if the result has been spilt then cannot share */
2044 /* first make sure that they actually share */
2045 for (i = 0; i < count; i++)
2047 for (j = 0; j < count; j++)
2049 if (result->regs[i] == opsym->regs[j] && i != j)
2059 regs *tmp = result->regs[i];
2060 result->regs[i] = result->regs[j];
2061 result->regs[j] = tmp;
2066 /*------------------------------------------------------------------*/
2067 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2068 /* it should either have registers or have beed spilled. Otherwise, */
2069 /* there was an uninitialized variable, so just spill this to get */
2070 /* the operand in a valid state. */
2071 /*------------------------------------------------------------------*/
2073 verifyRegsAssigned (operand *op, iCode * ic)
2078 if (!IS_ITEMP (op)) return;
2080 sym = OP_SYMBOL (op);
2081 if (sym->isspilt) return;
2082 if (!sym->nRegs) return;
2083 if (sym->regs[0]) return;
2085 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2086 sym->prereqv ? sym->prereqv->name : sym->name);
2091 /*-----------------------------------------------------------------*/
2092 /* serialRegAssign - serially allocate registers to the variables */
2093 /*-----------------------------------------------------------------*/
2095 serialRegAssign (eBBlock ** ebbs, int count)
2099 debugLog ("%s\n", __FUNCTION__);
2100 /* for all blocks */
2101 for (i = 0; i < count; i++)
2106 if (ebbs[i]->noPath &&
2107 (ebbs[i]->entryLabel != entryLabel &&
2108 ebbs[i]->entryLabel != returnLabel))
2111 /* of all instructions do */
2112 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2115 debugLog (" op: %s\n", decodeOp (ic->op));
2117 /* if this is an ipop that means some live
2118 range will have to be assigned again */
2120 reassignLR (IC_LEFT (ic));
2122 /* if result is present && is a true symbol */
2123 if (IC_RESULT (ic) && ic->op != IFX &&
2124 IS_TRUE_SYMOP (IC_RESULT (ic)))
2125 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2127 /* take away registers from live
2128 ranges that end at this instruction */
2129 deassignLRs (ic, ebbs[i]);
2131 /* some don't need registers */
2132 if (SKIP_IC2 (ic) ||
2133 ic->op == JUMPTABLE ||
2137 (IC_RESULT (ic) && POINTER_SET (ic)))
2140 /* now we need to allocate registers
2141 only for the result */
2144 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2150 /* if it does not need or is spilt
2151 or is already assigned to registers
2152 or will not live beyond this instructions */
2155 bitVectBitValue (_G.regAssigned, sym->key) ||
2156 sym->liveTo <= ic->seq)
2159 /* if some liverange has been spilt at the block level
2160 and this one live beyond this block then spil this
2162 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2167 /* if trying to allocate this will cause
2168 a spill and there is nothing to spill
2169 or this one is rematerializable then
2171 willCS = willCauseSpill (sym->nRegs, sym->regType);
2172 spillable = computeSpillable (ic);
2174 (willCS && bitVectIsZero (spillable)))
2182 /* if it has a spillocation & is used less than
2183 all other live ranges then spill this */
2185 if (sym->usl.spillLoc) {
2186 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2187 allLRs, ebbs[i], ic));
2188 if (leastUsed && leastUsed->used > sym->used) {
2193 /* if none of the liveRanges have a spillLocation then better
2194 to spill this one than anything else already assigned to registers */
2195 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2196 /* if this is local to this block then we might find a block spil */
2197 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2205 if (ic->op == RECEIVE)
2206 debugLog ("When I get clever, I'll optimize the receive logic\n");
2208 /* if we need ptr regs for the right side
2210 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2211 <= (unsigned) PTRSIZE)
2216 /* else we assign registers to it */
2217 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2219 debugLog (" %d - \n", __LINE__);
2221 bitVectDebugOn(_G.regAssigned, debugF);
2223 for (j = 0; j < sym->nRegs; j++)
2225 if (sym->regType == REG_PTR)
2226 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2228 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2230 /* if the allocation falied which means
2231 this was spilt then break */
2235 debugLog (" %d - \n", __LINE__);
2237 /* if it shares registers with operands make sure
2238 that they are in the same position */
2239 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2240 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2241 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2242 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2243 /* do the same for the right operand */
2244 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2245 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2246 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2247 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2249 debugLog (" %d - \n", __LINE__);
2252 debugLog (" %d - \n", __LINE__);
2261 /* Check for and fix any problems with uninitialized operands */
2262 for (i = 0; i < count; i++)
2266 if (ebbs[i]->noPath &&
2267 (ebbs[i]->entryLabel != entryLabel &&
2268 ebbs[i]->entryLabel != returnLabel))
2271 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2278 verifyRegsAssigned (IC_COND (ic), ic);
2282 if (ic->op == JUMPTABLE)
2284 verifyRegsAssigned (IC_JTCOND (ic), ic);
2288 verifyRegsAssigned (IC_RESULT (ic), ic);
2289 verifyRegsAssigned (IC_LEFT (ic), ic);
2290 verifyRegsAssigned (IC_RIGHT (ic), ic);
2296 /*-----------------------------------------------------------------*/
2297 /* rUmaskForOp :- returns register mask for an operand */
2298 /*-----------------------------------------------------------------*/
2300 rUmaskForOp (operand * op)
2306 debugLog ("%s\n", __FUNCTION__);
2307 /* only temporaries are assigned registers */
2311 sym = OP_SYMBOL (op);
2313 /* if spilt or no registers assigned to it
2315 if (sym->isspilt || !sym->nRegs)
2318 rumask = newBitVect (pic16_nRegs);
2320 for (j = 0; j < sym->nRegs; j++)
2322 rumask = bitVectSetBit (rumask,
2323 sym->regs[j]->rIdx);
2329 /*-----------------------------------------------------------------*/
2330 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2331 /*-----------------------------------------------------------------*/
2333 regsUsedIniCode (iCode * ic)
2335 bitVect *rmask = newBitVect (pic16_nRegs);
2337 debugLog ("%s\n", __FUNCTION__);
2338 /* do the special cases first */
2341 rmask = bitVectUnion (rmask,
2342 rUmaskForOp (IC_COND (ic)));
2346 /* for the jumptable */
2347 if (ic->op == JUMPTABLE)
2349 rmask = bitVectUnion (rmask,
2350 rUmaskForOp (IC_JTCOND (ic)));
2355 /* of all other cases */
2357 rmask = bitVectUnion (rmask,
2358 rUmaskForOp (IC_LEFT (ic)));
2362 rmask = bitVectUnion (rmask,
2363 rUmaskForOp (IC_RIGHT (ic)));
2366 rmask = bitVectUnion (rmask,
2367 rUmaskForOp (IC_RESULT (ic)));
2373 /*-----------------------------------------------------------------*/
2374 /* createRegMask - for each instruction will determine the regsUsed */
2375 /*-----------------------------------------------------------------*/
2377 createRegMask (eBBlock ** ebbs, int count)
2381 debugLog ("%s\n", __FUNCTION__);
2382 /* for all blocks */
2383 for (i = 0; i < count; i++)
2387 if (ebbs[i]->noPath &&
2388 (ebbs[i]->entryLabel != entryLabel &&
2389 ebbs[i]->entryLabel != returnLabel))
2392 /* for all instructions */
2393 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2398 if (SKIP_IC2 (ic) || !ic->rlive)
2401 /* first mark the registers used in this
2403 ic->rUsed = regsUsedIniCode (ic);
2404 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2406 /* now create the register mask for those
2407 registers that are in use : this is a
2408 super set of ic->rUsed */
2409 ic->rMask = newBitVect (pic16_nRegs + 1);
2411 /* for all live Ranges alive at this point */
2412 for (j = 1; j < ic->rlive->size; j++)
2417 /* if not alive then continue */
2418 if (!bitVectBitValue (ic->rlive, j))
2421 /* find the live range we are interested in */
2422 if (!(sym = hTabItemWithKey (liveRanges, j)))
2424 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2425 "createRegMask cannot find live range");
2429 /* if no register assigned to it */
2430 if (!sym->nRegs || sym->isspilt)
2433 /* for all the registers allocated to it */
2434 for (k = 0; k < sym->nRegs; k++)
2437 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2443 /*-----------------------------------------------------------------*/
2444 /* rematStr - returns the rematerialized string for a remat var */
2445 /*-----------------------------------------------------------------*/
2447 rematStr (symbol * sym)
2450 iCode *ic = sym->rematiCode;
2451 symbol *psym = NULL;
2453 debugLog ("%s\n", __FUNCTION__);
2455 //printf ("%s\n", s);
2457 /* if plus or minus print the right hand side */
2459 if (ic->op == '+' || ic->op == '-') {
2461 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2463 sprintf (s, "(%s %c 0x%04x)",
2464 OP_SYMBOL (IC_LEFT (ric))->rname,
2466 (int) operandLitValue (IC_RIGHT (ic)));
2469 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2471 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2472 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2477 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2478 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2480 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2485 /*-----------------------------------------------------------------*/
2486 /* rematStr - returns the rematerialized string for a remat var */
2487 /*-----------------------------------------------------------------*/
2489 rematStr (symbol * sym)
2492 iCode *ic = sym->rematiCode;
2494 debugLog ("%s\n", __FUNCTION__);
2499 /* if plus or minus print the right hand side */
2501 if (ic->op == '+' || ic->op == '-') {
2502 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2505 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2509 if (ic->op == '+' || ic->op == '-')
2511 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2512 sprintf (s, "(%s %c 0x%04x)",
2513 OP_SYMBOL (IC_LEFT (ric))->rname,
2515 (int) operandLitValue (IC_RIGHT (ic)));
2518 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2520 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2524 /* we reached the end */
2525 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2529 printf ("%s\n", buffer);
2534 /*-----------------------------------------------------------------*/
2535 /* regTypeNum - computes the type & number of registers required */
2536 /*-----------------------------------------------------------------*/
2544 debugLog ("%s\n", __FUNCTION__);
2545 /* for each live range do */
2546 for (sym = hTabFirstItem (liveRanges, &k); sym;
2547 sym = hTabNextItem (liveRanges, &k)) {
2549 debugLog (" %d - %s\n", __LINE__, sym->rname);
2550 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2552 /* if used zero times then no registers needed */
2553 if ((sym->liveTo - sym->liveFrom) == 0)
2557 /* if the live range is a temporary */
2560 debugLog (" %d - itemp register\n", __LINE__);
2562 /* if the type is marked as a conditional */
2563 if (sym->regType == REG_CND)
2566 /* if used in return only then we don't
2568 if (sym->ruonly || sym->accuse) {
2569 if (IS_AGGREGATE (sym->type) || sym->isptr)
2570 sym->type = aggrToPtr (sym->type, FALSE);
2571 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2576 /* if the symbol has only one definition &
2577 that definition is a get_pointer and the
2578 pointer we are getting is rematerializable and
2581 if (bitVectnBitsOn (sym->defs) == 1 &&
2582 (ic = hTabItemWithKey (iCodehTab,
2583 bitVectFirstBit (sym->defs))) &&
2585 !IS_BITVAR (sym->etype) &&
2586 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2588 if (ptrPseudoSymSafe (sym, ic)) {
2592 debugLog (" %d - \n", __LINE__);
2594 /* create a psuedo symbol & force a spil */
2595 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2596 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2597 psym->type = sym->type;
2598 psym->etype = sym->etype;
2599 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2600 strcpy (psym->rname, psym->name);
2602 sym->usl.spillLoc = psym;
2606 /* if in data space or idata space then try to
2607 allocate pointer register */
2611 /* if not then we require registers */
2612 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2613 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2614 getSize (sym->type));
2618 if(IS_PTR_CONST (sym->type)) {
2620 if(IS_CODEPTR (sym->type)) {
2622 // what IS this ???? (HJD)
2623 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2624 sym->nRegs = 3; // patch 14
2627 if (sym->nRegs > 4) {
2628 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2629 printTypeChain (sym->type, stderr);
2630 fprintf (stderr, "\n");
2633 /* determine the type of register required */
2634 if (sym->nRegs == 1 &&
2635 IS_PTR (sym->type) &&
2637 sym->regType = REG_PTR;
2639 sym->regType = REG_GPR;
2642 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2646 /* for the first run we don't provide */
2647 /* registers for true symbols we will */
2648 /* see how things go */
2653 static DEFSETFUNC (markRegFree)
2655 ((regs *)item)->isFree = 1;
2660 DEFSETFUNC (pic16_deallocReg)
2662 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2663 ((regs *)item)->isFree = 1;
2664 ((regs *)item)->wasUsed = 0;
2668 /*-----------------------------------------------------------------*/
2669 /* freeAllRegs - mark all registers as free */
2670 /*-----------------------------------------------------------------*/
2672 pic16_freeAllRegs ()
2674 debugLog ("%s\n", __FUNCTION__);
2676 applyToSet(pic16_dynAllocRegs,markRegFree);
2677 applyToSet(pic16_dynStackRegs,markRegFree);
2680 /*-----------------------------------------------------------------*/
2681 /*-----------------------------------------------------------------*/
2683 pic16_deallocateAllRegs ()
2685 debugLog ("%s\n", __FUNCTION__);
2687 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2691 /*-----------------------------------------------------------------*/
2692 /* deallocStackSpil - this will set the stack pointer back */
2693 /*-----------------------------------------------------------------*/
2695 DEFSETFUNC (deallocStackSpil)
2699 debugLog ("%s\n", __FUNCTION__);
2704 /*-----------------------------------------------------------------*/
2705 /* farSpacePackable - returns the packable icode for far variables */
2706 /*-----------------------------------------------------------------*/
2708 farSpacePackable (iCode * ic)
2712 debugLog ("%s\n", __FUNCTION__);
2713 /* go thru till we find a definition for the
2714 symbol on the right */
2715 for (dic = ic->prev; dic; dic = dic->prev)
2718 /* if the definition is a call then no */
2719 if ((dic->op == CALL || dic->op == PCALL) &&
2720 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2725 /* if shift by unknown amount then not */
2726 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2727 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2730 /* if pointer get and size > 1 */
2731 if (POINTER_GET (dic) &&
2732 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2735 if (POINTER_SET (dic) &&
2736 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2739 /* if any three is a true symbol in far space */
2740 if (IC_RESULT (dic) &&
2741 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2742 isOperandInFarSpace (IC_RESULT (dic)))
2745 if (IC_RIGHT (dic) &&
2746 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2747 isOperandInFarSpace (IC_RIGHT (dic)) &&
2748 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2751 if (IC_LEFT (dic) &&
2752 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2753 isOperandInFarSpace (IC_LEFT (dic)) &&
2754 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2757 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2759 if ((dic->op == LEFT_OP ||
2760 dic->op == RIGHT_OP ||
2762 IS_OP_LITERAL (IC_RIGHT (dic)))
2772 /*-----------------------------------------------------------------*/
2773 /* packRegsForAssign - register reduction for assignment */
2774 /*-----------------------------------------------------------------*/
2776 packRegsForAssign (iCode * ic, eBBlock * ebp)
2781 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2782 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2783 debugAopGet (" result:", IC_RESULT (ic));
2784 debugAopGet (" left:", IC_LEFT (ic));
2785 debugAopGet (" right:", IC_RIGHT (ic));
2787 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2789 /* if this is at an absolute address, then get the address. */
2790 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2791 if(PIC16_IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2792 debugLog (" %d - found config word declaration\n", __LINE__);
2793 if(IS_VALOP(IC_RIGHT(ic))) {
2794 debugLog (" setting config word to %x\n",
2795 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2796 // fprintf(stderr, " setting config word to %x\n",
2797 // (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2798 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2799 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2803 debugLog(" %d\n", __LINE__);
2805 /* remove the assignment from the iCode chain. */
2807 remiCodeFromeBBlock (ebp, ic);
2808 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2809 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2815 debugLog(" %d - actuall processing\n", __LINE__ );
2817 if (!IS_ITEMP (IC_RESULT (ic))) {
2818 pic16_allocDirReg(IC_RESULT (ic));
2819 debugLog (" %d - result is not temp\n", __LINE__);
2823 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2824 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2825 pic16_allocDirReg(IC_LEFT (ic));
2829 /* See BUGLOG0001 - VR */
2831 if (!IS_ITEMP (IC_RIGHT (ic))) {
2832 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2833 pic16_allocDirReg(IC_RIGHT (ic));
2838 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2839 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2841 debugLog (" %d - not packing - right side fails \n", __LINE__);
2845 /* if the true symbol is defined in far space or on stack
2846 then we should not since this will increase register pressure */
2847 if (isOperandInFarSpace (IC_RESULT (ic)))
2849 if ((dic = farSpacePackable (ic)))
2856 /* find the definition of iTempNN scanning backwards if we find a
2857 a use of the true symbol before we find the definition then
2859 for (dic = ic->prev; dic; dic = dic->prev)
2862 /* if there is a function call and this is
2863 a parameter & not my parameter then don't pack it */
2864 if ((dic->op == CALL || dic->op == PCALL) &&
2865 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2866 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2868 debugLog (" %d - \n", __LINE__);
2877 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2880 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2881 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2882 debugAopGet(" result is ", IC_RESULT(dic));
2884 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2885 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2886 debugAopGet(" left is ", IC_LEFT(dic));
2888 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2889 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2890 debugAopGet(" right is ", IC_RIGHT(dic));
2894 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2895 IS_OP_VOLATILE (IC_RESULT (dic)))
2897 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2903 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2904 IS_OP_VOLATILE (IC_RIGHT(dic)))
2906 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2913 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2914 IS_OP_VOLATILE (IC_LEFT(dic)))
2916 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2924 if( IS_SYMOP( IC_RESULT(dic)) &&
2925 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2927 debugLog (" %d - result is bitfield\n", __LINE__);
2933 if (IS_SYMOP (IC_RESULT (dic)) &&
2934 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2936 /* A previous result was assigned to the same register - we'll our definition */
2937 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2938 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2939 if (POINTER_SET (dic))
2945 if (IS_SYMOP (IC_RIGHT (dic)) &&
2946 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2947 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2949 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2954 if (IS_SYMOP (IC_LEFT (dic)) &&
2955 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2956 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2958 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2963 if (POINTER_SET (dic) &&
2964 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2966 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2974 return 0; /* did not find */
2977 /* This code is taken from the hc08 port. Do not know
2978 * if it fits for pic16, but I leave it here just in case */
2980 /* if assignment then check that right is not a bit */
2981 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2982 sym_link *etype = operandType (IC_RIGHT (dic));
2984 if (IS_BITFIELD (etype)) {
2985 /* if result is a bit too then it's ok */
2986 etype = operandType (IC_RESULT (dic));
2987 if (!IS_BITFIELD (etype)) {
2988 debugLog(" %d bitfields\n");
2995 /* if the result is on stack or iaccess then it must be
2996 the same atleast one of the operands */
2997 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2998 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3002 /* clear the onStack flag, the port doesn't support it yet! FIXME */
3003 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3004 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3008 /* the operation has only one symbol
3009 operator then we can pack */
3010 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3011 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3014 if (!((IC_LEFT (dic) &&
3015 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3017 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3021 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3022 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3023 /* found the definition */
3024 /* replace the result with the result of */
3025 /* this assignment and remove this assignment */
3026 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3027 IC_RESULT (dic) = IC_RESULT (ic);
3029 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3031 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3033 /* delete from liverange table also
3034 delete from all the points inbetween and the new
3036 for (sic = dic; sic != ic; sic = sic->next)
3038 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3039 if (IS_ITEMP (IC_RESULT (dic)))
3040 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3043 remiCodeFromeBBlock (ebp, ic);
3044 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3046 debugLog(" %d\n", __LINE__ );
3047 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3048 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3056 #define NO_packRegsForAccUse
3057 #define NO_packRegsForSupport
3058 #define NO_packRegsForOneuse
3059 #define NO_cast_peep
3064 #ifndef NO_packRegsForSupport
3065 /*-----------------------------------------------------------------*/
3066 /* findAssignToSym : scanning backwards looks for first assig found */
3067 /*-----------------------------------------------------------------*/
3069 findAssignToSym (operand * op, iCode * ic)
3073 debugLog ("%s\n", __FUNCTION__);
3074 for (dic = ic->prev; dic; dic = dic->prev)
3077 /* if definition by assignment */
3078 if (dic->op == '=' &&
3079 !POINTER_SET (dic) &&
3080 IC_RESULT (dic)->key == op->key
3081 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3085 /* we are interested only if defined in far space */
3086 /* or in stack space in case of + & - */
3088 /* if assigned to a non-symbol then return
3090 if (!IS_SYMOP (IC_RIGHT (dic)))
3093 /* if the symbol is in far space then
3095 if (isOperandInFarSpace (IC_RIGHT (dic)))
3098 /* for + & - operations make sure that
3099 if it is on the stack it is the same
3100 as one of the three operands */
3101 if ((ic->op == '+' || ic->op == '-') &&
3102 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3106 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3107 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3110 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3111 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3112 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3120 /* if we find an usage then we cannot delete it */
3121 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3124 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3127 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3131 /* now make sure that the right side of dic
3132 is not defined between ic & dic */
3135 iCode *sic = dic->next;
3137 for (; sic != ic; sic = sic->next)
3138 if (IC_RESULT (sic) &&
3139 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3150 #ifndef NO_packRegsForSupport
3151 /*-----------------------------------------------------------------*/
3152 /* packRegsForSupport :- reduce some registers for support calls */
3153 /*-----------------------------------------------------------------*/
3155 packRegsForSupport (iCode * ic, eBBlock * ebp)
3159 debugLog ("%s\n", __FUNCTION__);
3160 /* for the left & right operand :- look to see if the
3161 left was assigned a true symbol in far space in that
3162 case replace them */
3163 if (IS_ITEMP (IC_LEFT (ic)) &&
3164 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3166 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3172 debugAopGet ("removing left:", IC_LEFT (ic));
3174 /* found it we need to remove it from the
3176 for (sic = dic; sic != ic; sic = sic->next)
3177 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3179 IC_LEFT (ic)->operand.symOperand =
3180 IC_RIGHT (dic)->operand.symOperand;
3181 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3182 remiCodeFromeBBlock (ebp, dic);
3183 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3184 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3188 /* do the same for the right operand */
3191 IS_ITEMP (IC_RIGHT (ic)) &&
3192 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3194 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3200 /* if this is a subtraction & the result
3201 is a true symbol in far space then don't pack */
3202 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3204 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3205 if (IN_FARSPACE (SPEC_OCLS (etype)))
3209 debugAopGet ("removing right:", IC_RIGHT (ic));
3211 /* found it we need to remove it from the
3213 for (sic = dic; sic != ic; sic = sic->next)
3214 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3216 IC_RIGHT (ic)->operand.symOperand =
3217 IC_RIGHT (dic)->operand.symOperand;
3218 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3220 remiCodeFromeBBlock (ebp, dic);
3221 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3222 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3231 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3233 #ifndef NO_packRegsForOneuse
3234 /*-----------------------------------------------------------------*/
3235 /* packRegsForOneuse : - will reduce some registers for single Use */
3236 /*-----------------------------------------------------------------*/
3238 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3243 debugLog ("%s\n", __FUNCTION__);
3244 /* if returning a literal then do nothing */
3248 /* only upto 2 bytes since we cannot predict
3249 the usage of b, & acc */
3250 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3255 /* this routine will mark the a symbol as used in one
3256 instruction use only && if the definition is local
3257 (ie. within the basic block) && has only one definition &&
3258 that definition is either a return value from a
3259 function or does not contain any variables in
3261 uses = bitVectCopy (OP_USES (op));
3262 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3263 if (!bitVectIsZero (uses)) /* has other uses */
3266 /* if it has only one defintion */
3267 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3268 return NULL; /* has more than one definition */
3270 /* get that definition */
3272 hTabItemWithKey (iCodehTab,
3273 bitVectFirstBit (OP_DEFS (op)))))
3276 /* found the definition now check if it is local */
3277 if (dic->seq < ebp->fSeq ||
3278 dic->seq > ebp->lSeq)
3279 return NULL; /* non-local */
3281 /* now check if it is the return from
3283 if (dic->op == CALL || dic->op == PCALL)
3285 if (ic->op != SEND && ic->op != RETURN &&
3286 !POINTER_SET(ic) && !POINTER_GET(ic))
3288 OP_SYMBOL (op)->ruonly = 1;
3295 /* otherwise check that the definition does
3296 not contain any symbols in far space */
3297 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3298 isOperandInFarSpace (IC_RIGHT (dic)) ||
3299 IS_OP_RUONLY (IC_LEFT (ic)) ||
3300 IS_OP_RUONLY (IC_RIGHT (ic)))
3305 /* if pointer set then make sure the pointer
3307 if (POINTER_SET (dic) &&
3308 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3311 if (POINTER_GET (dic) &&
3312 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3317 /* also make sure the intervenening instructions
3318 don't have any thing in far space */
3319 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3322 /* if there is an intervening function call then no */
3323 if (dic->op == CALL || dic->op == PCALL)
3325 /* if pointer set then make sure the pointer
3327 if (POINTER_SET (dic) &&
3328 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3331 if (POINTER_GET (dic) &&
3332 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3335 /* if address of & the result is remat then okay */
3336 if (dic->op == ADDRESS_OF &&
3337 OP_SYMBOL (IC_RESULT (dic))->remat)
3340 /* if operand has size of three or more & this
3341 operation is a '*','/' or '%' then 'b' may
3343 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3344 getSize (operandType (op)) >= 3)
3347 /* if left or right or result is in far space */
3348 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3349 isOperandInFarSpace (IC_RIGHT (dic)) ||
3350 isOperandInFarSpace (IC_RESULT (dic)) ||
3351 IS_OP_RUONLY (IC_LEFT (dic)) ||
3352 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3353 IS_OP_RUONLY (IC_RESULT (dic)))
3359 OP_SYMBOL (op)->ruonly = 1;
3366 /*-----------------------------------------------------------------*/
3367 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3368 /*-----------------------------------------------------------------*/
3370 isBitwiseOptimizable (iCode * ic)
3372 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3373 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3375 debugLog ("%s\n", __FUNCTION__);
3376 /* bitwise operations are considered optimizable
3377 under the following conditions (Jean-Louis VERN)
3389 if (IS_LITERAL (rtype) ||
3390 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3397 #ifndef NO_packRegsForAccUse
3399 /*-----------------------------------------------------------------*/
3400 /* packRegsForAccUse - pack registers for acc use */
3401 /*-----------------------------------------------------------------*/
3403 packRegsForAccUse (iCode * ic)
3407 debugLog ("%s\n", __FUNCTION__);
3409 /* if this is an aggregate, e.g. a one byte char array */
3410 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3413 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3415 /* if + or - then it has to be one byte result */
3416 if ((ic->op == '+' || ic->op == '-')
3417 && getSize (operandType (IC_RESULT (ic))) > 1)
3420 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3421 /* if shift operation make sure right side is not a literal */
3422 if (ic->op == RIGHT_OP &&
3423 (isOperandLiteral (IC_RIGHT (ic)) ||
3424 getSize (operandType (IC_RESULT (ic))) > 1))
3427 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3428 if (ic->op == LEFT_OP &&
3429 (isOperandLiteral (IC_RIGHT (ic)) ||
3430 getSize (operandType (IC_RESULT (ic))) > 1))
3433 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3434 if (IS_BITWISE_OP (ic) &&
3435 getSize (operandType (IC_RESULT (ic))) > 1)
3439 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3440 /* has only one definition */
3441 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3444 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3445 /* has only one use */
3446 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3449 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3450 /* and the usage immediately follows this iCode */
3451 if (!(uic = hTabItemWithKey (iCodehTab,
3452 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3455 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3456 if (ic->next != uic)
3459 /* if it is a conditional branch then we definitely can */
3463 if (uic->op == JUMPTABLE)
3466 /* if the usage is not is an assignment
3467 or an arithmetic / bitwise / shift operation then not */
3468 if (POINTER_SET (uic) &&
3469 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3472 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3473 if (uic->op != '=' &&
3474 !IS_ARITHMETIC_OP (uic) &&
3475 !IS_BITWISE_OP (uic) &&
3476 uic->op != LEFT_OP &&
3477 uic->op != RIGHT_OP)
3480 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3481 /* if used in ^ operation then make sure right is not a
3483 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3486 /* if shift operation make sure right side is not a literal */
3487 if (uic->op == RIGHT_OP &&
3488 (isOperandLiteral (IC_RIGHT (uic)) ||
3489 getSize (operandType (IC_RESULT (uic))) > 1))
3492 if (uic->op == LEFT_OP &&
3493 (isOperandLiteral (IC_RIGHT (uic)) ||
3494 getSize (operandType (IC_RESULT (uic))) > 1))
3497 /* make sure that the result of this icode is not on the
3498 stack, since acc is used to compute stack offset */
3499 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3500 OP_SYMBOL (IC_RESULT (uic))->onStack)
3503 /* if either one of them in far space then we cannot */
3504 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3505 isOperandInFarSpace (IC_LEFT (uic))) ||
3506 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3507 isOperandInFarSpace (IC_RIGHT (uic))))
3510 /* if the usage has only one operand then we can */
3511 if (IC_LEFT (uic) == NULL ||
3512 IC_RIGHT (uic) == NULL)
3515 /* make sure this is on the left side if not
3516 a '+' since '+' is commutative */
3517 if (ic->op != '+' &&
3518 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3522 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3523 /* if one of them is a literal then we can */
3524 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3525 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3526 (getSize (operandType (IC_RESULT (uic))) <= 1))
3528 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3533 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3534 /* if the other one is not on stack then we can */
3535 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3536 (IS_ITEMP (IC_RIGHT (uic)) ||
3537 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3538 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3541 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3542 (IS_ITEMP (IC_LEFT (uic)) ||
3543 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3544 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3550 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3551 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3558 /*-----------------------------------------------------------------*/
3559 /* packForPush - hueristics to reduce iCode for pushing */
3560 /*-----------------------------------------------------------------*/
3562 packForReceive (iCode * ic, eBBlock * ebp)
3566 debugLog ("%s\n", __FUNCTION__);
3567 debugAopGet (" result:", IC_RESULT (ic));
3568 debugAopGet (" left:", IC_LEFT (ic));
3569 debugAopGet (" right:", IC_RIGHT (ic));
3574 for (dic = ic->next; dic; dic = dic->next)
3579 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3580 debugLog (" used on left\n");
3581 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3582 debugLog (" used on right\n");
3583 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3584 debugLog (" used on result\n");
3586 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3587 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3592 debugLog (" hey we can remove this unnecessary assign\n");
3594 /*-----------------------------------------------------------------*/
3595 /* packForPush - hueristics to reduce iCode for pushing */
3596 /*-----------------------------------------------------------------*/
3598 packForPush (iCode * ic, eBBlock * ebp)
3602 debugLog ("%s\n", __FUNCTION__);
3603 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3606 /* must have only definition & one usage */
3607 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3608 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3611 /* find the definition */
3612 if (!(dic = hTabItemWithKey (iCodehTab,
3613 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3616 if (dic->op != '=' || POINTER_SET (dic))
3619 /* we now we know that it has one & only one def & use
3620 and the that the definition is an assignment */
3621 IC_LEFT (ic) = IC_RIGHT (dic);
3623 remiCodeFromeBBlock (ebp, dic);
3624 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3625 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3628 static void printSymType(char * str, sym_link *sl)
3630 if(!pic16_ralloc_debug)return;
3632 debugLog (" %s Symbol type: ",str);
3633 printTypeChain( sl, debugF);
3637 /*-----------------------------------------------------------------*/
3638 /* some debug code to print the symbol S_TYPE. Note that
3639 * the function checkSClass in src/SDCCsymt.c dinks with
3640 * the S_TYPE in ways the PIC port doesn't fully like...*/
3641 /*-----------------------------------------------------------------*/
3642 static void isData(sym_link *sl)
3646 if(!pic16_ralloc_debug)return;
3653 for ( ; sl; sl=sl->next) {
3655 switch (SPEC_SCLS(sl)) {
3656 case S_DATA: fprintf (of, "data "); break;
3657 case S_XDATA: fprintf (of, "xdata "); break;
3658 case S_SFR: fprintf (of, "sfr "); break;
3659 case S_SBIT: fprintf (of, "sbit "); break;
3660 case S_CODE: fprintf (of, "code "); break;
3661 case S_IDATA: fprintf (of, "idata "); break;
3662 case S_PDATA: fprintf (of, "pdata "); break;
3663 case S_LITERAL: fprintf (of, "literal "); break;
3664 case S_STACK: fprintf (of, "stack "); break;
3665 case S_XSTACK: fprintf (of, "xstack "); break;
3666 case S_BIT: fprintf (of, "bit "); break;
3667 case S_EEPROM: fprintf (of, "eeprom "); break;
3676 /*--------------------------------------------------------------------*/
3677 /* pic16_packRegisters - does some transformations to reduce */
3678 /* register pressure */
3680 /*--------------------------------------------------------------------*/
3682 pic16_packRegisters (eBBlock * ebp)
3687 debugLog ("%s\n", __FUNCTION__);
3693 /* look for assignments of the form */
3694 /* iTempNN = TRueSym (someoperation) SomeOperand */
3696 /* TrueSym := iTempNN:1 */
3697 for (ic = ebp->sch; ic; ic = ic->next)
3699 // debugLog("%d\n", __LINE__);
3700 /* find assignment of the form TrueSym := iTempNN:1 */
3701 /* see BUGLOG0001 for workaround with the CAST - VR */
3702 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3703 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3704 change += packRegsForAssign (ic, ebp);
3708 if (POINTER_SET (ic))
3709 debugLog ("pointer is set\n");
3710 debugAopGet (" result:", IC_RESULT (ic));
3711 debugAopGet (" left:", IC_LEFT (ic));
3712 debugAopGet (" right:", IC_RIGHT (ic));
3721 for (ic = ebp->sch; ic; ic = ic->next) {
3723 if(IS_SYMOP ( IC_LEFT(ic))) {
3724 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3726 debugAopGet ("x left:", IC_LEFT (ic));
3728 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3730 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3732 debugLog (" is a pointer\n");
3734 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3735 debugLog (" is a ptr\n");
3737 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3738 debugLog (" is volatile\n");
3742 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3743 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3744 pic16_allocDirReg(IC_LEFT (ic));
3747 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3750 if(IS_SYMOP ( IC_RIGHT(ic))) {
3751 debugAopGet (" right:", IC_RIGHT (ic));
3752 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3755 if(IS_SYMOP ( IC_RESULT(ic))) {
3756 debugAopGet (" result:", IC_RESULT (ic));
3757 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3760 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3761 debugAopGet (" right:", IC_RIGHT (ic));
3762 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3763 // pic16_allocDirReg(IC_RIGHT(ic));
3766 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3767 debugAopGet (" result:", IC_RESULT (ic));
3768 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3769 // pic16_allocDirReg(IC_RESULT(ic));
3773 if (POINTER_SET (ic))
3774 debugLog (" %d - Pointer set\n", __LINE__);
3777 /* if this is an itemp & result of a address of a true sym
3778 then mark this as rematerialisable */
3779 if (ic->op == ADDRESS_OF &&
3780 IS_ITEMP (IC_RESULT (ic)) &&
3781 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3782 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3783 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3786 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3788 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3789 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3790 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3794 /* if straight assignment then carry remat flag if
3795 this is the only definition */
3796 if (ic->op == '=' &&
3797 !POINTER_SET (ic) &&
3798 IS_SYMOP (IC_RIGHT (ic)) &&
3799 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3800 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3802 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3804 OP_SYMBOL (IC_RESULT (ic))->remat =
3805 OP_SYMBOL (IC_RIGHT (ic))->remat;
3806 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3807 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3810 /* if this is a +/- operation with a rematerizable
3811 then mark this as rematerializable as well */
3812 if ((ic->op == '+' || ic->op == '-') &&
3813 (IS_SYMOP (IC_LEFT (ic)) &&
3814 IS_ITEMP (IC_RESULT (ic)) &&
3815 OP_SYMBOL (IC_LEFT (ic))->remat &&
3816 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3817 IS_OP_LITERAL (IC_RIGHT (ic))))
3819 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3821 operandLitValue (IC_RIGHT (ic));
3822 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3823 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3824 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3827 /* mark the pointer usages */
3828 if (POINTER_SET (ic))
3830 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3831 debugLog (" marking as a pointer (set) =>");
3832 debugAopGet (" result:", IC_RESULT (ic));
3834 if (POINTER_GET (ic))
3836 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3837 debugLog (" marking as a pointer (get) =>");
3838 debugAopGet (" left:", IC_LEFT (ic));
3841 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3845 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3846 /* if we are using a symbol on the stack
3847 then we should say pic16_ptrRegReq */
3848 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3849 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3850 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3851 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3852 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3853 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3857 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3858 if (IS_SYMOP (IC_LEFT (ic)))
3859 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3860 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3861 if (IS_SYMOP (IC_RIGHT (ic)))
3862 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3863 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3864 if (IS_SYMOP (IC_RESULT (ic)))
3865 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3866 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3869 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3873 /* if the condition of an if instruction
3874 is defined in the previous instruction then
3875 mark the itemp as a conditional */
3876 if ((IS_CONDITIONAL (ic) ||
3877 ((ic->op == BITWISEAND ||
3880 isBitwiseOptimizable (ic))) &&
3881 ic->next && ic->next->op == IFX &&
3882 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3883 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3886 debugLog (" %d\n", __LINE__);
3887 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3891 debugLog(" %d\n", __LINE__);
3893 #ifndef NO_packRegsForSupport
3894 /* reduce for support function calls */
3895 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3896 packRegsForSupport (ic, ebp);
3899 /* if a parameter is passed, it's in W, so we may not
3900 need to place a copy in a register */
3901 if (ic->op == RECEIVE)
3902 packForReceive (ic, ebp);
3904 #ifndef NO_packRegsForOneuse
3905 /* some cases the redundant moves can
3906 can be eliminated for return statements */
3907 if ((ic->op == RETURN || ic->op == SEND) &&
3908 !isOperandInFarSpace (IC_LEFT (ic)) &&
3910 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3913 #ifndef NO_packRegsForOneuse
3914 /* if pointer set & left has a size more than
3915 one and right is not in far space */
3916 if (POINTER_SET (ic) &&
3917 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3918 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3919 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3920 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3922 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3925 #ifndef NO_packRegsForOneuse
3926 /* if pointer get */
3927 if (POINTER_GET (ic) &&
3928 !isOperandInFarSpace (IC_RESULT (ic)) &&
3929 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3930 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3931 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3933 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3934 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3937 #ifndef NO_cast_peep
3938 /* if this is cast for intergral promotion then
3939 check if only use of the definition of the
3940 operand being casted/ if yes then replace
3941 the result of that arithmetic operation with
3942 this result and get rid of the cast */
3943 if (ic->op == CAST) {
3945 sym_link *fromType = operandType (IC_RIGHT (ic));
3946 sym_link *toType = operandType (IC_LEFT (ic));
3948 debugLog (" %d - casting\n", __LINE__);
3950 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3951 getSize (fromType) != getSize (toType)) {
3954 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3957 if (IS_ARITHMETIC_OP (dic)) {
3958 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3960 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3961 IC_RESULT (dic) = IC_RESULT (ic);
3962 remiCodeFromeBBlock (ebp, ic);
3963 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3964 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3965 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3969 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3973 /* if the type from and type to are the same
3974 then if this is the only use then packit */
3975 if (compareType (operandType (IC_RIGHT (ic)),
3976 operandType (IC_LEFT (ic))) == 1) {
3978 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3981 debugLog(" %d\n", __LINE__);
3983 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3984 IC_RESULT (dic) = IC_RESULT (ic);
3985 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3986 remiCodeFromeBBlock (ebp, ic);
3987 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3988 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3996 iTempNN := (some variable in farspace) V1
4001 if (ic->op == IPUSH)
4003 packForPush (ic, ebp);
4007 #ifndef NO_packRegsForAccUse
4008 /* pack registers for accumulator use, when the
4009 result of an arithmetic or bit wise operation
4010 has only one use, that use is immediately following
4011 the defintion and the using iCode has only one
4012 operand or has two operands but one is literal &
4013 the result of that operation is not on stack then
4014 we can leave the result of this operation in acc:b
4016 if ((IS_ARITHMETIC_OP (ic)
4018 || IS_BITWISE_OP (ic)
4020 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4023 IS_ITEMP (IC_RESULT (ic)) &&
4024 getSize (operandType (IC_RESULT (ic))) <= 1)
4026 packRegsForAccUse (ic);
4033 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4037 if (!pic16_ralloc_debug || !debugF)
4040 for (i = 0; i < count; i++)
4042 fprintf (debugF, "\n----------------------------------------------------------------\n");
4043 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4044 ebbs[i]->entryLabel->name,
4047 ebbs[i]->isLastInLoop);
4048 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4053 fprintf (debugF, "visited %d : hasFcall = %d\n",
4057 fprintf (debugF, "\ndefines bitVector :");
4058 bitVectDebugOn (ebbs[i]->defSet, debugF);
4059 fprintf (debugF, "\nlocal defines bitVector :");
4060 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4061 fprintf (debugF, "\npointers Set bitvector :");
4062 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4063 fprintf (debugF, "\nin pointers Set bitvector :");
4064 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4065 fprintf (debugF, "\ninDefs Set bitvector :");
4066 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4067 fprintf (debugF, "\noutDefs Set bitvector :");
4068 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4069 fprintf (debugF, "\nusesDefs Set bitvector :");
4070 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4071 fprintf (debugF, "\n----------------------------------------------------------------\n");
4072 printiCChain (ebbs[i]->sch, debugF);
4075 /*-----------------------------------------------------------------*/
4076 /* pic16_assignRegisters - assigns registers to each live range as need */
4077 /*-----------------------------------------------------------------*/
4079 pic16_assignRegisters (eBBlock ** ebbs, int count)
4084 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4085 debugLog ("\nebbs before optimizing:\n");
4086 dumpEbbsToDebug (ebbs, count);
4088 setToNull ((void *) &_G.funcrUsed);
4089 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4092 /* change assignments this will remove some
4093 live ranges reducing some register pressure */
4094 for (i = 0; i < count; i++)
4095 pic16_packRegisters (ebbs[i]);
4102 debugLog("dir registers allocated so far:\n");
4103 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4106 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4107 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4108 reg = hTabNextItem(dynDirectRegNames, &hkey);
4113 /* liveranges probably changed by register packing
4114 so we compute them again */
4115 recomputeLiveRanges (ebbs, count);
4117 if (options.dump_pack)
4118 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4120 /* first determine for each live range the number of
4121 registers & the type of registers required for each */
4124 /* and serially allocate registers */
4125 serialRegAssign (ebbs, count);
4127 // debugLog ("ebbs after serialRegAssign:\n");
4128 // dumpEbbsToDebug (ebbs, count);
4131 //pic16_freeAllRegs();
4133 /* if stack was extended then tell the user */
4136 /* werror(W_TOOMANY_SPILS,"stack", */
4137 /* _G.stackExtend,currFunc->name,""); */
4143 /* werror(W_TOOMANY_SPILS,"data space", */
4144 /* _G.dataExtend,currFunc->name,""); */
4148 /* after that create the register mask
4149 for each of the instruction */
4150 createRegMask (ebbs, count);
4152 /* redo that offsets for stacked automatic variables */
4153 redoStackOffsets ();
4155 if (options.dump_rassgn)
4156 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4158 /* now get back the chain */
4159 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4161 debugLog ("ebbs after optimizing:\n");
4162 dumpEbbsToDebug (ebbs, count);
4167 /* free up any _G.stackSpil locations allocated */
4168 applyToSet (_G.stackSpil, deallocStackSpil);
4170 setToNull ((void *) &_G.stackSpil);
4171 setToNull ((void *) &_G.spiltSet);
4172 /* mark all registers as free */
4173 pic16_freeAllRegs ();
4175 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");