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
43 /*-----------------------------------------------------------------*/
44 /* At this point we start getting processor specific although */
45 /* some routines are non-processor specific & can be reused when */
46 /* targetting other processors. The decision for this will have */
47 /* to be made on a routine by routine basis */
48 /* routines used to pack registers are most definitely not reusable */
49 /* since the pack the registers depending strictly on the MCU */
50 /*-----------------------------------------------------------------*/
52 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
53 extern void genpic16Code (iCode *);
63 bitVect *funcrUsed; /* registers used in a function */
69 /* Shared with gen.c */
70 int pic16_ptrRegReq; /* one byte pointer register required */
73 set *pic16_dynAllocRegs=NULL;
74 set *pic16_dynStackRegs=NULL;
75 set *pic16_dynProcessorRegs=NULL;
76 set *pic16_dynDirectRegs=NULL;
77 set *pic16_dynDirectBitRegs=NULL;
78 set *pic16_dynInternalRegs=NULL;
79 set *pic16_dynAccessRegs=NULL;
81 static hTab *dynDirectRegNames=NULL;
82 static hTab *dynAllocRegNames=NULL;
83 static hTab *dynProcRegNames=NULL;
84 static hTab *dynAccessRegNames=NULL;
85 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
87 extern set *sectNames;
89 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
90 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
91 set *pic16_equ_data=NULL; /* registers used by equates */
92 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
93 set *pic16_acs_udata=NULL; /* access bank variables */
95 set *pic16_builtin_functions=NULL;
97 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
98 static int rDirectIdx=0;
100 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
102 int pic16_Gstack_base_addr=0; /* The starting address of registers that
103 * are used to pass and return parameters */
108 static void spillThis (symbol *);
109 int pic16_ralloc_debug = 0;
110 static FILE *debugF = NULL;
111 /*-----------------------------------------------------------------*/
112 /* debugLog - open a file for debugging information */
113 /*-----------------------------------------------------------------*/
114 //static void debugLog(char *inst,char *fmt, ...)
116 debugLog (char *fmt,...)
118 static int append = 0; // First time through, open the file without append.
121 //char *bufferP=buffer;
124 if (!pic16_ralloc_debug || !dstFileName)
130 /* create the file name */
131 strcpy (buffer, dstFileName);
132 strcat (buffer, ".d");
134 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
136 werror (E_FILE_OPEN_ERR, buffer);
139 append = 1; // Next time debubLog is called, we'll append the debug info
145 vsprintf (buffer, fmt, ap);
147 fprintf (debugF, "%s", buffer);
149 while (isspace(*bufferP)) bufferP++;
151 if (bufferP && *bufferP)
152 lineCurr = (lineCurr ?
153 connectLine(lineCurr,newLineNode(lb)) :
154 (lineHead = newLineNode(lb)));
155 lineCurr->isInline = _G.inLine;
156 lineCurr->isDebug = _G.debugLine;
165 if(!pic16_ralloc_debug)return;
168 fputc ('\n', debugF);
170 /*-----------------------------------------------------------------*/
171 /* debugLogClose - closes the debug log file (if opened) */
172 /*-----------------------------------------------------------------*/
182 #define AOP(op) op->aop
185 debugAopGet (char *str, operand * op)
187 if(!pic16_ralloc_debug)return NULL;
192 printOperand (op, debugF);
199 decodeOp (unsigned int op)
201 if (op < 128 && op > ' ') {
202 buffer[0] = (op & 0xff);
208 case IDENTIFIER: return "IDENTIFIER";
209 case TYPE_NAME: return "TYPE_NAME";
210 case CONSTANT: return "CONSTANT";
211 case STRING_LITERAL: return "STRING_LITERAL";
212 case SIZEOF: return "SIZEOF";
213 case PTR_OP: return "PTR_OP";
214 case INC_OP: return "INC_OP";
215 case DEC_OP: return "DEC_OP";
216 case LEFT_OP: return "LEFT_OP";
217 case RIGHT_OP: return "RIGHT_OP";
218 case LE_OP: return "LE_OP";
219 case GE_OP: return "GE_OP";
220 case EQ_OP: return "EQ_OP";
221 case NE_OP: return "NE_OP";
222 case AND_OP: return "AND_OP";
223 case OR_OP: return "OR_OP";
224 case MUL_ASSIGN: return "MUL_ASSIGN";
225 case DIV_ASSIGN: return "DIV_ASSIGN";
226 case MOD_ASSIGN: return "MOD_ASSIGN";
227 case ADD_ASSIGN: return "ADD_ASSIGN";
228 case SUB_ASSIGN: return "SUB_ASSIGN";
229 case LEFT_ASSIGN: return "LEFT_ASSIGN";
230 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
231 case AND_ASSIGN: return "AND_ASSIGN";
232 case XOR_ASSIGN: return "XOR_ASSIGN";
233 case OR_ASSIGN: return "OR_ASSIGN";
234 case TYPEDEF: return "TYPEDEF";
235 case EXTERN: return "EXTERN";
236 case STATIC: return "STATIC";
237 case AUTO: return "AUTO";
238 case REGISTER: return "REGISTER";
239 case CODE: return "CODE";
240 case EEPROM: return "EEPROM";
241 case INTERRUPT: return "INTERRUPT";
242 case SFR: return "SFR";
243 case AT: return "AT";
244 case SBIT: return "SBIT";
245 case REENTRANT: return "REENTRANT";
246 case USING: return "USING";
247 case XDATA: return "XDATA";
248 case DATA: return "DATA";
249 case IDATA: return "IDATA";
250 case PDATA: return "PDATA";
251 case VAR_ARGS: return "VAR_ARGS";
252 case CRITICAL: return "CRITICAL";
253 case NONBANKED: return "NONBANKED";
254 case BANKED: return "BANKED";
255 case CHAR: return "CHAR";
256 case SHORT: return "SHORT";
257 case INT: return "INT";
258 case LONG: return "LONG";
259 case SIGNED: return "SIGNED";
260 case UNSIGNED: return "UNSIGNED";
261 case FLOAT: return "FLOAT";
262 case DOUBLE: return "DOUBLE";
263 case CONST: return "CONST";
264 case VOLATILE: return "VOLATILE";
265 case VOID: return "VOID";
266 case BIT: return "BIT";
267 case STRUCT: return "STRUCT";
268 case UNION: return "UNION";
269 case ENUM: return "ENUM";
270 case ELIPSIS: return "ELIPSIS";
271 case RANGE: return "RANGE";
272 case FAR: return "FAR";
273 case CASE: return "CASE";
274 case DEFAULT: return "DEFAULT";
275 case IF: return "IF";
276 case ELSE: return "ELSE";
277 case SWITCH: return "SWITCH";
278 case WHILE: return "WHILE";
279 case DO: return "DO";
280 case FOR: return "FOR";
281 case GOTO: return "GOTO";
282 case CONTINUE: return "CONTINUE";
283 case BREAK: return "BREAK";
284 case RETURN: return "RETURN";
285 case INLINEASM: return "INLINEASM";
286 case IFX: return "IFX";
287 case ADDRESS_OF: return "ADDRESS_OF";
288 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
289 case SPIL: return "SPIL";
290 case UNSPIL: return "UNSPIL";
291 case GETHBIT: return "GETHBIT";
292 case BITWISEAND: return "BITWISEAND";
293 case UNARYMINUS: return "UNARYMINUS";
294 case IPUSH: return "IPUSH";
295 case IPOP: return "IPOP";
296 case PCALL: return "PCALL";
297 case ENDFUNCTION: return "ENDFUNCTION";
298 case JUMPTABLE: return "JUMPTABLE";
299 case RRC: return "RRC";
300 case RLC: return "RLC";
301 case CAST: return "CAST";
302 case CALL: return "CALL";
303 case PARAM: return "PARAM ";
304 case NULLOP: return "NULLOP";
305 case BLOCK: return "BLOCK";
306 case LABEL: return "LABEL";
307 case RECEIVE: return "RECEIVE";
308 case SEND: return "SEND";
310 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
314 /*-----------------------------------------------------------------*/
315 /*-----------------------------------------------------------------*/
317 debugLogRegType (short type)
319 if(!pic16_ralloc_debug)return NULL;
321 case REG_GPR: return "REG_GPR";
322 case REG_PTR: return "REG_PTR";
323 case REG_CND: return "REG_CND";
325 sprintf (buffer, "unknown reg type %d", type);
330 /*-----------------------------------------------------------------*/
331 /*-----------------------------------------------------------------*/
332 static int regname2key(char const *name)
341 key += (*name++) + 1;
345 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
349 /*-----------------------------------------------------------------*/
350 /* newReg - allocate and init memory for a new register */
351 /*-----------------------------------------------------------------*/
352 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
357 dReg = Safe_calloc(1,sizeof(regs));
359 dReg->pc_type = pc_type;
362 dReg->name = Safe_strdup(name);
364 sprintf(buffer,"r0x%02X", dReg->rIdx);
367 dReg->name = Safe_strdup(buffer);
375 if(type == REG_SFR) {
377 dReg->address = rIdx;
378 dReg->accessBank = 1;
382 dReg->accessBank = 0;
385 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
389 dReg->reg_alias = NULL;
390 dReg->reglives.usedpFlows = newSet();
391 dReg->reglives.assignedpFlows = newSet();
394 if(!(type == REG_SFR && alias == 0x80))
395 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
400 /*-----------------------------------------------------------------*/
401 /* regWithIdx - Search through a set of registers that matches idx */
402 /*-----------------------------------------------------------------*/
404 regWithIdx (set *dRegs, int idx, unsigned fixed)
408 for (dReg = setFirstItem(dRegs) ; dReg ;
409 dReg = setNextItem(dRegs)) {
411 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
419 /*-----------------------------------------------------------------*/
420 /* regFindFree - Search for a free register in a set of registers */
421 /*-----------------------------------------------------------------*/
423 regFindFree (set *dRegs)
427 for (dReg = setFirstItem(dRegs) ; dReg ;
428 dReg = setNextItem(dRegs)) {
430 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
431 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
440 /*-----------------------------------------------------------------*/
441 /* pic16_initStack - allocate registers for a pseudo stack */
442 /*-----------------------------------------------------------------*/
443 void pic16_initStack(int base_address, int size)
448 pic16_Gstack_base_addr = base_address;
449 //fprintf(stderr,"initStack");
451 for(i = 0; i<size; i++)
452 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
455 /*-----------------------------------------------------------------*
456 *-----------------------------------------------------------------*/
458 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
460 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
462 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
464 reg->wasUsed = 0; // we do not know if they are going to be used at all
465 reg->accessBank = 1; // implicit add access Bank
467 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
469 return addSet(&pic16_dynProcessorRegs, reg);
472 /*-----------------------------------------------------------------*
473 *-----------------------------------------------------------------*/
476 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
478 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
480 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
484 return addSet(&pic16_dynInternalRegs,reg);
489 /*-----------------------------------------------------------------*/
490 /* allocReg - allocates register of given type */
491 /*-----------------------------------------------------------------*/
493 allocReg (short type)
498 if(dynrIdx > pic16_nRegs)
502 /* try to reuse some unused registers */
503 reg = regFindFree( pic16_dynAllocRegs );
506 // fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
510 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
511 // addSet(&pic16_dynAllocRegs, reg);
514 addSet(&pic16_dynAllocRegs, reg);
515 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
519 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
521 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
522 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
525 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
526 reg->isLocal = 1; /* this is a local frame register */
531 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
532 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
535 return (reg); // addSet(&pic16_dynAllocRegs,reg);
540 /*-----------------------------------------------------------------*/
541 /* pic16_dirregWithName - search for register by name */
542 /*-----------------------------------------------------------------*/
544 pic16_dirregWithName (char *name)
552 /* hash the name to get a key */
554 hkey = regname2key(name);
556 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
558 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
562 if(STRCASECMP(reg->name, name) == 0) {
563 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
567 reg = hTabNextItemWK (dynDirectRegNames);
571 return NULL; // name wasn't found in the hash table
574 /*-----------------------------------------------------------------*/
575 /* pic16_allocregWithName - search for register by name */
576 /*-----------------------------------------------------------------*/
578 pic16_allocregWithName (char *name)
586 /* hash the name to get a key */
588 hkey = regname2key(name);
590 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
592 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
596 if(STRCASECMP(reg->name, name) == 0) {
600 reg = hTabNextItemWK (dynAllocRegNames);
604 return NULL; // name wasn't found in the hash table
609 /*-----------------------------------------------------------------*/
610 /* pic16_procregWithName - search for register by name */
611 /*-----------------------------------------------------------------*/
613 pic16_procregWithName (char *name)
621 /* hash the name to get a key */
623 hkey = regname2key(name);
625 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
627 reg = hTabFirstItemWK(dynProcRegNames, hkey);
631 if(STRCASECMP(reg->name, name) == 0) {
635 reg = hTabNextItemWK (dynProcRegNames);
639 return NULL; // name wasn't found in the hash table
643 /*-----------------------------------------------------------------*/
644 /* pic16_accessregWithName - search for register by name */
645 /*-----------------------------------------------------------------*/
647 pic16_accessregWithName (char *name)
655 /* hash the name to get a key */
657 hkey = regname2key(name);
659 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
661 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
665 if(STRCASECMP(reg->name, name) == 0) {
669 reg = hTabNextItemWK (dynAccessRegNames);
673 return NULL; // name wasn't found in the hash table
677 regs *pic16_regWithName(char *name)
681 reg = pic16_dirregWithName( name );
684 reg = pic16_procregWithName( name );
687 reg = pic16_allocregWithName( name );
690 reg = pic16_accessregWithName( name );
697 /*-----------------------------------------------------------------*/
698 /* pic16_allocDirReg - allocates register of given type */
699 /*-----------------------------------------------------------------*/
701 pic16_allocDirReg (operand *op )
707 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
708 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
712 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
715 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
717 if(pic16_debug_verbose)
719 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
720 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
726 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
727 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
730 if(pic16_debug_verbose) {
731 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
732 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
733 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
734 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
735 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
736 IN_STACK( OP_SYM_ETYPE(op)),
737 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
738 IS_REGPARM(OP_SYM_ETYPE(op)),
741 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
742 OP_SYMBOL(op)->name);
750 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
751 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
755 if(IS_ITEMP(op))return NULL;
757 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
758 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
761 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
762 debugLog(" %d const char\n",__LINE__);
763 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
764 // fprintf(stderr, " %d const char\n",__LINE__);
765 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
769 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
770 if (IS_CODE ( OP_SYM_ETYPE(op)) )
771 debugLog(" %d code space\n",__LINE__);
773 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
774 debugLog(" %d integral\n",__LINE__);
776 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
777 debugLog(" %d literal\n",__LINE__);
779 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
780 debugLog(" %d specifier\n",__LINE__);
782 debugAopGet(NULL, op);
786 reg = pic16_dirregWithName(name);
790 int regtype = REG_GPR;
792 /* if this is at an absolute address, then get the address. */
793 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
794 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
795 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
798 /* Register wasn't found in hash, so let's create
799 * a new one and put it in the hash table AND in the
800 * dynDirectRegNames set */
801 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
802 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
808 if(OP_SYMBOL(op)->onStack) {
809 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
810 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
814 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
815 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
818 if(pic16_debug_verbose)
820 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
821 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
822 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
823 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
824 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
825 IN_STACK( OP_SYM_ETYPE(op)),
826 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
828 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
829 OP_SYMBOL(op)->name);
834 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
835 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
837 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
838 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
842 checkAddReg(&pic16_dynAccessRegs, reg);
843 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
849 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
850 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
851 // reg->type = REG_SFR;
854 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
855 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
856 addSet(&pic16_dynDirectBitRegs, reg);
859 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
860 // addSet(&pic16_dynDirectRegs, reg);
862 checkAddReg(&pic16_dynDirectRegs, reg);
866 // debugLog (" -- %s is declared at address 0x30000x\n",name);
867 return (reg); /* This was NULL before, but since we found it
868 * why not just return it?! */
871 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
873 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
875 /* work around for user defined registers in access bank */
876 if((reg->address>= 0x00 && reg->address < 0x80)
877 || (reg->address >= 0xf80 && reg->address <= 0xfff))
880 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
886 /*-----------------------------------------------------------------*/
887 /* pic16_allocRegByName - allocates register of given type */
888 /*-----------------------------------------------------------------*/
890 pic16_allocRegByName (char *name, int size, operand *op)
896 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
900 /* First, search the hash table to see if there is a register with this name */
901 reg = pic16_dirregWithName(name);
905 /* Register wasn't found in hash, so let's create
906 * a new one and put it in the hash table AND in the
907 * dynDirectRegNames set */
909 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
911 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
913 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
914 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
916 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
917 addSet(&pic16_dynDirectRegs, reg);
923 /*-----------------------------------------------------------------*/
924 /* RegWithIdx - returns pointer to register with index number */
925 /*-----------------------------------------------------------------*/
926 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
931 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
932 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
937 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
939 debugLog ("Found a Dynamic Register!\n");
942 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
943 debugLog ("Found a Direct Register!\n");
949 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
950 debugLog ("Found a Stack Register!\n");
955 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
956 debugLog ("Found a Processor Register!\n");
970 /*-----------------------------------------------------------------*/
971 /* pic16_regWithIdx - returns pointer to register with index number*/
972 /*-----------------------------------------------------------------*/
974 pic16_regWithIdx (int idx)
978 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
981 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
985 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
992 /*-----------------------------------------------------------------*/
993 /* pic16_regWithIdx - returns pointer to register with index number */
994 /*-----------------------------------------------------------------*/
996 pic16_allocWithIdx (int idx)
1001 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1002 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1004 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1006 debugLog ("Found a Dynamic Register!\n");
1007 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1008 debugLog ("Found a Stack Register!\n");
1009 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1010 debugLog ("Found a Processor Register!\n");
1011 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1012 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1013 debugLog ("Found an Internal Register!\n");
1016 debugLog ("Dynamic Register not found\n");
1019 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1020 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1021 "regWithIdx not found");
1031 /*-----------------------------------------------------------------*/
1032 /*-----------------------------------------------------------------*/
1034 pic16_findFreeReg(short type)
1041 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1043 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1047 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1059 /*-----------------------------------------------------------------*/
1060 /* freeReg - frees a register */
1061 /*-----------------------------------------------------------------*/
1063 freeReg (regs * reg)
1065 debugLog ("%s\n", __FUNCTION__);
1066 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1071 /*-----------------------------------------------------------------*/
1072 /* nFreeRegs - returns number of free registers */
1073 /*-----------------------------------------------------------------*/
1075 nFreeRegs (int type)
1081 /* although I fixed the register allocation/freeing scheme
1082 * the for loop below doesn't give valid results. I do not
1083 * know why yet. -- VR 10-Jan-2003 */
1088 /* dynamically allocate as many as we need and worry about
1089 * fitting them into a PIC later */
1091 debugLog ("%s\n", __FUNCTION__);
1093 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1094 if((reg->type == type) && reg->isFree)nfr++;
1096 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1100 /*-----------------------------------------------------------------*/
1101 /* nfreeRegsType - free registers with type */
1102 /*-----------------------------------------------------------------*/
1104 nfreeRegsType (int type)
1107 debugLog ("%s\n", __FUNCTION__);
1108 if (type == REG_PTR)
1110 if ((nfr = nFreeRegs (type)) == 0)
1111 return nFreeRegs (REG_GPR);
1114 return nFreeRegs (type);
1117 static void writeSetUsedRegs(FILE *of, set *dRegs)
1122 for (dReg = setFirstItem(dRegs) ; dReg ;
1123 dReg = setNextItem(dRegs)) {
1126 fprintf (of, "\t%s\n",dReg->name);
1132 extern void pic16_groupRegistersInSection(set *regset);
1134 extern void pic16_dump_equates(FILE *of, set *equs);
1135 extern void pic16_dump_access(FILE *of, set *section);
1136 //extern void pic16_dump_map(void);
1137 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1138 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1139 extern void pic16_dump_int_registers(FILE *of, set *section);
1140 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1142 extern void pic16_dump_gsection(FILE *of, set *sections);
1144 static void packBits(set *bregs)
1148 regs *bitfield=NULL;
1149 regs *relocbitfield=NULL;
1155 for (regset = bregs ; regset ;
1156 regset = regset->next) {
1158 breg = regset->item;
1159 breg->isBitField = 1;
1160 //fprintf(stderr,"bit reg: %s\n",breg->name);
1163 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1165 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1166 breg->rIdx = breg->address & 7;
1167 breg->address >>= 3;
1170 sprintf (buffer, "fbitfield%02x", breg->address);
1171 //fprintf(stderr,"new bit field\n");
1172 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1173 bitfield->isBitField = 1;
1174 bitfield->isFixed = 1;
1175 bitfield->address = breg->address;
1176 addSet(&pic16_dynDirectRegs,bitfield);
1177 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1179 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1182 breg->reg_alias = bitfield;
1186 if(!relocbitfield || bit_no >7) {
1189 sprintf (buffer, "bitfield%d", byte_no);
1190 //fprintf(stderr,"new relocatable bit field\n");
1191 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1192 relocbitfield->isBitField = 1;
1193 addSet(&pic16_dynDirectRegs,relocbitfield);
1194 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1198 breg->reg_alias = relocbitfield;
1199 breg->address = rDirectIdx; /* byte_no; */
1200 breg->rIdx = bit_no++;
1206 void pic16_writeUsedRegs(FILE *of)
1208 packBits(pic16_dynDirectBitRegs);
1210 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1211 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1213 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1214 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1216 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1217 pic16_groupRegistersInSection(pic16_dynStackRegs);
1219 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1220 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1222 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1223 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1225 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1226 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1228 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1229 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1232 pic16_dump_equates(of, pic16_equ_data);
1234 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1235 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1237 /* dump access bank symbols */
1238 pic16_dump_access(of, pic16_acs_udata);
1240 /* dump initialised data */
1241 pic16_dump_isection(of, rel_idataSymSet, 0);
1242 pic16_dump_isection(of, fix_idataSymSet, 1);
1244 /* dump internal registers */
1245 pic16_dump_int_registers(of, pic16_int_regs);
1247 /* dump generic section variables */
1248 pic16_dump_gsection(of, sectNames);
1250 /* dump other variables */
1251 pic16_dump_usection(of, pic16_rel_udata, 0);
1252 pic16_dump_usection(of, pic16_fix_udata, 1);
1257 /*-----------------------------------------------------------------*/
1258 /* computeSpillable - given a point find the spillable live ranges */
1259 /*-----------------------------------------------------------------*/
1261 computeSpillable (iCode * ic)
1265 debugLog ("%s\n", __FUNCTION__);
1266 /* spillable live ranges are those that are live at this
1267 point . the following categories need to be subtracted
1269 a) - those that are already spilt
1270 b) - if being used by this one
1271 c) - defined by this one */
1273 spillable = bitVectCopy (ic->rlive);
1275 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1277 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1278 bitVectUnSetBit (spillable, ic->defKey);
1279 spillable = bitVectIntersect (spillable, _G.regAssigned);
1284 /*-----------------------------------------------------------------*/
1285 /* noSpilLoc - return true if a variable has no spil location */
1286 /*-----------------------------------------------------------------*/
1288 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1290 debugLog ("%s\n", __FUNCTION__);
1291 return (sym->usl.spillLoc ? 0 : 1);
1294 /*-----------------------------------------------------------------*/
1295 /* hasSpilLoc - will return 1 if the symbol has spil location */
1296 /*-----------------------------------------------------------------*/
1298 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1300 debugLog ("%s\n", __FUNCTION__);
1301 return (sym->usl.spillLoc ? 1 : 0);
1304 /*-----------------------------------------------------------------*/
1305 /* directSpilLoc - will return 1 if the splilocation is in direct */
1306 /*-----------------------------------------------------------------*/
1308 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1310 debugLog ("%s\n", __FUNCTION__);
1311 if (sym->usl.spillLoc &&
1312 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1318 /*-----------------------------------------------------------------*/
1319 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1320 /* but is not used as a pointer */
1321 /*-----------------------------------------------------------------*/
1323 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1325 debugLog ("%s\n", __FUNCTION__);
1326 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1329 /*-----------------------------------------------------------------*/
1330 /* rematable - will return 1 if the remat flag is set */
1331 /*-----------------------------------------------------------------*/
1333 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1335 debugLog ("%s\n", __FUNCTION__);
1339 /*-----------------------------------------------------------------*/
1340 /* notUsedInRemaining - not used or defined in remain of the block */
1341 /*-----------------------------------------------------------------*/
1343 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1345 debugLog ("%s\n", __FUNCTION__);
1346 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1347 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1350 /*-----------------------------------------------------------------*/
1351 /* allLRs - return true for all */
1352 /*-----------------------------------------------------------------*/
1354 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1356 debugLog ("%s\n", __FUNCTION__);
1360 /*-----------------------------------------------------------------*/
1361 /* liveRangesWith - applies function to a given set of live range */
1362 /*-----------------------------------------------------------------*/
1364 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1365 eBBlock * ebp, iCode * ic)
1370 debugLog ("%s\n", __FUNCTION__);
1371 if (!lrs || !lrs->size)
1374 for (i = 1; i < lrs->size; i++)
1377 if (!bitVectBitValue (lrs, i))
1380 /* if we don't find it in the live range
1381 hash table we are in serious trouble */
1382 if (!(sym = hTabItemWithKey (liveRanges, i)))
1384 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1385 "liveRangesWith could not find liveRange");
1389 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1390 addSetHead (&rset, sym);
1397 /*-----------------------------------------------------------------*/
1398 /* leastUsedLR - given a set determines which is the least used */
1399 /*-----------------------------------------------------------------*/
1401 leastUsedLR (set * sset)
1403 symbol *sym = NULL, *lsym = NULL;
1405 debugLog ("%s\n", __FUNCTION__);
1406 sym = lsym = setFirstItem (sset);
1411 for (; lsym; lsym = setNextItem (sset))
1414 /* if usage is the same then prefer
1415 the spill the smaller of the two */
1416 if (lsym->used == sym->used)
1417 if (getSize (lsym->type) < getSize (sym->type))
1421 if (lsym->used < sym->used)
1426 setToNull ((void *) &sset);
1431 /*-----------------------------------------------------------------*/
1432 /* noOverLap - will iterate through the list looking for over lap */
1433 /*-----------------------------------------------------------------*/
1435 noOverLap (set * itmpStack, symbol * fsym)
1438 debugLog ("%s\n", __FUNCTION__);
1441 for (sym = setFirstItem (itmpStack); sym;
1442 sym = setNextItem (itmpStack))
1444 if (sym->liveTo > fsym->liveFrom)
1452 /*-----------------------------------------------------------------*/
1453 /* isFree - will return 1 if the a free spil location is found */
1454 /*-----------------------------------------------------------------*/
1459 V_ARG (symbol **, sloc);
1460 V_ARG (symbol *, fsym);
1462 debugLog ("%s\n", __FUNCTION__);
1463 /* if already found */
1467 /* if it is free && and the itmp assigned to
1468 this does not have any overlapping live ranges
1469 with the one currently being assigned and
1470 the size can be accomodated */
1472 noOverLap (sym->usl.itmpStack, fsym) &&
1473 getSize (sym->type) >= getSize (fsym->type))
1482 /*-----------------------------------------------------------------*/
1483 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1484 /*-----------------------------------------------------------------*/
1486 spillLRWithPtrReg (symbol * forSym)
1492 debugLog ("%s\n", __FUNCTION__);
1493 if (!_G.regAssigned ||
1494 bitVectIsZero (_G.regAssigned))
1497 r0 = pic16_regWithIdx (R0_IDX);
1498 r1 = pic16_regWithIdx (R1_IDX);
1500 /* for all live ranges */
1501 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1502 lrsym = hTabNextItem (liveRanges, &k))
1506 /* if no registers assigned to it or
1508 /* if it does not overlap with this then
1509 not need to spill it */
1511 if (lrsym->isspilt || !lrsym->nRegs ||
1512 (lrsym->liveTo < forSym->liveFrom))
1515 /* go thru the registers : if it is either
1516 r0 or r1 then spil it */
1517 for (j = 0; j < lrsym->nRegs; j++)
1518 if (lrsym->regs[j] == r0 ||
1519 lrsym->regs[j] == r1)
1528 /*-----------------------------------------------------------------*/
1529 /* createStackSpil - create a location on the stack to spil */
1530 /*-----------------------------------------------------------------*/
1532 createStackSpil (symbol * sym)
1534 symbol *sloc = NULL;
1535 int useXstack, model, noOverlay;
1537 char slocBuffer[30];
1538 debugLog ("%s\n", __FUNCTION__);
1540 /* first go try and find a free one that is already
1541 existing on the stack */
1542 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1544 /* found a free one : just update & return */
1545 sym->usl.spillLoc = sloc;
1548 addSetHead (&sloc->usl.itmpStack, sym);
1552 /* could not then have to create one , this is the hard part
1553 we need to allocate this on the stack : this is really a
1554 hack!! but cannot think of anything better at this time */
1556 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1558 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1559 __FILE__, __LINE__);
1563 sloc = newiTemp (slocBuffer);
1565 /* set the type to the spilling symbol */
1566 sloc->type = copyLinkChain (sym->type);
1567 sloc->etype = getSpec (sloc->type);
1568 SPEC_SCLS (sloc->etype) = S_DATA;
1569 SPEC_EXTR (sloc->etype) = 0;
1570 SPEC_STAT (sloc->etype) = 0;
1572 /* we don't allow it to be allocated`
1573 onto the external stack since : so we
1574 temporarily turn it off ; we also
1575 turn off memory model to prevent
1576 the spil from going to the external storage
1577 and turn off overlaying
1580 useXstack = options.useXstack;
1581 model = options.model;
1582 noOverlay = options.noOverlay;
1583 options.noOverlay = 1;
1584 options.model = options.useXstack = 0;
1588 options.useXstack = useXstack;
1589 options.model = model;
1590 options.noOverlay = noOverlay;
1591 sloc->isref = 1; /* to prevent compiler warning */
1593 /* if it is on the stack then update the stack */
1594 if (IN_STACK (sloc->etype))
1596 currFunc->stack += getSize (sloc->type);
1597 _G.stackExtend += getSize (sloc->type);
1600 _G.dataExtend += getSize (sloc->type);
1602 /* add it to the _G.stackSpil set */
1603 addSetHead (&_G.stackSpil, sloc);
1604 sym->usl.spillLoc = sloc;
1607 /* add it to the set of itempStack set
1608 of the spill location */
1609 addSetHead (&sloc->usl.itmpStack, sym);
1613 /*-----------------------------------------------------------------*/
1614 /* isSpiltOnStack - returns true if the spil location is on stack */
1615 /*-----------------------------------------------------------------*/
1617 isSpiltOnStack (symbol * sym)
1621 debugLog ("%s\n", __FUNCTION__);
1628 /* if (sym->_G.stackSpil) */
1631 if (!sym->usl.spillLoc)
1634 etype = getSpec (sym->usl.spillLoc->type);
1635 if (IN_STACK (etype))
1641 /*-----------------------------------------------------------------*/
1642 /* spillThis - spils a specific operand */
1643 /*-----------------------------------------------------------------*/
1645 spillThis (symbol * sym)
1648 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1650 /* if this is rematerializable or has a spillLocation
1651 we are okay, else we need to create a spillLocation
1653 if (!(sym->remat || sym->usl.spillLoc))
1654 createStackSpil (sym);
1657 /* mark it has spilt & put it in the spilt set */
1659 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1661 bitVectUnSetBit (_G.regAssigned, sym->key);
1663 for (i = 0; i < sym->nRegs; i++)
1667 freeReg (sym->regs[i]);
1668 sym->regs[i] = NULL;
1671 /* if spilt on stack then free up r0 & r1
1672 if they could have been assigned to some
1674 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1677 spillLRWithPtrReg (sym);
1680 if (sym->usl.spillLoc && !sym->remat)
1681 sym->usl.spillLoc->allocreq = 1;
1685 /*-----------------------------------------------------------------*/
1686 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1687 /*-----------------------------------------------------------------*/
1689 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1691 bitVect *lrcs = NULL;
1695 debugLog ("%s\n", __FUNCTION__);
1696 /* get the spillable live ranges */
1697 lrcs = computeSpillable (ic);
1699 /* get all live ranges that are rematerizable */
1700 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1703 /* return the least used of these */
1704 return leastUsedLR (selectS);
1707 /* get live ranges with spillLocations in direct space */
1708 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1710 sym = leastUsedLR (selectS);
1711 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1712 sym->usl.spillLoc->rname :
1713 sym->usl.spillLoc->name));
1715 /* mark it as allocation required */
1716 sym->usl.spillLoc->allocreq = 1;
1720 /* if the symbol is local to the block then */
1721 if (forSym->liveTo < ebp->lSeq)
1724 /* check if there are any live ranges allocated
1725 to registers that are not used in this block */
1726 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1728 sym = leastUsedLR (selectS);
1729 /* if this is not rematerializable */
1738 /* check if there are any live ranges that not
1739 used in the remainder of the block */
1740 if (!_G.blockSpil &&
1741 !isiCodeInFunctionCall (ic) &&
1742 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1744 sym = leastUsedLR (selectS);
1747 sym->remainSpil = 1;
1754 /* find live ranges with spillocation && not used as pointers */
1755 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1758 sym = leastUsedLR (selectS);
1759 /* mark this as allocation required */
1760 sym->usl.spillLoc->allocreq = 1;
1764 /* find live ranges with spillocation */
1765 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1768 sym = leastUsedLR (selectS);
1769 sym->usl.spillLoc->allocreq = 1;
1773 /* couldn't find then we need to create a spil
1774 location on the stack , for which one? the least
1776 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1779 /* return a created spil location */
1780 sym = createStackSpil (leastUsedLR (selectS));
1781 sym->usl.spillLoc->allocreq = 1;
1785 /* this is an extreme situation we will spill
1786 this one : happens very rarely but it does happen */
1792 /*-----------------------------------------------------------------*/
1793 /* spilSomething - spil some variable & mark registers as free */
1794 /*-----------------------------------------------------------------*/
1796 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1801 debugLog ("%s\n", __FUNCTION__);
1802 /* get something we can spil */
1803 ssym = selectSpil (ic, ebp, forSym);
1805 /* mark it as spilt */
1807 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1809 /* mark it as not register assigned &
1810 take it away from the set */
1811 bitVectUnSetBit (_G.regAssigned, ssym->key);
1813 /* mark the registers as free */
1814 for (i = 0; i < ssym->nRegs; i++)
1816 freeReg (ssym->regs[i]);
1818 /* if spilt on stack then free up r0 & r1
1819 if they could have been assigned to as gprs */
1820 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1823 spillLRWithPtrReg (ssym);
1826 /* if this was a block level spil then insert push & pop
1827 at the start & end of block respectively */
1828 if (ssym->blockSpil)
1830 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1831 /* add push to the start of the block */
1832 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1833 ebp->sch->next : ebp->sch));
1834 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1835 /* add pop to the end of the block */
1836 addiCodeToeBBlock (ebp, nic, NULL);
1839 /* if spilt because not used in the remainder of the
1840 block then add a push before this instruction and
1841 a pop at the end of the block */
1842 if (ssym->remainSpil)
1845 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1846 /* add push just before this instruction */
1847 addiCodeToeBBlock (ebp, nic, ic);
1849 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1850 /* add pop to the end of the block */
1851 addiCodeToeBBlock (ebp, nic, NULL);
1860 /*-----------------------------------------------------------------*/
1861 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1862 /*-----------------------------------------------------------------*/
1864 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1869 debugLog ("%s\n", __FUNCTION__);
1871 /* try for a ptr type */
1872 if ((reg = allocReg (REG_PTR)))
1875 /* try for gpr type */
1876 if ((reg = allocReg (REG_GPR)))
1879 /* we have to spil */
1880 if (!spilSomething (ic, ebp, sym))
1883 /* make sure partially assigned registers aren't reused */
1884 for (j=0; j<=sym->nRegs; j++)
1886 sym->regs[j]->isFree = 0;
1888 /* this looks like an infinite loop but
1889 in really selectSpil will abort */
1893 /*-----------------------------------------------------------------*/
1894 /* getRegGpr - will try for GPR if not spil */
1895 /*-----------------------------------------------------------------*/
1897 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1902 debugLog ("%s\n", __FUNCTION__);
1904 /* try for gpr type */
1905 if ((reg = allocReg (REG_GPR)))
1908 if (!pic16_ptrRegReq)
1909 if ((reg = allocReg (REG_PTR)))
1912 /* we have to spil */
1913 if (!spilSomething (ic, ebp, sym))
1916 /* make sure partially assigned registers aren't reused */
1917 for (j=0; j<=sym->nRegs; j++)
1919 sym->regs[j]->isFree = 0;
1921 /* this looks like an infinite loop but
1922 in really selectSpil will abort */
1926 /*-----------------------------------------------------------------*/
1927 /* symHasReg - symbol has a given register */
1928 /*-----------------------------------------------------------------*/
1930 symHasReg (symbol * sym, regs * reg)
1934 debugLog ("%s\n", __FUNCTION__);
1935 for (i = 0; i < sym->nRegs; i++)
1936 if (sym->regs[i] == reg)
1942 /*-----------------------------------------------------------------*/
1943 /* deassignLRs - check the live to and if they have registers & are */
1944 /* not spilt then free up the registers */
1945 /*-----------------------------------------------------------------*/
1947 deassignLRs (iCode * ic, eBBlock * ebp)
1953 debugLog ("%s\n", __FUNCTION__);
1954 for (sym = hTabFirstItem (liveRanges, &k); sym;
1955 sym = hTabNextItem (liveRanges, &k))
1958 symbol *psym = NULL;
1959 /* if it does not end here */
1960 if (sym->liveTo > ic->seq)
1963 /* if it was spilt on stack then we can
1964 mark the stack spil location as free */
1969 sym->usl.spillLoc->isFree = 1;
1975 if (!bitVectBitValue (_G.regAssigned, sym->key))
1978 /* special case for shifting: there is a case where shift count
1979 * can be allocated in the same register as the result, so do not
1980 * free right registers if same as result registers, cause genShiftLeft
1981 * will fail -- VR */
1982 if(ic->op == LEFT_OP)
1985 /* special case check if this is an IFX &
1986 the privious one was a pop and the
1987 previous one was not spilt then keep track
1989 if (ic->op == IFX && ic->prev &&
1990 ic->prev->op == IPOP &&
1991 !ic->prev->parmPush &&
1992 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1993 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1999 bitVectUnSetBit (_G.regAssigned, sym->key);
2001 /* if the result of this one needs registers
2002 and does not have it then assign it right
2004 if (IC_RESULT (ic) &&
2005 !(SKIP_IC2 (ic) || /* not a special icode */
2006 ic->op == JUMPTABLE ||
2011 POINTER_SET (ic)) &&
2012 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2013 result->liveTo > ic->seq && /* and will live beyond this */
2014 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2015 result->liveFrom == ic->seq && /* does not start before here */
2016 result->regType == sym->regType && /* same register types */
2017 result->nRegs && /* which needs registers */
2018 !result->isspilt && /* and does not already have them */
2020 !bitVectBitValue (_G.regAssigned, result->key) &&
2021 /* the number of free regs + number of regs in this LR
2022 can accomodate the what result Needs */
2023 ((nfreeRegsType (result->regType) +
2024 sym->nRegs) >= result->nRegs)
2028 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2030 result->regs[i] = sym->regs[i];
2032 result->regs[i] = getRegGpr (ic, ebp, result);
2034 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2038 /* free the remaining */
2039 for (; i < sym->nRegs; i++)
2043 if (!symHasReg (psym, sym->regs[i]))
2044 freeReg (sym->regs[i]);
2047 freeReg (sym->regs[i]);
2054 /*-----------------------------------------------------------------*/
2055 /* reassignLR - reassign this to registers */
2056 /*-----------------------------------------------------------------*/
2058 reassignLR (operand * op)
2060 symbol *sym = OP_SYMBOL (op);
2063 debugLog ("%s\n", __FUNCTION__);
2064 /* not spilt any more */
2065 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2066 bitVectUnSetBit (_G.spiltSet, sym->key);
2068 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2072 for (i = 0; i < sym->nRegs; i++)
2073 sym->regs[i]->isFree = 0;
2076 /*-----------------------------------------------------------------*/
2077 /* willCauseSpill - determines if allocating will cause a spill */
2078 /*-----------------------------------------------------------------*/
2080 willCauseSpill (int nr, int rt)
2082 debugLog ("%s\n", __FUNCTION__);
2083 /* first check if there are any avlb registers
2084 of te type required */
2087 /* special case for pointer type
2088 if pointer type not avlb then
2089 check for type gpr */
2090 if (nFreeRegs (rt) >= nr)
2092 if (nFreeRegs (REG_GPR) >= nr)
2097 if (pic16_ptrRegReq)
2099 if (nFreeRegs (rt) >= nr)
2104 if (nFreeRegs (REG_PTR) +
2105 nFreeRegs (REG_GPR) >= nr)
2110 debugLog (" ... yep it will (cause a spill)\n");
2111 /* it will cause a spil */
2115 /*-----------------------------------------------------------------*/
2116 /* positionRegs - the allocator can allocate same registers to res- */
2117 /* ult and operand, if this happens make sure they are in the same */
2118 /* position as the operand otherwise chaos results */
2119 /*-----------------------------------------------------------------*/
2121 positionRegs (symbol * result, symbol * opsym, int lineno)
2123 int count = min (result->nRegs, opsym->nRegs);
2124 int i, j = 0, shared = 0;
2126 debugLog ("%s\n", __FUNCTION__);
2127 /* if the result has been spilt then cannot share */
2132 /* first make sure that they actually share */
2133 for (i = 0; i < count; i++)
2135 for (j = 0; j < count; j++)
2137 if (result->regs[i] == opsym->regs[j] && i != j)
2147 regs *tmp = result->regs[i];
2148 result->regs[i] = result->regs[j];
2149 result->regs[j] = tmp;
2154 /*------------------------------------------------------------------*/
2155 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2156 /* it should either have registers or have beed spilled. Otherwise, */
2157 /* there was an uninitialized variable, so just spill this to get */
2158 /* the operand in a valid state. */
2159 /*------------------------------------------------------------------*/
2161 verifyRegsAssigned (operand *op, iCode * ic)
2166 if (!IS_ITEMP (op)) return;
2168 sym = OP_SYMBOL (op);
2169 if (sym->isspilt) return;
2170 if (!sym->nRegs) return;
2171 if (sym->regs[0]) return;
2173 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2174 sym->prereqv ? sym->prereqv->name : sym->name);
2179 /*-----------------------------------------------------------------*/
2180 /* serialRegAssign - serially allocate registers to the variables */
2181 /*-----------------------------------------------------------------*/
2183 serialRegAssign (eBBlock ** ebbs, int count)
2187 debugLog ("%s\n", __FUNCTION__);
2188 /* for all blocks */
2189 for (i = 0; i < count; i++)
2194 if (ebbs[i]->noPath &&
2195 (ebbs[i]->entryLabel != entryLabel &&
2196 ebbs[i]->entryLabel != returnLabel))
2199 /* of all instructions do */
2200 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2203 debugLog (" op: %s\n", decodeOp (ic->op));
2205 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2206 pic16_allocDirReg(IC_RESULT(ic));
2208 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2209 pic16_allocDirReg(IC_LEFT(ic));
2211 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2212 pic16_allocDirReg(IC_RIGHT(ic));
2214 /* if this is an ipop that means some live
2215 range will have to be assigned again */
2217 reassignLR (IC_LEFT (ic));
2219 /* if result is present && is a true symbol */
2220 if (IC_RESULT (ic) && ic->op != IFX &&
2221 IS_TRUE_SYMOP (IC_RESULT (ic)))
2222 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2224 /* take away registers from live
2225 ranges that end at this instruction */
2226 deassignLRs (ic, ebbs[i]);
2228 /* some don't need registers */
2229 if (SKIP_IC2 (ic) ||
2230 ic->op == JUMPTABLE ||
2234 (IC_RESULT (ic) && POINTER_SET (ic)))
2237 /* now we need to allocate registers
2238 only for the result */
2241 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2247 /* if it does not need or is spilt
2248 or is already assigned to registers
2249 or will not live beyond this instructions */
2252 bitVectBitValue (_G.regAssigned, sym->key) ||
2253 sym->liveTo <= ic->seq)
2256 /* if some liverange has been spilt at the block level
2257 and this one live beyond this block then spil this
2259 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2264 /* if trying to allocate this will cause
2265 a spill and there is nothing to spill
2266 or this one is rematerializable then
2268 willCS = willCauseSpill (sym->nRegs, sym->regType);
2269 spillable = computeSpillable (ic);
2271 (willCS && bitVectIsZero (spillable)))
2279 /* If the live range preceeds the point of definition
2280 then ideally we must take into account registers that
2281 have been allocated after sym->liveFrom but freed
2282 before ic->seq. This is complicated, so spill this
2283 symbol instead and let fillGaps handle the allocation. */
2284 if (sym->liveFrom < ic->seq)
2290 /* if it has a spillocation & is used less than
2291 all other live ranges then spill this */
2293 if (sym->usl.spillLoc) {
2294 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2295 allLRs, ebbs[i], ic));
2296 if (leastUsed && leastUsed->used > sym->used) {
2301 /* if none of the liveRanges have a spillLocation then better
2302 to spill this one than anything else already assigned to registers */
2303 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2304 /* if this is local to this block then we might find a block spil */
2305 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2313 if (ic->op == RECEIVE)
2314 debugLog ("When I get clever, I'll optimize the receive logic\n");
2316 /* if we need ptr regs for the right side
2318 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2319 <= (unsigned) PTRSIZE)
2324 /* else we assign registers to it */
2325 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2327 debugLog (" %d - nRegs: %d\n", __LINE__, sym->nRegs);
2329 bitVectDebugOn(_G.regAssigned, debugF);
2331 for (j = 0; j < sym->nRegs; j++)
2333 if (sym->regType == REG_PTR)
2334 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2336 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2338 /* if the allocation falied which means
2339 this was spilt then break */
2343 debugLog (" %d - \n", __LINE__);
2345 /* if it shares registers with operands make sure
2346 that they are in the same position */
2347 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2348 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2349 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2350 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2351 /* do the same for the right operand */
2352 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2353 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2354 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2355 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2357 debugLog (" %d - \n", __LINE__);
2360 debugLog (" %d - \n", __LINE__);
2369 /* Check for and fix any problems with uninitialized operands */
2370 for (i = 0; i < count; i++)
2374 if (ebbs[i]->noPath &&
2375 (ebbs[i]->entryLabel != entryLabel &&
2376 ebbs[i]->entryLabel != returnLabel))
2379 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2386 verifyRegsAssigned (IC_COND (ic), ic);
2390 if (ic->op == JUMPTABLE)
2392 verifyRegsAssigned (IC_JTCOND (ic), ic);
2396 verifyRegsAssigned (IC_RESULT (ic), ic);
2397 verifyRegsAssigned (IC_LEFT (ic), ic);
2398 verifyRegsAssigned (IC_RIGHT (ic), ic);
2404 /*-----------------------------------------------------------------*/
2405 /* rUmaskForOp :- returns register mask for an operand */
2406 /*-----------------------------------------------------------------*/
2408 rUmaskForOp (operand * op)
2414 debugLog ("%s\n", __FUNCTION__);
2415 /* only temporaries are assigned registers */
2419 sym = OP_SYMBOL (op);
2421 /* if spilt or no registers assigned to it
2423 if (sym->isspilt || !sym->nRegs)
2426 rumask = newBitVect (pic16_nRegs);
2428 for (j = 0; j < sym->nRegs; j++)
2430 rumask = bitVectSetBit (rumask,
2431 sym->regs[j]->rIdx);
2437 /*-----------------------------------------------------------------*/
2438 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2439 /*-----------------------------------------------------------------*/
2441 regsUsedIniCode (iCode * ic)
2443 bitVect *rmask = newBitVect (pic16_nRegs);
2445 debugLog ("%s\n", __FUNCTION__);
2446 /* do the special cases first */
2449 rmask = bitVectUnion (rmask,
2450 rUmaskForOp (IC_COND (ic)));
2454 /* for the jumptable */
2455 if (ic->op == JUMPTABLE)
2457 rmask = bitVectUnion (rmask,
2458 rUmaskForOp (IC_JTCOND (ic)));
2463 /* of all other cases */
2465 rmask = bitVectUnion (rmask,
2466 rUmaskForOp (IC_LEFT (ic)));
2470 rmask = bitVectUnion (rmask,
2471 rUmaskForOp (IC_RIGHT (ic)));
2474 rmask = bitVectUnion (rmask,
2475 rUmaskForOp (IC_RESULT (ic)));
2481 /*-----------------------------------------------------------------*/
2482 /* createRegMask - for each instruction will determine the regsUsed */
2483 /*-----------------------------------------------------------------*/
2485 createRegMask (eBBlock ** ebbs, int count)
2489 debugLog ("%s\n", __FUNCTION__);
2490 /* for all blocks */
2491 for (i = 0; i < count; i++)
2495 if (ebbs[i]->noPath &&
2496 (ebbs[i]->entryLabel != entryLabel &&
2497 ebbs[i]->entryLabel != returnLabel))
2500 /* for all instructions */
2501 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2506 if (SKIP_IC2 (ic) || !ic->rlive)
2509 /* first mark the registers used in this
2511 ic->rUsed = regsUsedIniCode (ic);
2512 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2514 /* now create the register mask for those
2515 registers that are in use : this is a
2516 super set of ic->rUsed */
2517 ic->rMask = newBitVect (pic16_nRegs + 1);
2519 /* for all live Ranges alive at this point */
2520 for (j = 1; j < ic->rlive->size; j++)
2525 /* if not alive then continue */
2526 if (!bitVectBitValue (ic->rlive, j))
2529 /* find the live range we are interested in */
2530 if (!(sym = hTabItemWithKey (liveRanges, j)))
2532 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2533 "createRegMask cannot find live range");
2537 /* if no register assigned to it */
2538 if (!sym->nRegs || sym->isspilt)
2541 /* for all the registers allocated to it */
2542 for (k = 0; k < sym->nRegs; k++)
2545 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2551 /*-----------------------------------------------------------------*/
2552 /* rematStr - returns the rematerialized string for a remat var */
2553 /*-----------------------------------------------------------------*/
2555 rematStr (symbol * sym)
2558 iCode *ic = sym->rematiCode;
2559 symbol *psym = NULL;
2561 debugLog ("%s\n", __FUNCTION__);
2563 //printf ("%s\n", s);
2565 /* if plus or minus print the right hand side */
2567 if (ic->op == '+' || ic->op == '-') {
2569 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2571 sprintf (s, "(%s %c 0x%04x)",
2572 OP_SYMBOL (IC_LEFT (ric))->rname,
2574 (int) operandLitValue (IC_RIGHT (ic)));
2577 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2579 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2580 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2585 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2586 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2588 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2593 /*-----------------------------------------------------------------*/
2594 /* rematStr - returns the rematerialized string for a remat var */
2595 /*-----------------------------------------------------------------*/
2597 rematStr (symbol * sym)
2600 iCode *ic = sym->rematiCode;
2602 debugLog ("%s\n", __FUNCTION__);
2607 /* if plus or minus print the right hand side */
2609 if (ic->op == '+' || ic->op == '-') {
2610 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2613 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2617 if (ic->op == '+' || ic->op == '-')
2619 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2620 sprintf (s, "(%s %c 0x%04x)",
2621 OP_SYMBOL (IC_LEFT (ric))->rname,
2623 (int) operandLitValue (IC_RIGHT (ic)));
2626 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2628 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2632 /* we reached the end */
2633 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2637 printf ("%s\n", buffer);
2642 /*-----------------------------------------------------------------*/
2643 /* regTypeNum - computes the type & number of registers required */
2644 /*-----------------------------------------------------------------*/
2652 debugLog ("%s\n", __FUNCTION__);
2653 /* for each live range do */
2654 for (sym = hTabFirstItem (liveRanges, &k); sym;
2655 sym = hTabNextItem (liveRanges, &k)) {
2657 debugLog (" %d - %s\n", __LINE__, sym->rname);
2658 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2660 /* if used zero times then no registers needed */
2661 if ((sym->liveTo - sym->liveFrom) == 0)
2665 /* if the live range is a temporary */
2668 debugLog (" %d - itemp register\n", __LINE__);
2670 /* if the type is marked as a conditional */
2671 if (sym->regType == REG_CND)
2674 /* if used in return only then we don't
2676 if (sym->ruonly || sym->accuse) {
2677 if (IS_AGGREGATE (sym->type) || sym->isptr)
2678 sym->type = aggrToPtr (sym->type, FALSE);
2679 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2684 /* if the symbol has only one definition &
2685 that definition is a get_pointer and the
2686 pointer we are getting is rematerializable and
2689 if (bitVectnBitsOn (sym->defs) == 1 &&
2690 (ic = hTabItemWithKey (iCodehTab,
2691 bitVectFirstBit (sym->defs))) &&
2693 !IS_BITVAR (sym->etype) &&
2694 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2696 if (ptrPseudoSymSafe (sym, ic)) {
2700 debugLog (" %d - \n", __LINE__);
2702 /* create a psuedo symbol & force a spil */
2703 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2704 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2705 psym->type = sym->type;
2706 psym->etype = sym->etype;
2707 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2708 strcpy (psym->rname, psym->name);
2710 sym->usl.spillLoc = psym;
2714 /* if in data space or idata space then try to
2715 allocate pointer register */
2719 /* if not then we require registers */
2720 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2721 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2722 getSize (sym->type));
2726 if(IS_PTR_CONST (sym->type)) {
2728 if(IS_CODEPTR (sym->type)) {
2730 // what IS this ???? (HJD)
2731 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2732 sym->nRegs = 3; // patch 14
2735 if (sym->nRegs > 4) {
2736 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2737 printTypeChain (sym->type, stderr);
2738 fprintf (stderr, "\n");
2741 /* determine the type of register required */
2742 if (sym->nRegs == 1 &&
2743 IS_PTR (sym->type) &&
2745 sym->regType = REG_PTR;
2747 sym->regType = REG_GPR;
2750 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2754 /* for the first run we don't provide */
2755 /* registers for true symbols we will */
2756 /* see how things go */
2761 static DEFSETFUNC (markRegFree)
2763 ((regs *)item)->isFree = 1;
2768 DEFSETFUNC (pic16_deallocReg)
2770 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2771 ((regs *)item)->isFree = 1;
2772 ((regs *)item)->wasUsed = 0;
2776 /*-----------------------------------------------------------------*/
2777 /* freeAllRegs - mark all registers as free */
2778 /*-----------------------------------------------------------------*/
2780 pic16_freeAllRegs ()
2782 debugLog ("%s\n", __FUNCTION__);
2784 applyToSet(pic16_dynAllocRegs,markRegFree);
2785 applyToSet(pic16_dynStackRegs,markRegFree);
2788 /*-----------------------------------------------------------------*/
2789 /*-----------------------------------------------------------------*/
2791 pic16_deallocateAllRegs ()
2793 debugLog ("%s\n", __FUNCTION__);
2795 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2799 /*-----------------------------------------------------------------*/
2800 /* deallocStackSpil - this will set the stack pointer back */
2801 /*-----------------------------------------------------------------*/
2803 DEFSETFUNC (deallocStackSpil)
2807 debugLog ("%s\n", __FUNCTION__);
2812 /*-----------------------------------------------------------------*/
2813 /* farSpacePackable - returns the packable icode for far variables */
2814 /*-----------------------------------------------------------------*/
2816 farSpacePackable (iCode * ic)
2820 debugLog ("%s\n", __FUNCTION__);
2821 /* go thru till we find a definition for the
2822 symbol on the right */
2823 for (dic = ic->prev; dic; dic = dic->prev)
2826 /* if the definition is a call then no */
2827 if ((dic->op == CALL || dic->op == PCALL) &&
2828 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2833 /* if shift by unknown amount then not */
2834 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2835 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2838 /* if pointer get and size > 1 */
2839 if (POINTER_GET (dic) &&
2840 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2843 if (POINTER_SET (dic) &&
2844 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2847 /* if any three is a true symbol in far space */
2848 if (IC_RESULT (dic) &&
2849 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2850 isOperandInFarSpace (IC_RESULT (dic)))
2853 if (IC_RIGHT (dic) &&
2854 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2855 isOperandInFarSpace (IC_RIGHT (dic)) &&
2856 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2859 if (IC_LEFT (dic) &&
2860 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2861 isOperandInFarSpace (IC_LEFT (dic)) &&
2862 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2865 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2867 if ((dic->op == LEFT_OP ||
2868 dic->op == RIGHT_OP ||
2870 IS_OP_LITERAL (IC_RIGHT (dic)))
2880 /*-----------------------------------------------------------------*/
2881 /* packRegsForAssign - register reduction for assignment */
2882 /*-----------------------------------------------------------------*/
2884 packRegsForAssign (iCode * ic, eBBlock * ebp)
2889 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2890 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2891 debugAopGet (" result:", IC_RESULT (ic));
2892 debugAopGet (" left:", IC_LEFT (ic));
2893 debugAopGet (" right:", IC_RIGHT (ic));
2895 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2897 debugLog(" %d - actuall processing\n", __LINE__ );
2899 if (!IS_ITEMP (IC_RESULT (ic))) {
2900 pic16_allocDirReg(IC_RESULT (ic));
2901 debugLog (" %d - result is not temp\n", __LINE__);
2905 /* See BUGLOG0001 - VR */
2907 if (!IS_ITEMP (IC_RIGHT (ic))) {
2908 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2909 pic16_allocDirReg(IC_RIGHT (ic));
2914 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2915 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2917 debugLog (" %d - not packing - right side fails \n", __LINE__);
2921 /* if the true symbol is defined in far space or on stack
2922 then we should not since this will increase register pressure */
2923 if (isOperandInFarSpace (IC_RESULT (ic)))
2925 if ((dic = farSpacePackable (ic)))
2932 /* find the definition of iTempNN scanning backwards if we find a
2933 a use of the true symbol before we find the definition then
2935 for (dic = ic->prev; dic; dic = dic->prev)
2938 /* if there is a function call and this is
2939 a parameter & not my parameter then don't pack it */
2940 if ((dic->op == CALL || dic->op == PCALL) &&
2941 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2942 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2944 debugLog (" %d - \n", __LINE__);
2953 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2955 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2956 IS_OP_VOLATILE (IC_RESULT (dic)))
2958 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2964 if( IS_SYMOP( IC_RESULT(dic)) &&
2965 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2967 debugLog (" %d - result is bitfield\n", __LINE__);
2973 if (IS_SYMOP (IC_RESULT (dic)) &&
2974 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2976 /* A previous result was assigned to the same register - we'll our definition */
2977 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2978 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2979 if (POINTER_SET (dic))
2985 if (IS_SYMOP (IC_RIGHT (dic)) &&
2986 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2987 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2989 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2994 if (IS_SYMOP (IC_LEFT (dic)) &&
2995 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2996 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2998 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3003 if (POINTER_SET (dic) &&
3004 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3006 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3014 return 0; /* did not find */
3017 /* This code is taken from the hc08 port. Do not know
3018 * if it fits for pic16, but I leave it here just in case */
3020 /* if assignment then check that right is not a bit */
3021 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3022 sym_link *etype = operandType (IC_RIGHT (dic));
3024 if (IS_BITFIELD (etype)) {
3025 /* if result is a bit too then it's ok */
3026 etype = operandType (IC_RESULT (dic));
3027 if (!IS_BITFIELD (etype)) {
3028 debugLog(" %d bitfields\n");
3035 /* if the result is on stack or iaccess then it must be
3036 the same atleast one of the operands */
3037 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3038 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3040 /* the operation has only one symbol
3041 operator then we can pack */
3042 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3043 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3046 if (!((IC_LEFT (dic) &&
3047 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3049 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3053 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3054 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3055 /* found the definition */
3056 /* replace the result with the result of */
3057 /* this assignment and remove this assignment */
3058 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3059 IC_RESULT (dic) = IC_RESULT (ic);
3061 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3063 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3065 /* delete from liverange table also
3066 delete from all the points inbetween and the new
3068 for (sic = dic; sic != ic; sic = sic->next)
3070 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3071 if (IS_ITEMP (IC_RESULT (dic)))
3072 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3075 remiCodeFromeBBlock (ebp, ic);
3076 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3078 debugLog(" %d\n", __LINE__ );
3079 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3080 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3088 #define NO_packRegsForAccUse
3089 #define NO_packRegsForSupport
3090 #define NO_packRegsForOneuse
3091 #define NO_cast_peep
3096 #ifndef NO_packRegsForSupport
3097 /*-----------------------------------------------------------------*/
3098 /* findAssignToSym : scanning backwards looks for first assig found */
3099 /*-----------------------------------------------------------------*/
3101 findAssignToSym (operand * op, iCode * ic)
3105 debugLog ("%s\n", __FUNCTION__);
3106 for (dic = ic->prev; dic; dic = dic->prev)
3109 /* if definition by assignment */
3110 if (dic->op == '=' &&
3111 !POINTER_SET (dic) &&
3112 IC_RESULT (dic)->key == op->key
3113 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3117 /* we are interested only if defined in far space */
3118 /* or in stack space in case of + & - */
3120 /* if assigned to a non-symbol then return
3122 if (!IS_SYMOP (IC_RIGHT (dic)))
3125 /* if the symbol is in far space then
3127 if (isOperandInFarSpace (IC_RIGHT (dic)))
3130 /* for + & - operations make sure that
3131 if it is on the stack it is the same
3132 as one of the three operands */
3133 if ((ic->op == '+' || ic->op == '-') &&
3134 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3136 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3137 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3138 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3146 /* if we find an usage then we cannot delete it */
3147 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3150 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3153 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3157 /* now make sure that the right side of dic
3158 is not defined between ic & dic */
3161 iCode *sic = dic->next;
3163 for (; sic != ic; sic = sic->next)
3164 if (IC_RESULT (sic) &&
3165 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3176 #ifndef NO_packRegsForSupport
3177 /*-----------------------------------------------------------------*/
3178 /* packRegsForSupport :- reduce some registers for support calls */
3179 /*-----------------------------------------------------------------*/
3181 packRegsForSupport (iCode * ic, eBBlock * ebp)
3185 debugLog ("%s\n", __FUNCTION__);
3186 /* for the left & right operand :- look to see if the
3187 left was assigned a true symbol in far space in that
3188 case replace them */
3189 if (IS_ITEMP (IC_LEFT (ic)) &&
3190 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3192 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3198 debugAopGet ("removing left:", IC_LEFT (ic));
3200 /* found it we need to remove it from the
3202 for (sic = dic; sic != ic; sic = sic->next)
3203 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3205 IC_LEFT (ic)->operand.symOperand =
3206 IC_RIGHT (dic)->operand.symOperand;
3207 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3208 remiCodeFromeBBlock (ebp, dic);
3209 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3210 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3214 /* do the same for the right operand */
3217 IS_ITEMP (IC_RIGHT (ic)) &&
3218 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3220 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3226 /* if this is a subtraction & the result
3227 is a true symbol in far space then don't pack */
3228 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3230 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3231 if (IN_FARSPACE (SPEC_OCLS (etype)))
3235 debugAopGet ("removing right:", IC_RIGHT (ic));
3237 /* found it we need to remove it from the
3239 for (sic = dic; sic != ic; sic = sic->next)
3240 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3242 IC_RIGHT (ic)->operand.symOperand =
3243 IC_RIGHT (dic)->operand.symOperand;
3244 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3246 remiCodeFromeBBlock (ebp, dic);
3247 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3248 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3257 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3259 #ifndef NO_packRegsForOneuse
3260 /*-----------------------------------------------------------------*/
3261 /* packRegsForOneuse : - will reduce some registers for single Use */
3262 /*-----------------------------------------------------------------*/
3264 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3269 debugLog ("%s\n", __FUNCTION__);
3270 /* if returning a literal then do nothing */
3274 /* only upto 2 bytes since we cannot predict
3275 the usage of b, & acc */
3276 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3281 /* this routine will mark the a symbol as used in one
3282 instruction use only && if the definition is local
3283 (ie. within the basic block) && has only one definition &&
3284 that definition is either a return value from a
3285 function or does not contain any variables in
3287 uses = bitVectCopy (OP_USES (op));
3288 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3289 if (!bitVectIsZero (uses)) /* has other uses */
3292 /* if it has only one defintion */
3293 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3294 return NULL; /* has more than one definition */
3296 /* get that definition */
3298 hTabItemWithKey (iCodehTab,
3299 bitVectFirstBit (OP_DEFS (op)))))
3302 /* found the definition now check if it is local */
3303 if (dic->seq < ebp->fSeq ||
3304 dic->seq > ebp->lSeq)
3305 return NULL; /* non-local */
3307 /* now check if it is the return from
3309 if (dic->op == CALL || dic->op == PCALL)
3311 if (ic->op != SEND && ic->op != RETURN &&
3312 !POINTER_SET(ic) && !POINTER_GET(ic))
3314 OP_SYMBOL (op)->ruonly = 1;
3321 /* otherwise check that the definition does
3322 not contain any symbols in far space */
3323 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3324 isOperandInFarSpace (IC_RIGHT (dic)) ||
3325 IS_OP_RUONLY (IC_LEFT (ic)) ||
3326 IS_OP_RUONLY (IC_RIGHT (ic)))
3331 /* if pointer set then make sure the pointer
3333 if (POINTER_SET (dic) &&
3334 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3337 if (POINTER_GET (dic) &&
3338 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3343 /* also make sure the intervenening instructions
3344 don't have any thing in far space */
3345 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3348 /* if there is an intervening function call then no */
3349 if (dic->op == CALL || dic->op == PCALL)
3351 /* if pointer set then make sure the pointer
3353 if (POINTER_SET (dic) &&
3354 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3357 if (POINTER_GET (dic) &&
3358 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3361 /* if address of & the result is remat then okay */
3362 if (dic->op == ADDRESS_OF &&
3363 OP_SYMBOL (IC_RESULT (dic))->remat)
3366 /* if operand has size of three or more & this
3367 operation is a '*','/' or '%' then 'b' may
3369 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3370 getSize (operandType (op)) >= 3)
3373 /* if left or right or result is in far space */
3374 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3375 isOperandInFarSpace (IC_RIGHT (dic)) ||
3376 isOperandInFarSpace (IC_RESULT (dic)) ||
3377 IS_OP_RUONLY (IC_LEFT (dic)) ||
3378 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3379 IS_OP_RUONLY (IC_RESULT (dic)))
3385 OP_SYMBOL (op)->ruonly = 1;
3392 /*-----------------------------------------------------------------*/
3393 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3394 /*-----------------------------------------------------------------*/
3396 isBitwiseOptimizable (iCode * ic)
3398 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3399 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3401 debugLog ("%s\n", __FUNCTION__);
3402 /* bitwise operations are considered optimizable
3403 under the following conditions (Jean-Louis VERN)
3415 if (IS_LITERAL (rtype) ||
3416 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3423 #ifndef NO_packRegsForAccUse
3425 /*-----------------------------------------------------------------*/
3426 /* packRegsForAccUse - pack registers for acc use */
3427 /*-----------------------------------------------------------------*/
3429 packRegsForAccUse (iCode * ic)
3433 debugLog ("%s\n", __FUNCTION__);
3435 /* if this is an aggregate, e.g. a one byte char array */
3436 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3439 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3441 /* if + or - then it has to be one byte result */
3442 if ((ic->op == '+' || ic->op == '-')
3443 && getSize (operandType (IC_RESULT (ic))) > 1)
3446 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3447 /* if shift operation make sure right side is not a literal */
3448 if (ic->op == RIGHT_OP &&
3449 (isOperandLiteral (IC_RIGHT (ic)) ||
3450 getSize (operandType (IC_RESULT (ic))) > 1))
3453 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3454 if (ic->op == LEFT_OP &&
3455 (isOperandLiteral (IC_RIGHT (ic)) ||
3456 getSize (operandType (IC_RESULT (ic))) > 1))
3459 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3460 if (IS_BITWISE_OP (ic) &&
3461 getSize (operandType (IC_RESULT (ic))) > 1)
3465 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3466 /* has only one definition */
3467 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3470 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3471 /* has only one use */
3472 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3475 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3476 /* and the usage immediately follows this iCode */
3477 if (!(uic = hTabItemWithKey (iCodehTab,
3478 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3481 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3482 if (ic->next != uic)
3485 /* if it is a conditional branch then we definitely can */
3489 if (uic->op == JUMPTABLE)
3492 /* if the usage is not is an assignment
3493 or an arithmetic / bitwise / shift operation then not */
3494 if (POINTER_SET (uic) &&
3495 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3498 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3499 if (uic->op != '=' &&
3500 !IS_ARITHMETIC_OP (uic) &&
3501 !IS_BITWISE_OP (uic) &&
3502 uic->op != LEFT_OP &&
3503 uic->op != RIGHT_OP)
3506 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3507 /* if used in ^ operation then make sure right is not a
3509 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3512 /* if shift operation make sure right side is not a literal */
3513 if (uic->op == RIGHT_OP &&
3514 (isOperandLiteral (IC_RIGHT (uic)) ||
3515 getSize (operandType (IC_RESULT (uic))) > 1))
3518 if (uic->op == LEFT_OP &&
3519 (isOperandLiteral (IC_RIGHT (uic)) ||
3520 getSize (operandType (IC_RESULT (uic))) > 1))
3523 /* make sure that the result of this icode is not on the
3524 stack, since acc is used to compute stack offset */
3525 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3526 OP_SYMBOL (IC_RESULT (uic))->onStack)
3529 /* if either one of them in far space then we cannot */
3530 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3531 isOperandInFarSpace (IC_LEFT (uic))) ||
3532 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3533 isOperandInFarSpace (IC_RIGHT (uic))))
3536 /* if the usage has only one operand then we can */
3537 if (IC_LEFT (uic) == NULL ||
3538 IC_RIGHT (uic) == NULL)
3541 /* make sure this is on the left side if not
3542 a '+' since '+' is commutative */
3543 if (ic->op != '+' &&
3544 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3548 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3549 /* if one of them is a literal then we can */
3550 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3551 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3552 (getSize (operandType (IC_RESULT (uic))) <= 1))
3554 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3559 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3560 /* if the other one is not on stack then we can */
3561 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3562 (IS_ITEMP (IC_RIGHT (uic)) ||
3563 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3564 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3567 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3568 (IS_ITEMP (IC_LEFT (uic)) ||
3569 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3570 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3576 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3577 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3584 /*-----------------------------------------------------------------*/
3585 /* packForPush - hueristics to reduce iCode for pushing */
3586 /*-----------------------------------------------------------------*/
3588 packForReceive (iCode * ic, eBBlock * ebp)
3592 debugLog ("%s\n", __FUNCTION__);
3593 debugAopGet (" result:", IC_RESULT (ic));
3594 debugAopGet (" left:", IC_LEFT (ic));
3595 debugAopGet (" right:", IC_RIGHT (ic));
3600 for (dic = ic->next; dic; dic = dic->next)
3605 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3606 debugLog (" used on left\n");
3607 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3608 debugLog (" used on right\n");
3609 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3610 debugLog (" used on result\n");
3612 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3613 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3618 debugLog (" hey we can remove this unnecessary assign\n");
3620 /*-----------------------------------------------------------------*/
3621 /* packForPush - hueristics to reduce iCode for pushing */
3622 /*-----------------------------------------------------------------*/
3624 packForPush (iCode * ic, eBBlock * ebp)
3628 debugLog ("%s\n", __FUNCTION__);
3629 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3632 /* must have only definition & one usage */
3633 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3634 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3637 /* find the definition */
3638 if (!(dic = hTabItemWithKey (iCodehTab,
3639 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3642 if (dic->op != '=' || POINTER_SET (dic))
3645 /* we now we know that it has one & only one def & use
3646 and the that the definition is an assignment */
3647 IC_LEFT (ic) = IC_RIGHT (dic);
3649 remiCodeFromeBBlock (ebp, dic);
3650 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3651 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3654 static void printSymType(char * str, sym_link *sl)
3656 if(!pic16_ralloc_debug)return;
3658 debugLog (" %s Symbol type: ",str);
3659 printTypeChain( sl, debugF);
3663 /*-----------------------------------------------------------------*/
3664 /* some debug code to print the symbol S_TYPE. Note that
3665 * the function checkSClass in src/SDCCsymt.c dinks with
3666 * the S_TYPE in ways the PIC port doesn't fully like...*/
3667 /*-----------------------------------------------------------------*/
3668 static void isData(sym_link *sl)
3672 if(!pic16_ralloc_debug)return;
3679 for ( ; sl; sl=sl->next) {
3681 switch (SPEC_SCLS(sl)) {
3682 case S_DATA: fprintf (of, "data "); break;
3683 case S_XDATA: fprintf (of, "xdata "); break;
3684 case S_SFR: fprintf (of, "sfr "); break;
3685 case S_SBIT: fprintf (of, "sbit "); break;
3686 case S_CODE: fprintf (of, "code "); break;
3687 case S_IDATA: fprintf (of, "idata "); break;
3688 case S_PDATA: fprintf (of, "pdata "); break;
3689 case S_LITERAL: fprintf (of, "literal "); break;
3690 case S_STACK: fprintf (of, "stack "); break;
3691 case S_XSTACK: fprintf (of, "xstack "); break;
3692 case S_BIT: fprintf (of, "bit "); break;
3693 case S_EEPROM: fprintf (of, "eeprom "); break;
3702 /*--------------------------------------------------------------------*/
3703 /* pic16_packRegisters - does some transformations to reduce */
3704 /* register pressure */
3706 /*--------------------------------------------------------------------*/
3708 pic16_packRegisters (eBBlock * ebp)
3713 debugLog ("%s\n", __FUNCTION__);
3719 /* look for assignments of the form */
3720 /* iTempNN = TRueSym (someoperation) SomeOperand */
3722 /* TrueSym := iTempNN:1 */
3723 for (ic = ebp->sch; ic; ic = ic->next)
3725 // debugLog("%d\n", __LINE__);
3726 /* find assignment of the form TrueSym := iTempNN:1 */
3727 /* see BUGLOG0001 for workaround with the CAST - VR */
3728 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3729 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3730 change += packRegsForAssign (ic, ebp);
3734 if (POINTER_SET (ic))
3735 debugLog ("pointer is set\n");
3736 debugAopGet (" result:", IC_RESULT (ic));
3737 debugAopGet (" left:", IC_LEFT (ic));
3738 debugAopGet (" right:", IC_RIGHT (ic));
3747 for (ic = ebp->sch; ic; ic = ic->next) {
3749 if(IS_SYMOP ( IC_LEFT(ic))) {
3750 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3752 debugAopGet ("x left:", IC_LEFT (ic));
3754 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3756 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3758 debugLog (" is a pointer\n");
3760 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3761 debugLog (" is a ptr\n");
3763 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3764 debugLog (" is volatile\n");
3768 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3769 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3770 pic16_allocDirReg(IC_LEFT (ic));
3773 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3776 if(IS_SYMOP ( IC_RIGHT(ic))) {
3777 debugAopGet (" right:", IC_RIGHT (ic));
3778 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3781 if(IS_SYMOP ( IC_RESULT(ic))) {
3782 debugAopGet (" result:", IC_RESULT (ic));
3783 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3786 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3787 debugAopGet (" right:", IC_RIGHT (ic));
3788 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3789 // pic16_allocDirReg(IC_RIGHT(ic));
3792 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3793 debugAopGet (" result:", IC_RESULT (ic));
3794 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3795 // pic16_allocDirReg(IC_RESULT(ic));
3799 if (POINTER_SET (ic))
3800 debugLog (" %d - Pointer set\n", __LINE__);
3803 /* if this is an itemp & result of a address of a true sym
3804 then mark this as rematerialisable */
3805 if (ic->op == ADDRESS_OF &&
3806 IS_ITEMP (IC_RESULT (ic)) &&
3807 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3808 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3809 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3812 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3814 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3815 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3816 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3820 /* if straight assignment then carry remat flag if
3821 this is the only definition */
3822 if (ic->op == '=' &&
3823 !POINTER_SET (ic) &&
3824 IS_SYMOP (IC_RIGHT (ic)) &&
3825 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3826 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3828 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3830 OP_SYMBOL (IC_RESULT (ic))->remat =
3831 OP_SYMBOL (IC_RIGHT (ic))->remat;
3832 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3833 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3836 /* if this is a +/- operation with a rematerizable
3837 then mark this as rematerializable as well */
3838 if ((ic->op == '+' || ic->op == '-') &&
3839 (IS_SYMOP (IC_LEFT (ic)) &&
3840 IS_ITEMP (IC_RESULT (ic)) &&
3841 OP_SYMBOL (IC_LEFT (ic))->remat &&
3842 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3843 IS_OP_LITERAL (IC_RIGHT (ic))))
3845 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3847 operandLitValue (IC_RIGHT (ic));
3848 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3849 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3850 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3853 /* mark the pointer usages */
3854 if (POINTER_SET (ic))
3856 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3857 debugLog (" marking as a pointer (set) =>");
3858 debugAopGet (" result:", IC_RESULT (ic));
3860 if (POINTER_GET (ic))
3862 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3863 debugLog (" marking as a pointer (get) =>");
3864 debugAopGet (" left:", IC_LEFT (ic));
3867 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3871 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3872 /* if we are using a symbol on the stack
3873 then we should say pic16_ptrRegReq */
3874 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3875 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3876 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3877 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3878 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3879 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3883 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3884 if (IS_SYMOP (IC_LEFT (ic)))
3885 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3886 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3887 if (IS_SYMOP (IC_RIGHT (ic)))
3888 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3889 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3890 if (IS_SYMOP (IC_RESULT (ic)))
3891 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3892 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3895 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3899 /* if the condition of an if instruction
3900 is defined in the previous instruction then
3901 mark the itemp as a conditional */
3902 if ((IS_CONDITIONAL (ic) ||
3903 ((ic->op == BITWISEAND ||
3906 isBitwiseOptimizable (ic))) &&
3907 ic->next && ic->next->op == IFX &&
3908 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3909 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3912 debugLog (" %d\n", __LINE__);
3913 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3917 debugLog(" %d\n", __LINE__);
3919 #ifndef NO_packRegsForSupport
3920 /* reduce for support function calls */
3921 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3922 packRegsForSupport (ic, ebp);
3925 /* if a parameter is passed, it's in W, so we may not
3926 need to place a copy in a register */
3927 if (ic->op == RECEIVE)
3928 packForReceive (ic, ebp);
3930 #ifndef NO_packRegsForOneuse
3931 /* some cases the redundant moves can
3932 can be eliminated for return statements */
3933 if ((ic->op == RETURN || ic->op == SEND) &&
3934 !isOperandInFarSpace (IC_LEFT (ic)) &&
3936 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3939 #ifndef NO_packRegsForOneuse
3940 /* if pointer set & left has a size more than
3941 one and right is not in far space */
3942 if (POINTER_SET (ic) &&
3943 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3944 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3945 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3946 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3948 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3951 #ifndef NO_packRegsForOneuse
3952 /* if pointer get */
3953 if (POINTER_GET (ic) &&
3954 !isOperandInFarSpace (IC_RESULT (ic)) &&
3955 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3956 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3957 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3959 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3960 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3963 #ifndef NO_cast_peep
3964 /* if this is cast for intergral promotion then
3965 check if only use of the definition of the
3966 operand being casted/ if yes then replace
3967 the result of that arithmetic operation with
3968 this result and get rid of the cast */
3969 if (ic->op == CAST) {
3971 sym_link *fromType = operandType (IC_RIGHT (ic));
3972 sym_link *toType = operandType (IC_LEFT (ic));
3974 debugLog (" %d - casting\n", __LINE__);
3976 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3977 getSize (fromType) != getSize (toType)) {
3980 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3983 if (IS_ARITHMETIC_OP (dic)) {
3984 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3986 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3987 IC_RESULT (dic) = IC_RESULT (ic);
3988 remiCodeFromeBBlock (ebp, ic);
3989 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3990 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3991 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3995 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3999 /* if the type from and type to are the same
4000 then if this is the only use then packit */
4001 if (compareType (operandType (IC_RIGHT (ic)),
4002 operandType (IC_LEFT (ic))) == 1) {
4004 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4007 debugLog(" %d\n", __LINE__);
4009 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4010 IC_RESULT (dic) = IC_RESULT (ic);
4011 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4012 remiCodeFromeBBlock (ebp, ic);
4013 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4014 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4022 iTempNN := (some variable in farspace) V1
4027 if (ic->op == IPUSH)
4029 packForPush (ic, ebp);
4033 #ifndef NO_packRegsForAccUse
4034 /* pack registers for accumulator use, when the
4035 result of an arithmetic or bit wise operation
4036 has only one use, that use is immediately following
4037 the defintion and the using iCode has only one
4038 operand or has two operands but one is literal &
4039 the result of that operation is not on stack then
4040 we can leave the result of this operation in acc:b
4042 if ((IS_ARITHMETIC_OP (ic)
4044 || IS_BITWISE_OP (ic)
4046 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4049 IS_ITEMP (IC_RESULT (ic)) &&
4050 getSize (operandType (IC_RESULT (ic))) <= 1)
4052 packRegsForAccUse (ic);
4059 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4063 if (!pic16_ralloc_debug || !debugF)
4066 for (i = 0; i < count; i++)
4068 fprintf (debugF, "\n----------------------------------------------------------------\n");
4069 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4070 ebbs[i]->entryLabel->name,
4073 ebbs[i]->isLastInLoop);
4074 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4079 fprintf (debugF, "visited %d : hasFcall = %d\n",
4083 fprintf (debugF, "\ndefines bitVector :");
4084 bitVectDebugOn (ebbs[i]->defSet, debugF);
4085 fprintf (debugF, "\nlocal defines bitVector :");
4086 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4087 fprintf (debugF, "\npointers Set bitvector :");
4088 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4089 fprintf (debugF, "\nin pointers Set bitvector :");
4090 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4091 fprintf (debugF, "\ninDefs Set bitvector :");
4092 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4093 fprintf (debugF, "\noutDefs Set bitvector :");
4094 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4095 fprintf (debugF, "\nusesDefs Set bitvector :");
4096 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4097 fprintf (debugF, "\n----------------------------------------------------------------\n");
4098 printiCChain (ebbs[i]->sch, debugF);
4101 /*-----------------------------------------------------------------*/
4102 /* pic16_assignRegisters - assigns registers to each live range as need */
4103 /*-----------------------------------------------------------------*/
4105 pic16_assignRegisters (eBBlock ** ebbs, int count)
4110 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4111 debugLog ("\nebbs before optimizing:\n");
4112 dumpEbbsToDebug (ebbs, count);
4114 setToNull ((void *) &_G.funcrUsed);
4115 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4118 /* change assignments this will remove some
4119 live ranges reducing some register pressure */
4120 for (i = 0; i < count; i++)
4121 pic16_packRegisters (ebbs[i]);
4128 debugLog("dir registers allocated so far:\n");
4129 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4132 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4133 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4134 reg = hTabNextItem(dynDirectRegNames, &hkey);
4139 /* liveranges probably changed by register packing
4140 so we compute them again */
4141 recomputeLiveRanges (ebbs, count);
4143 if (options.dump_pack)
4144 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4146 /* first determine for each live range the number of
4147 registers & the type of registers required for each */
4150 /* and serially allocate registers */
4151 serialRegAssign (ebbs, count);
4154 debugLog ("ebbs after serialRegAssign:\n");
4155 dumpEbbsToDebug (ebbs, count);
4158 //pic16_freeAllRegs();
4160 /* if stack was extended then tell the user */
4163 /* werror(W_TOOMANY_SPILS,"stack", */
4164 /* _G.stackExtend,currFunc->name,""); */
4170 /* werror(W_TOOMANY_SPILS,"data space", */
4171 /* _G.dataExtend,currFunc->name,""); */
4175 /* after that create the register mask
4176 for each of the instruction */
4177 createRegMask (ebbs, count);
4179 /* redo that offsets for stacked automatic variables */
4180 redoStackOffsets ();
4182 if (options.dump_rassgn)
4183 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4185 /* now get back the chain */
4186 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4188 debugLog ("ebbs after optimizing:\n");
4189 dumpEbbsToDebug (ebbs, count);
4194 /* free up any _G.stackSpil locations allocated */
4195 applyToSet (_G.stackSpil, deallocStackSpil);
4197 setToNull ((void *) &_G.stackSpil);
4198 setToNull ((void *) &_G.spiltSet);
4199 /* mark all registers as free */
4200 pic16_freeAllRegs ();
4202 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");