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\n", __FUNCTION__, debugLogRegType (type), 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);
756 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
757 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
760 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
761 debugLog(" %d const char\n",__LINE__);
762 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
763 // fprintf(stderr, " %d const char\n",__LINE__);
764 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
768 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
769 if (IS_CODE ( OP_SYM_ETYPE(op)) )
770 debugLog(" %d code space\n",__LINE__);
772 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
773 debugLog(" %d integral\n",__LINE__);
775 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
776 debugLog(" %d literal\n",__LINE__);
778 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
779 debugLog(" %d specifier\n",__LINE__);
781 debugAopGet(NULL, op);
785 reg = pic16_dirregWithName(name);
789 int regtype = REG_GPR;
791 /* if this is at an absolute address, then get the address. */
792 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
793 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
794 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
797 /* Register wasn't found in hash, so let's create
798 * a new one and put it in the hash table AND in the
799 * dynDirectRegNames set */
800 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
801 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
806 if(OP_SYMBOL(op)->onStack) {
807 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
808 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
811 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
812 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
815 if(pic16_debug_verbose)
817 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
818 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
819 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
820 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
821 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
822 IN_STACK( OP_SYM_ETYPE(op)),
823 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
825 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
826 OP_SYMBOL(op)->name);
831 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
832 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
834 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
835 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
839 checkAddReg(&pic16_dynAccessRegs, reg);
840 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
846 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
847 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
848 // reg->type = REG_SFR;
851 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
852 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
853 addSet(&pic16_dynDirectBitRegs, reg);
856 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
857 // addSet(&pic16_dynDirectRegs, reg);
859 checkAddReg(&pic16_dynDirectRegs, reg);
863 // debugLog (" -- %s is declared at address 0x30000x\n",name);
864 return (reg); /* This was NULL before, but since we found it
865 * why not just return it?! */
868 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
870 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
872 /* work around for user defined registers in access bank */
873 if((reg->address>= 0x00 && reg->address < 0x80)
874 || (reg->address >= 0xf80 && reg->address <= 0xfff))
877 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
883 /*-----------------------------------------------------------------*/
884 /* pic16_allocRegByName - allocates register of given type */
885 /*-----------------------------------------------------------------*/
887 pic16_allocRegByName (char *name, int size, operand *op)
893 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
897 /* First, search the hash table to see if there is a register with this name */
898 reg = pic16_dirregWithName(name);
902 /* Register wasn't found in hash, so let's create
903 * a new one and put it in the hash table AND in the
904 * dynDirectRegNames set */
906 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
908 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
910 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
911 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
913 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
914 addSet(&pic16_dynDirectRegs, reg);
920 /*-----------------------------------------------------------------*/
921 /* RegWithIdx - returns pointer to register with index number */
922 /*-----------------------------------------------------------------*/
923 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
928 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
929 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
934 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
936 debugLog ("Found a Dynamic Register!\n");
939 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
940 debugLog ("Found a Direct Register!\n");
946 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
947 debugLog ("Found a Stack Register!\n");
952 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
953 debugLog ("Found a Processor Register!\n");
967 /*-----------------------------------------------------------------*/
968 /* pic16_regWithIdx - returns pointer to register with index number*/
969 /*-----------------------------------------------------------------*/
971 pic16_regWithIdx (int idx)
975 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
978 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
982 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
989 /*-----------------------------------------------------------------*/
990 /* pic16_regWithIdx - returns pointer to register with index number */
991 /*-----------------------------------------------------------------*/
993 pic16_allocWithIdx (int idx)
998 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
999 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1001 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1003 debugLog ("Found a Dynamic Register!\n");
1004 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1005 debugLog ("Found a Stack Register!\n");
1006 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1007 debugLog ("Found a Processor Register!\n");
1008 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1009 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1010 debugLog ("Found an Internal Register!\n");
1013 debugLog ("Dynamic Register not found\n");
1016 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1017 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1018 "regWithIdx not found");
1028 /*-----------------------------------------------------------------*/
1029 /*-----------------------------------------------------------------*/
1031 pic16_findFreeReg(short type)
1038 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1040 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1044 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1056 /*-----------------------------------------------------------------*/
1057 /* freeReg - frees a register */
1058 /*-----------------------------------------------------------------*/
1060 freeReg (regs * reg)
1062 debugLog ("%s\n", __FUNCTION__);
1063 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1068 /*-----------------------------------------------------------------*/
1069 /* nFreeRegs - returns number of free registers */
1070 /*-----------------------------------------------------------------*/
1072 nFreeRegs (int type)
1078 /* although I fixed the register allocation/freeing scheme
1079 * the for loop below doesn't give valid results. I do not
1080 * know why yet. -- VR 10-Jan-2003 */
1085 /* dynamically allocate as many as we need and worry about
1086 * fitting them into a PIC later */
1088 debugLog ("%s\n", __FUNCTION__);
1090 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1091 if((reg->type == type) && reg->isFree)nfr++;
1093 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1097 /*-----------------------------------------------------------------*/
1098 /* nfreeRegsType - free registers with type */
1099 /*-----------------------------------------------------------------*/
1101 nfreeRegsType (int type)
1104 debugLog ("%s\n", __FUNCTION__);
1105 if (type == REG_PTR)
1107 if ((nfr = nFreeRegs (type)) == 0)
1108 return nFreeRegs (REG_GPR);
1111 return nFreeRegs (type);
1114 static void writeSetUsedRegs(FILE *of, set *dRegs)
1119 for (dReg = setFirstItem(dRegs) ; dReg ;
1120 dReg = setNextItem(dRegs)) {
1123 fprintf (of, "\t%s\n",dReg->name);
1129 extern void pic16_groupRegistersInSection(set *regset);
1131 extern void pic16_dump_equates(FILE *of, set *equs);
1132 extern void pic16_dump_access(FILE *of, set *section);
1133 //extern void pic16_dump_map(void);
1134 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1135 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1136 extern void pic16_dump_int_registers(FILE *of, set *section);
1137 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1139 extern void pic16_dump_gsection(FILE *of, set *sections);
1141 static void packBits(set *bregs)
1145 regs *bitfield=NULL;
1146 regs *relocbitfield=NULL;
1152 for (regset = bregs ; regset ;
1153 regset = regset->next) {
1155 breg = regset->item;
1156 breg->isBitField = 1;
1157 //fprintf(stderr,"bit reg: %s\n",breg->name);
1160 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1162 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1163 breg->rIdx = breg->address & 7;
1164 breg->address >>= 3;
1167 sprintf (buffer, "fbitfield%02x", breg->address);
1168 //fprintf(stderr,"new bit field\n");
1169 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1170 bitfield->isBitField = 1;
1171 bitfield->isFixed = 1;
1172 bitfield->address = breg->address;
1173 addSet(&pic16_dynDirectRegs,bitfield);
1174 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1176 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1179 breg->reg_alias = bitfield;
1183 if(!relocbitfield || bit_no >7) {
1186 sprintf (buffer, "bitfield%d", byte_no);
1187 //fprintf(stderr,"new relocatable bit field\n");
1188 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1189 relocbitfield->isBitField = 1;
1190 addSet(&pic16_dynDirectRegs,relocbitfield);
1191 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1195 breg->reg_alias = relocbitfield;
1196 breg->address = rDirectIdx; /* byte_no; */
1197 breg->rIdx = bit_no++;
1203 void pic16_writeUsedRegs(FILE *of)
1205 packBits(pic16_dynDirectBitRegs);
1207 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1208 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1210 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1211 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1213 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1214 pic16_groupRegistersInSection(pic16_dynStackRegs);
1216 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1217 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1219 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1220 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1222 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1223 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1225 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1226 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1229 pic16_dump_equates(of, pic16_equ_data);
1231 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1232 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1234 /* dump access bank symbols */
1235 pic16_dump_access(of, pic16_acs_udata);
1237 /* dump initialised data */
1238 pic16_dump_isection(of, rel_idataSymSet, 0);
1239 pic16_dump_isection(of, fix_idataSymSet, 1);
1241 /* dump internal registers */
1242 pic16_dump_int_registers(of, pic16_int_regs);
1244 /* dump generic section variables */
1245 pic16_dump_gsection(of, sectNames);
1247 /* dump other variables */
1248 pic16_dump_usection(of, pic16_rel_udata, 0);
1249 pic16_dump_usection(of, pic16_fix_udata, 1);
1254 /*-----------------------------------------------------------------*/
1255 /* computeSpillable - given a point find the spillable live ranges */
1256 /*-----------------------------------------------------------------*/
1258 computeSpillable (iCode * ic)
1262 debugLog ("%s\n", __FUNCTION__);
1263 /* spillable live ranges are those that are live at this
1264 point . the following categories need to be subtracted
1266 a) - those that are already spilt
1267 b) - if being used by this one
1268 c) - defined by this one */
1270 spillable = bitVectCopy (ic->rlive);
1272 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1274 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1275 bitVectUnSetBit (spillable, ic->defKey);
1276 spillable = bitVectIntersect (spillable, _G.regAssigned);
1281 /*-----------------------------------------------------------------*/
1282 /* noSpilLoc - return true if a variable has no spil location */
1283 /*-----------------------------------------------------------------*/
1285 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1287 debugLog ("%s\n", __FUNCTION__);
1288 return (sym->usl.spillLoc ? 0 : 1);
1291 /*-----------------------------------------------------------------*/
1292 /* hasSpilLoc - will return 1 if the symbol has spil location */
1293 /*-----------------------------------------------------------------*/
1295 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1297 debugLog ("%s\n", __FUNCTION__);
1298 return (sym->usl.spillLoc ? 1 : 0);
1301 /*-----------------------------------------------------------------*/
1302 /* directSpilLoc - will return 1 if the splilocation is in direct */
1303 /*-----------------------------------------------------------------*/
1305 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1307 debugLog ("%s\n", __FUNCTION__);
1308 if (sym->usl.spillLoc &&
1309 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1315 /*-----------------------------------------------------------------*/
1316 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1317 /* but is not used as a pointer */
1318 /*-----------------------------------------------------------------*/
1320 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1322 debugLog ("%s\n", __FUNCTION__);
1323 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1326 /*-----------------------------------------------------------------*/
1327 /* rematable - will return 1 if the remat flag is set */
1328 /*-----------------------------------------------------------------*/
1330 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1332 debugLog ("%s\n", __FUNCTION__);
1336 /*-----------------------------------------------------------------*/
1337 /* notUsedInRemaining - not used or defined in remain of the block */
1338 /*-----------------------------------------------------------------*/
1340 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1342 debugLog ("%s\n", __FUNCTION__);
1343 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1344 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1347 /*-----------------------------------------------------------------*/
1348 /* allLRs - return true for all */
1349 /*-----------------------------------------------------------------*/
1351 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1353 debugLog ("%s\n", __FUNCTION__);
1357 /*-----------------------------------------------------------------*/
1358 /* liveRangesWith - applies function to a given set of live range */
1359 /*-----------------------------------------------------------------*/
1361 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1362 eBBlock * ebp, iCode * ic)
1367 debugLog ("%s\n", __FUNCTION__);
1368 if (!lrs || !lrs->size)
1371 for (i = 1; i < lrs->size; i++)
1374 if (!bitVectBitValue (lrs, i))
1377 /* if we don't find it in the live range
1378 hash table we are in serious trouble */
1379 if (!(sym = hTabItemWithKey (liveRanges, i)))
1381 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1382 "liveRangesWith could not find liveRange");
1386 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1387 addSetHead (&rset, sym);
1394 /*-----------------------------------------------------------------*/
1395 /* leastUsedLR - given a set determines which is the least used */
1396 /*-----------------------------------------------------------------*/
1398 leastUsedLR (set * sset)
1400 symbol *sym = NULL, *lsym = NULL;
1402 debugLog ("%s\n", __FUNCTION__);
1403 sym = lsym = setFirstItem (sset);
1408 for (; lsym; lsym = setNextItem (sset))
1411 /* if usage is the same then prefer
1412 the spill the smaller of the two */
1413 if (lsym->used == sym->used)
1414 if (getSize (lsym->type) < getSize (sym->type))
1418 if (lsym->used < sym->used)
1423 setToNull ((void *) &sset);
1428 /*-----------------------------------------------------------------*/
1429 /* noOverLap - will iterate through the list looking for over lap */
1430 /*-----------------------------------------------------------------*/
1432 noOverLap (set * itmpStack, symbol * fsym)
1435 debugLog ("%s\n", __FUNCTION__);
1438 for (sym = setFirstItem (itmpStack); sym;
1439 sym = setNextItem (itmpStack))
1441 if (sym->liveTo > fsym->liveFrom)
1449 /*-----------------------------------------------------------------*/
1450 /* isFree - will return 1 if the a free spil location is found */
1451 /*-----------------------------------------------------------------*/
1456 V_ARG (symbol **, sloc);
1457 V_ARG (symbol *, fsym);
1459 debugLog ("%s\n", __FUNCTION__);
1460 /* if already found */
1464 /* if it is free && and the itmp assigned to
1465 this does not have any overlapping live ranges
1466 with the one currently being assigned and
1467 the size can be accomodated */
1469 noOverLap (sym->usl.itmpStack, fsym) &&
1470 getSize (sym->type) >= getSize (fsym->type))
1479 /*-----------------------------------------------------------------*/
1480 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1481 /*-----------------------------------------------------------------*/
1483 spillLRWithPtrReg (symbol * forSym)
1489 debugLog ("%s\n", __FUNCTION__);
1490 if (!_G.regAssigned ||
1491 bitVectIsZero (_G.regAssigned))
1494 r0 = pic16_regWithIdx (R0_IDX);
1495 r1 = pic16_regWithIdx (R1_IDX);
1497 /* for all live ranges */
1498 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1499 lrsym = hTabNextItem (liveRanges, &k))
1503 /* if no registers assigned to it or
1505 /* if it does not overlap with this then
1506 not need to spill it */
1508 if (lrsym->isspilt || !lrsym->nRegs ||
1509 (lrsym->liveTo < forSym->liveFrom))
1512 /* go thru the registers : if it is either
1513 r0 or r1 then spil it */
1514 for (j = 0; j < lrsym->nRegs; j++)
1515 if (lrsym->regs[j] == r0 ||
1516 lrsym->regs[j] == r1)
1525 /*-----------------------------------------------------------------*/
1526 /* createStackSpil - create a location on the stack to spil */
1527 /*-----------------------------------------------------------------*/
1529 createStackSpil (symbol * sym)
1531 symbol *sloc = NULL;
1532 int useXstack, model, noOverlay;
1534 char slocBuffer[30];
1535 debugLog ("%s\n", __FUNCTION__);
1537 /* first go try and find a free one that is already
1538 existing on the stack */
1539 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1541 /* found a free one : just update & return */
1542 sym->usl.spillLoc = sloc;
1545 addSetHead (&sloc->usl.itmpStack, sym);
1549 /* could not then have to create one , this is the hard part
1550 we need to allocate this on the stack : this is really a
1551 hack!! but cannot think of anything better at this time */
1553 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1555 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1556 __FILE__, __LINE__);
1560 sloc = newiTemp (slocBuffer);
1562 /* set the type to the spilling symbol */
1563 sloc->type = copyLinkChain (sym->type);
1564 sloc->etype = getSpec (sloc->type);
1565 SPEC_SCLS (sloc->etype) = S_DATA;
1566 SPEC_EXTR (sloc->etype) = 0;
1567 SPEC_STAT (sloc->etype) = 0;
1569 /* we don't allow it to be allocated`
1570 onto the external stack since : so we
1571 temporarily turn it off ; we also
1572 turn off memory model to prevent
1573 the spil from going to the external storage
1574 and turn off overlaying
1577 useXstack = options.useXstack;
1578 model = options.model;
1579 noOverlay = options.noOverlay;
1580 options.noOverlay = 1;
1581 options.model = options.useXstack = 0;
1585 options.useXstack = useXstack;
1586 options.model = model;
1587 options.noOverlay = noOverlay;
1588 sloc->isref = 1; /* to prevent compiler warning */
1590 /* if it is on the stack then update the stack */
1591 if (IN_STACK (sloc->etype))
1593 currFunc->stack += getSize (sloc->type);
1594 _G.stackExtend += getSize (sloc->type);
1597 _G.dataExtend += getSize (sloc->type);
1599 /* add it to the _G.stackSpil set */
1600 addSetHead (&_G.stackSpil, sloc);
1601 sym->usl.spillLoc = sloc;
1604 /* add it to the set of itempStack set
1605 of the spill location */
1606 addSetHead (&sloc->usl.itmpStack, sym);
1610 /*-----------------------------------------------------------------*/
1611 /* isSpiltOnStack - returns true if the spil location is on stack */
1612 /*-----------------------------------------------------------------*/
1614 isSpiltOnStack (symbol * sym)
1618 debugLog ("%s\n", __FUNCTION__);
1625 /* if (sym->_G.stackSpil) */
1628 if (!sym->usl.spillLoc)
1631 etype = getSpec (sym->usl.spillLoc->type);
1632 if (IN_STACK (etype))
1638 /*-----------------------------------------------------------------*/
1639 /* spillThis - spils a specific operand */
1640 /*-----------------------------------------------------------------*/
1642 spillThis (symbol * sym)
1645 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1647 /* if this is rematerializable or has a spillLocation
1648 we are okay, else we need to create a spillLocation
1650 if (!(sym->remat || sym->usl.spillLoc))
1651 createStackSpil (sym);
1654 /* mark it has spilt & put it in the spilt set */
1656 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1658 bitVectUnSetBit (_G.regAssigned, sym->key);
1660 for (i = 0; i < sym->nRegs; i++)
1664 freeReg (sym->regs[i]);
1665 sym->regs[i] = NULL;
1668 /* if spilt on stack then free up r0 & r1
1669 if they could have been assigned to some
1671 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1674 spillLRWithPtrReg (sym);
1677 if (sym->usl.spillLoc && !sym->remat)
1678 sym->usl.spillLoc->allocreq = 1;
1682 /*-----------------------------------------------------------------*/
1683 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1684 /*-----------------------------------------------------------------*/
1686 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1688 bitVect *lrcs = NULL;
1692 debugLog ("%s\n", __FUNCTION__);
1693 /* get the spillable live ranges */
1694 lrcs = computeSpillable (ic);
1696 /* get all live ranges that are rematerizable */
1697 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1700 /* return the least used of these */
1701 return leastUsedLR (selectS);
1704 /* get live ranges with spillLocations in direct space */
1705 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1707 sym = leastUsedLR (selectS);
1708 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1709 sym->usl.spillLoc->rname :
1710 sym->usl.spillLoc->name));
1712 /* mark it as allocation required */
1713 sym->usl.spillLoc->allocreq = 1;
1717 /* if the symbol is local to the block then */
1718 if (forSym->liveTo < ebp->lSeq)
1721 /* check if there are any live ranges allocated
1722 to registers that are not used in this block */
1723 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1725 sym = leastUsedLR (selectS);
1726 /* if this is not rematerializable */
1735 /* check if there are any live ranges that not
1736 used in the remainder of the block */
1737 if (!_G.blockSpil &&
1738 !isiCodeInFunctionCall (ic) &&
1739 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1741 sym = leastUsedLR (selectS);
1744 sym->remainSpil = 1;
1751 /* find live ranges with spillocation && not used as pointers */
1752 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1755 sym = leastUsedLR (selectS);
1756 /* mark this as allocation required */
1757 sym->usl.spillLoc->allocreq = 1;
1761 /* find live ranges with spillocation */
1762 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1765 sym = leastUsedLR (selectS);
1766 sym->usl.spillLoc->allocreq = 1;
1770 /* couldn't find then we need to create a spil
1771 location on the stack , for which one? the least
1773 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1776 /* return a created spil location */
1777 sym = createStackSpil (leastUsedLR (selectS));
1778 sym->usl.spillLoc->allocreq = 1;
1782 /* this is an extreme situation we will spill
1783 this one : happens very rarely but it does happen */
1789 /*-----------------------------------------------------------------*/
1790 /* spilSomething - spil some variable & mark registers as free */
1791 /*-----------------------------------------------------------------*/
1793 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1798 debugLog ("%s\n", __FUNCTION__);
1799 /* get something we can spil */
1800 ssym = selectSpil (ic, ebp, forSym);
1802 /* mark it as spilt */
1804 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1806 /* mark it as not register assigned &
1807 take it away from the set */
1808 bitVectUnSetBit (_G.regAssigned, ssym->key);
1810 /* mark the registers as free */
1811 for (i = 0; i < ssym->nRegs; i++)
1813 freeReg (ssym->regs[i]);
1815 /* if spilt on stack then free up r0 & r1
1816 if they could have been assigned to as gprs */
1817 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1820 spillLRWithPtrReg (ssym);
1823 /* if this was a block level spil then insert push & pop
1824 at the start & end of block respectively */
1825 if (ssym->blockSpil)
1827 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1828 /* add push to the start of the block */
1829 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1830 ebp->sch->next : ebp->sch));
1831 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1832 /* add pop to the end of the block */
1833 addiCodeToeBBlock (ebp, nic, NULL);
1836 /* if spilt because not used in the remainder of the
1837 block then add a push before this instruction and
1838 a pop at the end of the block */
1839 if (ssym->remainSpil)
1842 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1843 /* add push just before this instruction */
1844 addiCodeToeBBlock (ebp, nic, ic);
1846 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1847 /* add pop to the end of the block */
1848 addiCodeToeBBlock (ebp, nic, NULL);
1857 /*-----------------------------------------------------------------*/
1858 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1859 /*-----------------------------------------------------------------*/
1861 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1866 debugLog ("%s\n", __FUNCTION__);
1868 /* try for a ptr type */
1869 if ((reg = allocReg (REG_PTR)))
1872 /* try for gpr type */
1873 if ((reg = allocReg (REG_GPR)))
1876 /* we have to spil */
1877 if (!spilSomething (ic, ebp, sym))
1880 /* make sure partially assigned registers aren't reused */
1881 for (j=0; j<=sym->nRegs; j++)
1883 sym->regs[j]->isFree = 0;
1885 /* this looks like an infinite loop but
1886 in really selectSpil will abort */
1890 /*-----------------------------------------------------------------*/
1891 /* getRegGpr - will try for GPR if not spil */
1892 /*-----------------------------------------------------------------*/
1894 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1899 debugLog ("%s\n", __FUNCTION__);
1901 /* try for gpr type */
1902 if ((reg = allocReg (REG_GPR)))
1905 if (!pic16_ptrRegReq)
1906 if ((reg = allocReg (REG_PTR)))
1909 /* we have to spil */
1910 if (!spilSomething (ic, ebp, sym))
1913 /* make sure partially assigned registers aren't reused */
1914 for (j=0; j<=sym->nRegs; j++)
1916 sym->regs[j]->isFree = 0;
1918 /* this looks like an infinite loop but
1919 in really selectSpil will abort */
1923 /*-----------------------------------------------------------------*/
1924 /* symHasReg - symbol has a given register */
1925 /*-----------------------------------------------------------------*/
1927 symHasReg (symbol * sym, regs * reg)
1931 debugLog ("%s\n", __FUNCTION__);
1932 for (i = 0; i < sym->nRegs; i++)
1933 if (sym->regs[i] == reg)
1939 /*-----------------------------------------------------------------*/
1940 /* deassignLRs - check the live to and if they have registers & are */
1941 /* not spilt then free up the registers */
1942 /*-----------------------------------------------------------------*/
1944 deassignLRs (iCode * ic, eBBlock * ebp)
1950 debugLog ("%s\n", __FUNCTION__);
1951 for (sym = hTabFirstItem (liveRanges, &k); sym;
1952 sym = hTabNextItem (liveRanges, &k))
1955 symbol *psym = NULL;
1956 /* if it does not end here */
1957 if (sym->liveTo > ic->seq)
1960 /* if it was spilt on stack then we can
1961 mark the stack spil location as free */
1966 sym->usl.spillLoc->isFree = 1;
1972 if (!bitVectBitValue (_G.regAssigned, sym->key))
1975 /* special case for shifting: there is a case where shift count
1976 * can be allocated in the same register as the result, so do not
1977 * free right registers if same as result registers, cause genShiftLeft
1978 * will fail -- VR */
1979 if(ic->op == LEFT_OP)
1982 /* special case check if this is an IFX &
1983 the privious one was a pop and the
1984 previous one was not spilt then keep track
1986 if (ic->op == IFX && ic->prev &&
1987 ic->prev->op == IPOP &&
1988 !ic->prev->parmPush &&
1989 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1990 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1996 bitVectUnSetBit (_G.regAssigned, sym->key);
1998 /* if the result of this one needs registers
1999 and does not have it then assign it right
2001 if (IC_RESULT (ic) &&
2002 !(SKIP_IC2 (ic) || /* not a special icode */
2003 ic->op == JUMPTABLE ||
2008 POINTER_SET (ic)) &&
2009 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2010 result->liveTo > ic->seq && /* and will live beyond this */
2011 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2012 result->liveFrom == ic->seq && /* does not start before here */
2013 result->regType == sym->regType && /* same register types */
2014 result->nRegs && /* which needs registers */
2015 !result->isspilt && /* and does not already have them */
2017 !bitVectBitValue (_G.regAssigned, result->key) &&
2018 /* the number of free regs + number of regs in this LR
2019 can accomodate the what result Needs */
2020 ((nfreeRegsType (result->regType) +
2021 sym->nRegs) >= result->nRegs)
2025 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2027 result->regs[i] = sym->regs[i];
2029 result->regs[i] = getRegGpr (ic, ebp, result);
2031 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2035 /* free the remaining */
2036 for (; i < sym->nRegs; i++)
2040 if (!symHasReg (psym, sym->regs[i]))
2041 freeReg (sym->regs[i]);
2044 freeReg (sym->regs[i]);
2051 /*-----------------------------------------------------------------*/
2052 /* reassignLR - reassign this to registers */
2053 /*-----------------------------------------------------------------*/
2055 reassignLR (operand * op)
2057 symbol *sym = OP_SYMBOL (op);
2060 debugLog ("%s\n", __FUNCTION__);
2061 /* not spilt any more */
2062 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2063 bitVectUnSetBit (_G.spiltSet, sym->key);
2065 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2069 for (i = 0; i < sym->nRegs; i++)
2070 sym->regs[i]->isFree = 0;
2073 /*-----------------------------------------------------------------*/
2074 /* willCauseSpill - determines if allocating will cause a spill */
2075 /*-----------------------------------------------------------------*/
2077 willCauseSpill (int nr, int rt)
2079 debugLog ("%s\n", __FUNCTION__);
2080 /* first check if there are any avlb registers
2081 of te type required */
2084 /* special case for pointer type
2085 if pointer type not avlb then
2086 check for type gpr */
2087 if (nFreeRegs (rt) >= nr)
2089 if (nFreeRegs (REG_GPR) >= nr)
2094 if (pic16_ptrRegReq)
2096 if (nFreeRegs (rt) >= nr)
2101 if (nFreeRegs (REG_PTR) +
2102 nFreeRegs (REG_GPR) >= nr)
2107 debugLog (" ... yep it will (cause a spill)\n");
2108 /* it will cause a spil */
2112 /*-----------------------------------------------------------------*/
2113 /* positionRegs - the allocator can allocate same registers to res- */
2114 /* ult and operand, if this happens make sure they are in the same */
2115 /* position as the operand otherwise chaos results */
2116 /*-----------------------------------------------------------------*/
2118 positionRegs (symbol * result, symbol * opsym, int lineno)
2120 int count = min (result->nRegs, opsym->nRegs);
2121 int i, j = 0, shared = 0;
2123 debugLog ("%s\n", __FUNCTION__);
2124 /* if the result has been spilt then cannot share */
2129 /* first make sure that they actually share */
2130 for (i = 0; i < count; i++)
2132 for (j = 0; j < count; j++)
2134 if (result->regs[i] == opsym->regs[j] && i != j)
2144 regs *tmp = result->regs[i];
2145 result->regs[i] = result->regs[j];
2146 result->regs[j] = tmp;
2151 /*------------------------------------------------------------------*/
2152 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2153 /* it should either have registers or have beed spilled. Otherwise, */
2154 /* there was an uninitialized variable, so just spill this to get */
2155 /* the operand in a valid state. */
2156 /*------------------------------------------------------------------*/
2158 verifyRegsAssigned (operand *op, iCode * ic)
2163 if (!IS_ITEMP (op)) return;
2165 sym = OP_SYMBOL (op);
2166 if (sym->isspilt) return;
2167 if (!sym->nRegs) return;
2168 if (sym->regs[0]) return;
2170 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2171 sym->prereqv ? sym->prereqv->name : sym->name);
2176 /*-----------------------------------------------------------------*/
2177 /* serialRegAssign - serially allocate registers to the variables */
2178 /*-----------------------------------------------------------------*/
2180 serialRegAssign (eBBlock ** ebbs, int count)
2184 debugLog ("%s\n", __FUNCTION__);
2185 /* for all blocks */
2186 for (i = 0; i < count; i++)
2191 if (ebbs[i]->noPath &&
2192 (ebbs[i]->entryLabel != entryLabel &&
2193 ebbs[i]->entryLabel != returnLabel))
2196 /* of all instructions do */
2197 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2200 debugLog (" op: %s\n", decodeOp (ic->op));
2202 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2203 pic16_allocDirReg(IC_RESULT(ic));
2205 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2206 pic16_allocDirReg(IC_LEFT(ic));
2208 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2209 pic16_allocDirReg(IC_RIGHT(ic));
2211 /* if this is an ipop that means some live
2212 range will have to be assigned again */
2214 reassignLR (IC_LEFT (ic));
2216 /* if result is present && is a true symbol */
2217 if (IC_RESULT (ic) && ic->op != IFX &&
2218 IS_TRUE_SYMOP (IC_RESULT (ic)))
2219 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2221 /* take away registers from live
2222 ranges that end at this instruction */
2223 deassignLRs (ic, ebbs[i]);
2225 /* some don't need registers */
2226 if (SKIP_IC2 (ic) ||
2227 ic->op == JUMPTABLE ||
2231 (IC_RESULT (ic) && POINTER_SET (ic)))
2234 /* now we need to allocate registers
2235 only for the result */
2238 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2244 /* if it does not need or is spilt
2245 or is already assigned to registers
2246 or will not live beyond this instructions */
2249 bitVectBitValue (_G.regAssigned, sym->key) ||
2250 sym->liveTo <= ic->seq)
2253 /* if some liverange has been spilt at the block level
2254 and this one live beyond this block then spil this
2256 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2261 /* if trying to allocate this will cause
2262 a spill and there is nothing to spill
2263 or this one is rematerializable then
2265 willCS = willCauseSpill (sym->nRegs, sym->regType);
2266 spillable = computeSpillable (ic);
2268 (willCS && bitVectIsZero (spillable)))
2276 /* If the live range preceeds the point of definition
2277 then ideally we must take into account registers that
2278 have been allocated after sym->liveFrom but freed
2279 before ic->seq. This is complicated, so spill this
2280 symbol instead and let fillGaps handle the allocation. */
2281 if (sym->liveFrom < ic->seq)
2287 /* if it has a spillocation & is used less than
2288 all other live ranges then spill this */
2290 if (sym->usl.spillLoc) {
2291 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2292 allLRs, ebbs[i], ic));
2293 if (leastUsed && leastUsed->used > sym->used) {
2298 /* if none of the liveRanges have a spillLocation then better
2299 to spill this one than anything else already assigned to registers */
2300 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2301 /* if this is local to this block then we might find a block spil */
2302 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2310 if (ic->op == RECEIVE)
2311 debugLog ("When I get clever, I'll optimize the receive logic\n");
2313 /* if we need ptr regs for the right side
2315 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2316 <= (unsigned) PTRSIZE)
2321 /* else we assign registers to it */
2322 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2324 debugLog (" %d - nRegs: %d\n", __LINE__, sym->nRegs);
2326 bitVectDebugOn(_G.regAssigned, debugF);
2328 for (j = 0; j < sym->nRegs; j++)
2330 if (sym->regType == REG_PTR)
2331 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2333 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2335 /* if the allocation falied which means
2336 this was spilt then break */
2340 debugLog (" %d - \n", __LINE__);
2342 /* if it shares registers with operands make sure
2343 that they are in the same position */
2344 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2345 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2346 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2347 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2348 /* do the same for the right operand */
2349 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2350 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2351 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2352 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2354 debugLog (" %d - \n", __LINE__);
2357 debugLog (" %d - \n", __LINE__);
2366 /* Check for and fix any problems with uninitialized operands */
2367 for (i = 0; i < count; i++)
2371 if (ebbs[i]->noPath &&
2372 (ebbs[i]->entryLabel != entryLabel &&
2373 ebbs[i]->entryLabel != returnLabel))
2376 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2383 verifyRegsAssigned (IC_COND (ic), ic);
2387 if (ic->op == JUMPTABLE)
2389 verifyRegsAssigned (IC_JTCOND (ic), ic);
2393 verifyRegsAssigned (IC_RESULT (ic), ic);
2394 verifyRegsAssigned (IC_LEFT (ic), ic);
2395 verifyRegsAssigned (IC_RIGHT (ic), ic);
2401 /*-----------------------------------------------------------------*/
2402 /* rUmaskForOp :- returns register mask for an operand */
2403 /*-----------------------------------------------------------------*/
2405 rUmaskForOp (operand * op)
2411 debugLog ("%s\n", __FUNCTION__);
2412 /* only temporaries are assigned registers */
2416 sym = OP_SYMBOL (op);
2418 /* if spilt or no registers assigned to it
2420 if (sym->isspilt || !sym->nRegs)
2423 rumask = newBitVect (pic16_nRegs);
2425 for (j = 0; j < sym->nRegs; j++)
2427 rumask = bitVectSetBit (rumask,
2428 sym->regs[j]->rIdx);
2434 /*-----------------------------------------------------------------*/
2435 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2436 /*-----------------------------------------------------------------*/
2438 regsUsedIniCode (iCode * ic)
2440 bitVect *rmask = newBitVect (pic16_nRegs);
2442 debugLog ("%s\n", __FUNCTION__);
2443 /* do the special cases first */
2446 rmask = bitVectUnion (rmask,
2447 rUmaskForOp (IC_COND (ic)));
2451 /* for the jumptable */
2452 if (ic->op == JUMPTABLE)
2454 rmask = bitVectUnion (rmask,
2455 rUmaskForOp (IC_JTCOND (ic)));
2460 /* of all other cases */
2462 rmask = bitVectUnion (rmask,
2463 rUmaskForOp (IC_LEFT (ic)));
2467 rmask = bitVectUnion (rmask,
2468 rUmaskForOp (IC_RIGHT (ic)));
2471 rmask = bitVectUnion (rmask,
2472 rUmaskForOp (IC_RESULT (ic)));
2478 /*-----------------------------------------------------------------*/
2479 /* createRegMask - for each instruction will determine the regsUsed */
2480 /*-----------------------------------------------------------------*/
2482 createRegMask (eBBlock ** ebbs, int count)
2486 debugLog ("%s\n", __FUNCTION__);
2487 /* for all blocks */
2488 for (i = 0; i < count; i++)
2492 if (ebbs[i]->noPath &&
2493 (ebbs[i]->entryLabel != entryLabel &&
2494 ebbs[i]->entryLabel != returnLabel))
2497 /* for all instructions */
2498 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2503 if (SKIP_IC2 (ic) || !ic->rlive)
2506 /* first mark the registers used in this
2508 ic->rUsed = regsUsedIniCode (ic);
2509 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2511 /* now create the register mask for those
2512 registers that are in use : this is a
2513 super set of ic->rUsed */
2514 ic->rMask = newBitVect (pic16_nRegs + 1);
2516 /* for all live Ranges alive at this point */
2517 for (j = 1; j < ic->rlive->size; j++)
2522 /* if not alive then continue */
2523 if (!bitVectBitValue (ic->rlive, j))
2526 /* find the live range we are interested in */
2527 if (!(sym = hTabItemWithKey (liveRanges, j)))
2529 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2530 "createRegMask cannot find live range");
2534 /* if no register assigned to it */
2535 if (!sym->nRegs || sym->isspilt)
2538 /* for all the registers allocated to it */
2539 for (k = 0; k < sym->nRegs; k++)
2542 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2548 /*-----------------------------------------------------------------*/
2549 /* rematStr - returns the rematerialized string for a remat var */
2550 /*-----------------------------------------------------------------*/
2552 rematStr (symbol * sym)
2555 iCode *ic = sym->rematiCode;
2556 symbol *psym = NULL;
2558 debugLog ("%s\n", __FUNCTION__);
2560 //printf ("%s\n", s);
2562 /* if plus or minus print the right hand side */
2564 if (ic->op == '+' || ic->op == '-') {
2566 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2568 sprintf (s, "(%s %c 0x%04x)",
2569 OP_SYMBOL (IC_LEFT (ric))->rname,
2571 (int) operandLitValue (IC_RIGHT (ic)));
2574 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2576 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2577 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2582 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2583 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2585 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2590 /*-----------------------------------------------------------------*/
2591 /* rematStr - returns the rematerialized string for a remat var */
2592 /*-----------------------------------------------------------------*/
2594 rematStr (symbol * sym)
2597 iCode *ic = sym->rematiCode;
2599 debugLog ("%s\n", __FUNCTION__);
2604 /* if plus or minus print the right hand side */
2606 if (ic->op == '+' || ic->op == '-') {
2607 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2610 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2614 if (ic->op == '+' || ic->op == '-')
2616 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2617 sprintf (s, "(%s %c 0x%04x)",
2618 OP_SYMBOL (IC_LEFT (ric))->rname,
2620 (int) operandLitValue (IC_RIGHT (ic)));
2623 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2625 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2629 /* we reached the end */
2630 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2634 printf ("%s\n", buffer);
2639 /*-----------------------------------------------------------------*/
2640 /* regTypeNum - computes the type & number of registers required */
2641 /*-----------------------------------------------------------------*/
2649 debugLog ("%s\n", __FUNCTION__);
2650 /* for each live range do */
2651 for (sym = hTabFirstItem (liveRanges, &k); sym;
2652 sym = hTabNextItem (liveRanges, &k)) {
2654 debugLog (" %d - %s\n", __LINE__, sym->rname);
2655 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2657 /* if used zero times then no registers needed */
2658 if ((sym->liveTo - sym->liveFrom) == 0)
2662 /* if the live range is a temporary */
2665 debugLog (" %d - itemp register\n", __LINE__);
2667 /* if the type is marked as a conditional */
2668 if (sym->regType == REG_CND)
2671 /* if used in return only then we don't
2673 if (sym->ruonly || sym->accuse) {
2674 if (IS_AGGREGATE (sym->type) || sym->isptr)
2675 sym->type = aggrToPtr (sym->type, FALSE);
2676 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2681 /* if the symbol has only one definition &
2682 that definition is a get_pointer and the
2683 pointer we are getting is rematerializable and
2686 if (bitVectnBitsOn (sym->defs) == 1 &&
2687 (ic = hTabItemWithKey (iCodehTab,
2688 bitVectFirstBit (sym->defs))) &&
2690 !IS_BITVAR (sym->etype) &&
2691 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2693 if (ptrPseudoSymSafe (sym, ic)) {
2697 debugLog (" %d - \n", __LINE__);
2699 /* create a psuedo symbol & force a spil */
2700 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2701 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2702 psym->type = sym->type;
2703 psym->etype = sym->etype;
2704 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2705 strcpy (psym->rname, psym->name);
2707 sym->usl.spillLoc = psym;
2711 /* if in data space or idata space then try to
2712 allocate pointer register */
2716 /* if not then we require registers */
2717 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2718 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2719 getSize (sym->type));
2723 if(IS_PTR_CONST (sym->type)) {
2725 if(IS_CODEPTR (sym->type)) {
2727 // what IS this ???? (HJD)
2728 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2729 sym->nRegs = 3; // patch 14
2732 if (sym->nRegs > 4) {
2733 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2734 printTypeChain (sym->type, stderr);
2735 fprintf (stderr, "\n");
2738 /* determine the type of register required */
2739 if (sym->nRegs == 1 &&
2740 IS_PTR (sym->type) &&
2742 sym->regType = REG_PTR;
2744 sym->regType = REG_GPR;
2747 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2751 /* for the first run we don't provide */
2752 /* registers for true symbols we will */
2753 /* see how things go */
2758 static DEFSETFUNC (markRegFree)
2760 ((regs *)item)->isFree = 1;
2765 DEFSETFUNC (pic16_deallocReg)
2767 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2768 ((regs *)item)->isFree = 1;
2769 ((regs *)item)->wasUsed = 0;
2773 /*-----------------------------------------------------------------*/
2774 /* freeAllRegs - mark all registers as free */
2775 /*-----------------------------------------------------------------*/
2777 pic16_freeAllRegs ()
2779 debugLog ("%s\n", __FUNCTION__);
2781 applyToSet(pic16_dynAllocRegs,markRegFree);
2782 applyToSet(pic16_dynStackRegs,markRegFree);
2785 /*-----------------------------------------------------------------*/
2786 /*-----------------------------------------------------------------*/
2788 pic16_deallocateAllRegs ()
2790 debugLog ("%s\n", __FUNCTION__);
2792 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2796 /*-----------------------------------------------------------------*/
2797 /* deallocStackSpil - this will set the stack pointer back */
2798 /*-----------------------------------------------------------------*/
2800 DEFSETFUNC (deallocStackSpil)
2804 debugLog ("%s\n", __FUNCTION__);
2809 /*-----------------------------------------------------------------*/
2810 /* farSpacePackable - returns the packable icode for far variables */
2811 /*-----------------------------------------------------------------*/
2813 farSpacePackable (iCode * ic)
2817 debugLog ("%s\n", __FUNCTION__);
2818 /* go thru till we find a definition for the
2819 symbol on the right */
2820 for (dic = ic->prev; dic; dic = dic->prev)
2823 /* if the definition is a call then no */
2824 if ((dic->op == CALL || dic->op == PCALL) &&
2825 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2830 /* if shift by unknown amount then not */
2831 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2832 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2835 /* if pointer get and size > 1 */
2836 if (POINTER_GET (dic) &&
2837 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2840 if (POINTER_SET (dic) &&
2841 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2844 /* if any three is a true symbol in far space */
2845 if (IC_RESULT (dic) &&
2846 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2847 isOperandInFarSpace (IC_RESULT (dic)))
2850 if (IC_RIGHT (dic) &&
2851 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2852 isOperandInFarSpace (IC_RIGHT (dic)) &&
2853 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2856 if (IC_LEFT (dic) &&
2857 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2858 isOperandInFarSpace (IC_LEFT (dic)) &&
2859 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2862 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2864 if ((dic->op == LEFT_OP ||
2865 dic->op == RIGHT_OP ||
2867 IS_OP_LITERAL (IC_RIGHT (dic)))
2877 /*-----------------------------------------------------------------*/
2878 /* packRegsForAssign - register reduction for assignment */
2879 /*-----------------------------------------------------------------*/
2881 packRegsForAssign (iCode * ic, eBBlock * ebp)
2886 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2887 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2888 debugAopGet (" result:", IC_RESULT (ic));
2889 debugAopGet (" left:", IC_LEFT (ic));
2890 debugAopGet (" right:", IC_RIGHT (ic));
2892 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2894 debugLog(" %d - actuall processing\n", __LINE__ );
2896 if (!IS_ITEMP (IC_RESULT (ic))) {
2897 pic16_allocDirReg(IC_RESULT (ic));
2898 debugLog (" %d - result is not temp\n", __LINE__);
2902 /* See BUGLOG0001 - VR */
2904 if (!IS_ITEMP (IC_RIGHT (ic))) {
2905 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2906 pic16_allocDirReg(IC_RIGHT (ic));
2911 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2912 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2914 debugLog (" %d - not packing - right side fails \n", __LINE__);
2918 /* if the true symbol is defined in far space or on stack
2919 then we should not since this will increase register pressure */
2920 if (isOperandInFarSpace (IC_RESULT (ic)))
2922 if ((dic = farSpacePackable (ic)))
2929 /* find the definition of iTempNN scanning backwards if we find a
2930 a use of the true symbol before we find the definition then
2932 for (dic = ic->prev; dic; dic = dic->prev)
2935 /* if there is a function call and this is
2936 a parameter & not my parameter then don't pack it */
2937 if ((dic->op == CALL || dic->op == PCALL) &&
2938 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2939 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2941 debugLog (" %d - \n", __LINE__);
2950 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2952 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2953 IS_OP_VOLATILE (IC_RESULT (dic)))
2955 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2961 if( IS_SYMOP( IC_RESULT(dic)) &&
2962 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2964 debugLog (" %d - result is bitfield\n", __LINE__);
2970 if (IS_SYMOP (IC_RESULT (dic)) &&
2971 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2973 /* A previous result was assigned to the same register - we'll our definition */
2974 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2975 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2976 if (POINTER_SET (dic))
2982 if (IS_SYMOP (IC_RIGHT (dic)) &&
2983 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2984 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2986 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2991 if (IS_SYMOP (IC_LEFT (dic)) &&
2992 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2993 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2995 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3000 if (POINTER_SET (dic) &&
3001 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3003 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3011 return 0; /* did not find */
3014 /* This code is taken from the hc08 port. Do not know
3015 * if it fits for pic16, but I leave it here just in case */
3017 /* if assignment then check that right is not a bit */
3018 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3019 sym_link *etype = operandType (IC_RIGHT (dic));
3021 if (IS_BITFIELD (etype)) {
3022 /* if result is a bit too then it's ok */
3023 etype = operandType (IC_RESULT (dic));
3024 if (!IS_BITFIELD (etype)) {
3025 debugLog(" %d bitfields\n");
3032 /* if the result is on stack or iaccess then it must be
3033 the same atleast one of the operands */
3034 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3035 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3037 /* the operation has only one symbol
3038 operator then we can pack */
3039 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3040 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3043 if (!((IC_LEFT (dic) &&
3044 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3046 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3050 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3051 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3052 /* found the definition */
3053 /* replace the result with the result of */
3054 /* this assignment and remove this assignment */
3055 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3056 IC_RESULT (dic) = IC_RESULT (ic);
3058 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3060 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3062 /* delete from liverange table also
3063 delete from all the points inbetween and the new
3065 for (sic = dic; sic != ic; sic = sic->next)
3067 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3068 if (IS_ITEMP (IC_RESULT (dic)))
3069 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3072 remiCodeFromeBBlock (ebp, ic);
3073 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3075 debugLog(" %d\n", __LINE__ );
3076 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3077 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3085 #define NO_packRegsForAccUse
3086 #define NO_packRegsForSupport
3087 #define NO_packRegsForOneuse
3088 #define NO_cast_peep
3093 #ifndef NO_packRegsForSupport
3094 /*-----------------------------------------------------------------*/
3095 /* findAssignToSym : scanning backwards looks for first assig found */
3096 /*-----------------------------------------------------------------*/
3098 findAssignToSym (operand * op, iCode * ic)
3102 debugLog ("%s\n", __FUNCTION__);
3103 for (dic = ic->prev; dic; dic = dic->prev)
3106 /* if definition by assignment */
3107 if (dic->op == '=' &&
3108 !POINTER_SET (dic) &&
3109 IC_RESULT (dic)->key == op->key
3110 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3114 /* we are interested only if defined in far space */
3115 /* or in stack space in case of + & - */
3117 /* if assigned to a non-symbol then return
3119 if (!IS_SYMOP (IC_RIGHT (dic)))
3122 /* if the symbol is in far space then
3124 if (isOperandInFarSpace (IC_RIGHT (dic)))
3127 /* for + & - operations make sure that
3128 if it is on the stack it is the same
3129 as one of the three operands */
3130 if ((ic->op == '+' || ic->op == '-') &&
3131 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3133 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3134 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3135 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3143 /* if we find an usage then we cannot delete it */
3144 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3147 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3150 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3154 /* now make sure that the right side of dic
3155 is not defined between ic & dic */
3158 iCode *sic = dic->next;
3160 for (; sic != ic; sic = sic->next)
3161 if (IC_RESULT (sic) &&
3162 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3173 #ifndef NO_packRegsForSupport
3174 /*-----------------------------------------------------------------*/
3175 /* packRegsForSupport :- reduce some registers for support calls */
3176 /*-----------------------------------------------------------------*/
3178 packRegsForSupport (iCode * ic, eBBlock * ebp)
3182 debugLog ("%s\n", __FUNCTION__);
3183 /* for the left & right operand :- look to see if the
3184 left was assigned a true symbol in far space in that
3185 case replace them */
3186 if (IS_ITEMP (IC_LEFT (ic)) &&
3187 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3189 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3195 debugAopGet ("removing left:", IC_LEFT (ic));
3197 /* found it we need to remove it from the
3199 for (sic = dic; sic != ic; sic = sic->next)
3200 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3202 IC_LEFT (ic)->operand.symOperand =
3203 IC_RIGHT (dic)->operand.symOperand;
3204 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3205 remiCodeFromeBBlock (ebp, dic);
3206 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3207 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3211 /* do the same for the right operand */
3214 IS_ITEMP (IC_RIGHT (ic)) &&
3215 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3217 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3223 /* if this is a subtraction & the result
3224 is a true symbol in far space then don't pack */
3225 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3227 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3228 if (IN_FARSPACE (SPEC_OCLS (etype)))
3232 debugAopGet ("removing right:", IC_RIGHT (ic));
3234 /* found it we need to remove it from the
3236 for (sic = dic; sic != ic; sic = sic->next)
3237 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3239 IC_RIGHT (ic)->operand.symOperand =
3240 IC_RIGHT (dic)->operand.symOperand;
3241 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3243 remiCodeFromeBBlock (ebp, dic);
3244 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3245 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3254 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3256 #ifndef NO_packRegsForOneuse
3257 /*-----------------------------------------------------------------*/
3258 /* packRegsForOneuse : - will reduce some registers for single Use */
3259 /*-----------------------------------------------------------------*/
3261 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3266 debugLog ("%s\n", __FUNCTION__);
3267 /* if returning a literal then do nothing */
3271 /* only upto 2 bytes since we cannot predict
3272 the usage of b, & acc */
3273 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3278 /* this routine will mark the a symbol as used in one
3279 instruction use only && if the definition is local
3280 (ie. within the basic block) && has only one definition &&
3281 that definition is either a return value from a
3282 function or does not contain any variables in
3284 uses = bitVectCopy (OP_USES (op));
3285 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3286 if (!bitVectIsZero (uses)) /* has other uses */
3289 /* if it has only one defintion */
3290 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3291 return NULL; /* has more than one definition */
3293 /* get that definition */
3295 hTabItemWithKey (iCodehTab,
3296 bitVectFirstBit (OP_DEFS (op)))))
3299 /* found the definition now check if it is local */
3300 if (dic->seq < ebp->fSeq ||
3301 dic->seq > ebp->lSeq)
3302 return NULL; /* non-local */
3304 /* now check if it is the return from
3306 if (dic->op == CALL || dic->op == PCALL)
3308 if (ic->op != SEND && ic->op != RETURN &&
3309 !POINTER_SET(ic) && !POINTER_GET(ic))
3311 OP_SYMBOL (op)->ruonly = 1;
3318 /* otherwise check that the definition does
3319 not contain any symbols in far space */
3320 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3321 isOperandInFarSpace (IC_RIGHT (dic)) ||
3322 IS_OP_RUONLY (IC_LEFT (ic)) ||
3323 IS_OP_RUONLY (IC_RIGHT (ic)))
3328 /* if pointer set then make sure the pointer
3330 if (POINTER_SET (dic) &&
3331 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3334 if (POINTER_GET (dic) &&
3335 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3340 /* also make sure the intervenening instructions
3341 don't have any thing in far space */
3342 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3345 /* if there is an intervening function call then no */
3346 if (dic->op == CALL || dic->op == PCALL)
3348 /* if pointer set then make sure the pointer
3350 if (POINTER_SET (dic) &&
3351 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3354 if (POINTER_GET (dic) &&
3355 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3358 /* if address of & the result is remat then okay */
3359 if (dic->op == ADDRESS_OF &&
3360 OP_SYMBOL (IC_RESULT (dic))->remat)
3363 /* if operand has size of three or more & this
3364 operation is a '*','/' or '%' then 'b' may
3366 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3367 getSize (operandType (op)) >= 3)
3370 /* if left or right or result is in far space */
3371 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3372 isOperandInFarSpace (IC_RIGHT (dic)) ||
3373 isOperandInFarSpace (IC_RESULT (dic)) ||
3374 IS_OP_RUONLY (IC_LEFT (dic)) ||
3375 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3376 IS_OP_RUONLY (IC_RESULT (dic)))
3382 OP_SYMBOL (op)->ruonly = 1;
3389 /*-----------------------------------------------------------------*/
3390 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3391 /*-----------------------------------------------------------------*/
3393 isBitwiseOptimizable (iCode * ic)
3395 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3396 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3398 debugLog ("%s\n", __FUNCTION__);
3399 /* bitwise operations are considered optimizable
3400 under the following conditions (Jean-Louis VERN)
3412 if (IS_LITERAL (rtype) ||
3413 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3420 #ifndef NO_packRegsForAccUse
3422 /*-----------------------------------------------------------------*/
3423 /* packRegsForAccUse - pack registers for acc use */
3424 /*-----------------------------------------------------------------*/
3426 packRegsForAccUse (iCode * ic)
3430 debugLog ("%s\n", __FUNCTION__);
3432 /* if this is an aggregate, e.g. a one byte char array */
3433 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3436 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3438 /* if + or - then it has to be one byte result */
3439 if ((ic->op == '+' || ic->op == '-')
3440 && getSize (operandType (IC_RESULT (ic))) > 1)
3443 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3444 /* if shift operation make sure right side is not a literal */
3445 if (ic->op == RIGHT_OP &&
3446 (isOperandLiteral (IC_RIGHT (ic)) ||
3447 getSize (operandType (IC_RESULT (ic))) > 1))
3450 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3451 if (ic->op == LEFT_OP &&
3452 (isOperandLiteral (IC_RIGHT (ic)) ||
3453 getSize (operandType (IC_RESULT (ic))) > 1))
3456 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3457 if (IS_BITWISE_OP (ic) &&
3458 getSize (operandType (IC_RESULT (ic))) > 1)
3462 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3463 /* has only one definition */
3464 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3467 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3468 /* has only one use */
3469 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3472 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3473 /* and the usage immediately follows this iCode */
3474 if (!(uic = hTabItemWithKey (iCodehTab,
3475 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3478 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3479 if (ic->next != uic)
3482 /* if it is a conditional branch then we definitely can */
3486 if (uic->op == JUMPTABLE)
3489 /* if the usage is not is an assignment
3490 or an arithmetic / bitwise / shift operation then not */
3491 if (POINTER_SET (uic) &&
3492 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3495 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3496 if (uic->op != '=' &&
3497 !IS_ARITHMETIC_OP (uic) &&
3498 !IS_BITWISE_OP (uic) &&
3499 uic->op != LEFT_OP &&
3500 uic->op != RIGHT_OP)
3503 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3504 /* if used in ^ operation then make sure right is not a
3506 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3509 /* if shift operation make sure right side is not a literal */
3510 if (uic->op == RIGHT_OP &&
3511 (isOperandLiteral (IC_RIGHT (uic)) ||
3512 getSize (operandType (IC_RESULT (uic))) > 1))
3515 if (uic->op == LEFT_OP &&
3516 (isOperandLiteral (IC_RIGHT (uic)) ||
3517 getSize (operandType (IC_RESULT (uic))) > 1))
3520 /* make sure that the result of this icode is not on the
3521 stack, since acc is used to compute stack offset */
3522 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3523 OP_SYMBOL (IC_RESULT (uic))->onStack)
3526 /* if either one of them in far space then we cannot */
3527 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3528 isOperandInFarSpace (IC_LEFT (uic))) ||
3529 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3530 isOperandInFarSpace (IC_RIGHT (uic))))
3533 /* if the usage has only one operand then we can */
3534 if (IC_LEFT (uic) == NULL ||
3535 IC_RIGHT (uic) == NULL)
3538 /* make sure this is on the left side if not
3539 a '+' since '+' is commutative */
3540 if (ic->op != '+' &&
3541 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3545 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3546 /* if one of them is a literal then we can */
3547 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3548 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3549 (getSize (operandType (IC_RESULT (uic))) <= 1))
3551 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3556 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3557 /* if the other one is not on stack then we can */
3558 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3559 (IS_ITEMP (IC_RIGHT (uic)) ||
3560 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3561 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3564 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3565 (IS_ITEMP (IC_LEFT (uic)) ||
3566 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3567 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3573 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3574 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3581 /*-----------------------------------------------------------------*/
3582 /* packForPush - hueristics to reduce iCode for pushing */
3583 /*-----------------------------------------------------------------*/
3585 packForReceive (iCode * ic, eBBlock * ebp)
3589 debugLog ("%s\n", __FUNCTION__);
3590 debugAopGet (" result:", IC_RESULT (ic));
3591 debugAopGet (" left:", IC_LEFT (ic));
3592 debugAopGet (" right:", IC_RIGHT (ic));
3597 for (dic = ic->next; dic; dic = dic->next)
3602 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3603 debugLog (" used on left\n");
3604 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3605 debugLog (" used on right\n");
3606 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3607 debugLog (" used on result\n");
3609 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3610 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3615 debugLog (" hey we can remove this unnecessary assign\n");
3617 /*-----------------------------------------------------------------*/
3618 /* packForPush - hueristics to reduce iCode for pushing */
3619 /*-----------------------------------------------------------------*/
3621 packForPush (iCode * ic, eBBlock * ebp)
3625 debugLog ("%s\n", __FUNCTION__);
3626 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3629 /* must have only definition & one usage */
3630 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3631 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3634 /* find the definition */
3635 if (!(dic = hTabItemWithKey (iCodehTab,
3636 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3639 if (dic->op != '=' || POINTER_SET (dic))
3642 /* we now we know that it has one & only one def & use
3643 and the that the definition is an assignment */
3644 IC_LEFT (ic) = IC_RIGHT (dic);
3646 remiCodeFromeBBlock (ebp, dic);
3647 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3648 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3651 static void printSymType(char * str, sym_link *sl)
3653 if(!pic16_ralloc_debug)return;
3655 debugLog (" %s Symbol type: ",str);
3656 printTypeChain( sl, debugF);
3660 /*-----------------------------------------------------------------*/
3661 /* some debug code to print the symbol S_TYPE. Note that
3662 * the function checkSClass in src/SDCCsymt.c dinks with
3663 * the S_TYPE in ways the PIC port doesn't fully like...*/
3664 /*-----------------------------------------------------------------*/
3665 static void isData(sym_link *sl)
3669 if(!pic16_ralloc_debug)return;
3676 for ( ; sl; sl=sl->next) {
3678 switch (SPEC_SCLS(sl)) {
3679 case S_DATA: fprintf (of, "data "); break;
3680 case S_XDATA: fprintf (of, "xdata "); break;
3681 case S_SFR: fprintf (of, "sfr "); break;
3682 case S_SBIT: fprintf (of, "sbit "); break;
3683 case S_CODE: fprintf (of, "code "); break;
3684 case S_IDATA: fprintf (of, "idata "); break;
3685 case S_PDATA: fprintf (of, "pdata "); break;
3686 case S_LITERAL: fprintf (of, "literal "); break;
3687 case S_STACK: fprintf (of, "stack "); break;
3688 case S_XSTACK: fprintf (of, "xstack "); break;
3689 case S_BIT: fprintf (of, "bit "); break;
3690 case S_EEPROM: fprintf (of, "eeprom "); break;
3699 /*--------------------------------------------------------------------*/
3700 /* pic16_packRegisters - does some transformations to reduce */
3701 /* register pressure */
3703 /*--------------------------------------------------------------------*/
3705 pic16_packRegisters (eBBlock * ebp)
3710 debugLog ("%s\n", __FUNCTION__);
3716 /* look for assignments of the form */
3717 /* iTempNN = TRueSym (someoperation) SomeOperand */
3719 /* TrueSym := iTempNN:1 */
3720 for (ic = ebp->sch; ic; ic = ic->next)
3722 // debugLog("%d\n", __LINE__);
3723 /* find assignment of the form TrueSym := iTempNN:1 */
3724 /* see BUGLOG0001 for workaround with the CAST - VR */
3725 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3726 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3727 change += packRegsForAssign (ic, ebp);
3731 if (POINTER_SET (ic))
3732 debugLog ("pointer is set\n");
3733 debugAopGet (" result:", IC_RESULT (ic));
3734 debugAopGet (" left:", IC_LEFT (ic));
3735 debugAopGet (" right:", IC_RIGHT (ic));
3744 for (ic = ebp->sch; ic; ic = ic->next) {
3746 if(IS_SYMOP ( IC_LEFT(ic))) {
3747 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3749 debugAopGet ("x left:", IC_LEFT (ic));
3751 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3753 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3755 debugLog (" is a pointer\n");
3757 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3758 debugLog (" is a ptr\n");
3760 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3761 debugLog (" is volatile\n");
3765 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3766 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3767 pic16_allocDirReg(IC_LEFT (ic));
3770 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3773 if(IS_SYMOP ( IC_RIGHT(ic))) {
3774 debugAopGet (" right:", IC_RIGHT (ic));
3775 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3778 if(IS_SYMOP ( IC_RESULT(ic))) {
3779 debugAopGet (" result:", IC_RESULT (ic));
3780 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3783 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3784 debugAopGet (" right:", IC_RIGHT (ic));
3785 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3786 // pic16_allocDirReg(IC_RIGHT(ic));
3789 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3790 debugAopGet (" result:", IC_RESULT (ic));
3791 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3792 // pic16_allocDirReg(IC_RESULT(ic));
3796 if (POINTER_SET (ic))
3797 debugLog (" %d - Pointer set\n", __LINE__);
3800 /* if this is an itemp & result of a address of a true sym
3801 then mark this as rematerialisable */
3802 if (ic->op == ADDRESS_OF &&
3803 IS_ITEMP (IC_RESULT (ic)) &&
3804 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3805 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3806 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3809 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3811 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3812 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3813 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3817 /* if straight assignment then carry remat flag if
3818 this is the only definition */
3819 if (ic->op == '=' &&
3820 !POINTER_SET (ic) &&
3821 IS_SYMOP (IC_RIGHT (ic)) &&
3822 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3823 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3825 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3827 OP_SYMBOL (IC_RESULT (ic))->remat =
3828 OP_SYMBOL (IC_RIGHT (ic))->remat;
3829 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3830 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3833 /* if this is a +/- operation with a rematerizable
3834 then mark this as rematerializable as well */
3835 if ((ic->op == '+' || ic->op == '-') &&
3836 (IS_SYMOP (IC_LEFT (ic)) &&
3837 IS_ITEMP (IC_RESULT (ic)) &&
3838 OP_SYMBOL (IC_LEFT (ic))->remat &&
3839 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3840 IS_OP_LITERAL (IC_RIGHT (ic))))
3842 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3844 operandLitValue (IC_RIGHT (ic));
3845 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3846 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3847 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3850 /* mark the pointer usages */
3851 if (POINTER_SET (ic))
3853 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3854 debugLog (" marking as a pointer (set) =>");
3855 debugAopGet (" result:", IC_RESULT (ic));
3857 if (POINTER_GET (ic))
3859 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3860 debugLog (" marking as a pointer (get) =>");
3861 debugAopGet (" left:", IC_LEFT (ic));
3864 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3868 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3869 /* if we are using a symbol on the stack
3870 then we should say pic16_ptrRegReq */
3871 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3872 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3873 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3874 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3875 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3876 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3880 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3881 if (IS_SYMOP (IC_LEFT (ic)))
3882 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3883 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3884 if (IS_SYMOP (IC_RIGHT (ic)))
3885 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3886 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3887 if (IS_SYMOP (IC_RESULT (ic)))
3888 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3889 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3892 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3896 /* if the condition of an if instruction
3897 is defined in the previous instruction then
3898 mark the itemp as a conditional */
3899 if ((IS_CONDITIONAL (ic) ||
3900 ((ic->op == BITWISEAND ||
3903 isBitwiseOptimizable (ic))) &&
3904 ic->next && ic->next->op == IFX &&
3905 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3906 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3909 debugLog (" %d\n", __LINE__);
3910 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3914 debugLog(" %d\n", __LINE__);
3916 #ifndef NO_packRegsForSupport
3917 /* reduce for support function calls */
3918 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3919 packRegsForSupport (ic, ebp);
3922 /* if a parameter is passed, it's in W, so we may not
3923 need to place a copy in a register */
3924 if (ic->op == RECEIVE)
3925 packForReceive (ic, ebp);
3927 #ifndef NO_packRegsForOneuse
3928 /* some cases the redundant moves can
3929 can be eliminated for return statements */
3930 if ((ic->op == RETURN || ic->op == SEND) &&
3931 !isOperandInFarSpace (IC_LEFT (ic)) &&
3933 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3936 #ifndef NO_packRegsForOneuse
3937 /* if pointer set & left has a size more than
3938 one and right is not in far space */
3939 if (POINTER_SET (ic) &&
3940 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3941 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3942 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3943 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3945 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3948 #ifndef NO_packRegsForOneuse
3949 /* if pointer get */
3950 if (POINTER_GET (ic) &&
3951 !isOperandInFarSpace (IC_RESULT (ic)) &&
3952 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3953 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3954 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3956 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3957 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3960 #ifndef NO_cast_peep
3961 /* if this is cast for intergral promotion then
3962 check if only use of the definition of the
3963 operand being casted/ if yes then replace
3964 the result of that arithmetic operation with
3965 this result and get rid of the cast */
3966 if (ic->op == CAST) {
3968 sym_link *fromType = operandType (IC_RIGHT (ic));
3969 sym_link *toType = operandType (IC_LEFT (ic));
3971 debugLog (" %d - casting\n", __LINE__);
3973 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3974 getSize (fromType) != getSize (toType)) {
3977 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3980 if (IS_ARITHMETIC_OP (dic)) {
3981 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3983 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3984 IC_RESULT (dic) = IC_RESULT (ic);
3985 remiCodeFromeBBlock (ebp, ic);
3986 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3987 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3988 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3992 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3996 /* if the type from and type to are the same
3997 then if this is the only use then packit */
3998 if (compareType (operandType (IC_RIGHT (ic)),
3999 operandType (IC_LEFT (ic))) == 1) {
4001 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4004 debugLog(" %d\n", __LINE__);
4006 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4007 IC_RESULT (dic) = IC_RESULT (ic);
4008 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4009 remiCodeFromeBBlock (ebp, ic);
4010 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4011 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4019 iTempNN := (some variable in farspace) V1
4024 if (ic->op == IPUSH)
4026 packForPush (ic, ebp);
4030 #ifndef NO_packRegsForAccUse
4031 /* pack registers for accumulator use, when the
4032 result of an arithmetic or bit wise operation
4033 has only one use, that use is immediately following
4034 the defintion and the using iCode has only one
4035 operand or has two operands but one is literal &
4036 the result of that operation is not on stack then
4037 we can leave the result of this operation in acc:b
4039 if ((IS_ARITHMETIC_OP (ic)
4041 || IS_BITWISE_OP (ic)
4043 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4046 IS_ITEMP (IC_RESULT (ic)) &&
4047 getSize (operandType (IC_RESULT (ic))) <= 1)
4049 packRegsForAccUse (ic);
4056 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4060 if (!pic16_ralloc_debug || !debugF)
4063 for (i = 0; i < count; i++)
4065 fprintf (debugF, "\n----------------------------------------------------------------\n");
4066 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4067 ebbs[i]->entryLabel->name,
4070 ebbs[i]->isLastInLoop);
4071 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4076 fprintf (debugF, "visited %d : hasFcall = %d\n",
4080 fprintf (debugF, "\ndefines bitVector :");
4081 bitVectDebugOn (ebbs[i]->defSet, debugF);
4082 fprintf (debugF, "\nlocal defines bitVector :");
4083 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4084 fprintf (debugF, "\npointers Set bitvector :");
4085 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4086 fprintf (debugF, "\nin pointers Set bitvector :");
4087 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4088 fprintf (debugF, "\ninDefs Set bitvector :");
4089 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4090 fprintf (debugF, "\noutDefs Set bitvector :");
4091 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4092 fprintf (debugF, "\nusesDefs Set bitvector :");
4093 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4094 fprintf (debugF, "\n----------------------------------------------------------------\n");
4095 printiCChain (ebbs[i]->sch, debugF);
4098 /*-----------------------------------------------------------------*/
4099 /* pic16_assignRegisters - assigns registers to each live range as need */
4100 /*-----------------------------------------------------------------*/
4102 pic16_assignRegisters (eBBlock ** ebbs, int count)
4107 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4108 debugLog ("\nebbs before optimizing:\n");
4109 dumpEbbsToDebug (ebbs, count);
4111 setToNull ((void *) &_G.funcrUsed);
4112 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4115 /* change assignments this will remove some
4116 live ranges reducing some register pressure */
4117 for (i = 0; i < count; i++)
4118 pic16_packRegisters (ebbs[i]);
4125 debugLog("dir registers allocated so far:\n");
4126 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4129 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4130 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4131 reg = hTabNextItem(dynDirectRegNames, &hkey);
4136 /* liveranges probably changed by register packing
4137 so we compute them again */
4138 recomputeLiveRanges (ebbs, count);
4140 if (options.dump_pack)
4141 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4143 /* first determine for each live range the number of
4144 registers & the type of registers required for each */
4147 /* and serially allocate registers */
4148 serialRegAssign (ebbs, count);
4150 // debugLog ("ebbs after serialRegAssign:\n");
4151 // dumpEbbsToDebug (ebbs, count);
4154 //pic16_freeAllRegs();
4156 /* if stack was extended then tell the user */
4159 /* werror(W_TOOMANY_SPILS,"stack", */
4160 /* _G.stackExtend,currFunc->name,""); */
4166 /* werror(W_TOOMANY_SPILS,"data space", */
4167 /* _G.dataExtend,currFunc->name,""); */
4171 /* after that create the register mask
4172 for each of the instruction */
4173 createRegMask (ebbs, count);
4175 /* redo that offsets for stacked automatic variables */
4176 redoStackOffsets ();
4178 if (options.dump_rassgn)
4179 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4181 /* now get back the chain */
4182 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4184 debugLog ("ebbs after optimizing:\n");
4185 dumpEbbsToDebug (ebbs, count);
4190 /* free up any _G.stackSpil locations allocated */
4191 applyToSet (_G.stackSpil, deallocStackSpil);
4193 setToNull ((void *) &_G.stackSpil);
4194 setToNull ((void *) &_G.spiltSet);
4195 /* mark all registers as free */
4196 pic16_freeAllRegs ();
4198 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");