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;
80 static hTab *dynDirectRegNames=NULL;
81 static hTab *dynAllocRegNames=NULL;
82 static hTab *dynProcRegNames=NULL;
83 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 extern set *sectNames;
87 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
88 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
89 set *pic16_equ_data=NULL; /* registers used by equates */
90 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
92 set *pic16_builtin_functions=NULL;
94 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
95 static int rDirectIdx=0;
97 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
99 int pic16_Gstack_base_addr=0; /* The starting address of registers that
100 * are used to pass and return parameters */
105 static void spillThis (symbol *);
106 int pic16_ralloc_debug = 0;
107 static FILE *debugF = NULL;
108 /*-----------------------------------------------------------------*/
109 /* debugLog - open a file for debugging information */
110 /*-----------------------------------------------------------------*/
111 //static void debugLog(char *inst,char *fmt, ...)
113 debugLog (char *fmt,...)
115 static int append = 0; // First time through, open the file without append.
118 //char *bufferP=buffer;
121 if (!pic16_ralloc_debug || !dstFileName)
127 /* create the file name */
128 strcpy (buffer, dstFileName);
129 strcat (buffer, ".d");
131 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
133 werror (E_FILE_OPEN_ERR, buffer);
136 append = 1; // Next time debubLog is called, we'll append the debug info
142 vsprintf (buffer, fmt, ap);
144 fprintf (debugF, "%s", buffer);
146 while (isspace(*bufferP)) bufferP++;
148 if (bufferP && *bufferP)
149 lineCurr = (lineCurr ?
150 connectLine(lineCurr,newLineNode(lb)) :
151 (lineHead = newLineNode(lb)));
152 lineCurr->isInline = _G.inLine;
153 lineCurr->isDebug = _G.debugLine;
162 if(!pic16_ralloc_debug)return;
165 fputc ('\n', debugF);
167 /*-----------------------------------------------------------------*/
168 /* debugLogClose - closes the debug log file (if opened) */
169 /*-----------------------------------------------------------------*/
179 #define AOP(op) op->aop
182 debugAopGet (char *str, operand * op)
184 if(!pic16_ralloc_debug)return NULL;
189 printOperand (op, debugF);
196 decodeOp (unsigned int op)
198 if (op < 128 && op > ' ') {
199 buffer[0] = (op & 0xff);
205 case IDENTIFIER: return "IDENTIFIER";
206 case TYPE_NAME: return "TYPE_NAME";
207 case CONSTANT: return "CONSTANT";
208 case STRING_LITERAL: return "STRING_LITERAL";
209 case SIZEOF: return "SIZEOF";
210 case PTR_OP: return "PTR_OP";
211 case INC_OP: return "INC_OP";
212 case DEC_OP: return "DEC_OP";
213 case LEFT_OP: return "LEFT_OP";
214 case RIGHT_OP: return "RIGHT_OP";
215 case LE_OP: return "LE_OP";
216 case GE_OP: return "GE_OP";
217 case EQ_OP: return "EQ_OP";
218 case NE_OP: return "NE_OP";
219 case AND_OP: return "AND_OP";
220 case OR_OP: return "OR_OP";
221 case MUL_ASSIGN: return "MUL_ASSIGN";
222 case DIV_ASSIGN: return "DIV_ASSIGN";
223 case MOD_ASSIGN: return "MOD_ASSIGN";
224 case ADD_ASSIGN: return "ADD_ASSIGN";
225 case SUB_ASSIGN: return "SUB_ASSIGN";
226 case LEFT_ASSIGN: return "LEFT_ASSIGN";
227 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
228 case AND_ASSIGN: return "AND_ASSIGN";
229 case XOR_ASSIGN: return "XOR_ASSIGN";
230 case OR_ASSIGN: return "OR_ASSIGN";
231 case TYPEDEF: return "TYPEDEF";
232 case EXTERN: return "EXTERN";
233 case STATIC: return "STATIC";
234 case AUTO: return "AUTO";
235 case REGISTER: return "REGISTER";
236 case CODE: return "CODE";
237 case EEPROM: return "EEPROM";
238 case INTERRUPT: return "INTERRUPT";
239 case SFR: return "SFR";
240 case AT: return "AT";
241 case SBIT: return "SBIT";
242 case REENTRANT: return "REENTRANT";
243 case USING: return "USING";
244 case XDATA: return "XDATA";
245 case DATA: return "DATA";
246 case IDATA: return "IDATA";
247 case PDATA: return "PDATA";
248 case VAR_ARGS: return "VAR_ARGS";
249 case CRITICAL: return "CRITICAL";
250 case NONBANKED: return "NONBANKED";
251 case BANKED: return "BANKED";
252 case CHAR: return "CHAR";
253 case SHORT: return "SHORT";
254 case INT: return "INT";
255 case LONG: return "LONG";
256 case SIGNED: return "SIGNED";
257 case UNSIGNED: return "UNSIGNED";
258 case FLOAT: return "FLOAT";
259 case DOUBLE: return "DOUBLE";
260 case CONST: return "CONST";
261 case VOLATILE: return "VOLATILE";
262 case VOID: return "VOID";
263 case BIT: return "BIT";
264 case STRUCT: return "STRUCT";
265 case UNION: return "UNION";
266 case ENUM: return "ENUM";
267 case ELIPSIS: return "ELIPSIS";
268 case RANGE: return "RANGE";
269 case FAR: return "FAR";
270 case CASE: return "CASE";
271 case DEFAULT: return "DEFAULT";
272 case IF: return "IF";
273 case ELSE: return "ELSE";
274 case SWITCH: return "SWITCH";
275 case WHILE: return "WHILE";
276 case DO: return "DO";
277 case FOR: return "FOR";
278 case GOTO: return "GOTO";
279 case CONTINUE: return "CONTINUE";
280 case BREAK: return "BREAK";
281 case RETURN: return "RETURN";
282 case INLINEASM: return "INLINEASM";
283 case IFX: return "IFX";
284 case ADDRESS_OF: return "ADDRESS_OF";
285 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
286 case SPIL: return "SPIL";
287 case UNSPIL: return "UNSPIL";
288 case GETHBIT: return "GETHBIT";
289 case BITWISEAND: return "BITWISEAND";
290 case UNARYMINUS: return "UNARYMINUS";
291 case IPUSH: return "IPUSH";
292 case IPOP: return "IPOP";
293 case PCALL: return "PCALL";
294 case ENDFUNCTION: return "ENDFUNCTION";
295 case JUMPTABLE: return "JUMPTABLE";
296 case RRC: return "RRC";
297 case RLC: return "RLC";
298 case CAST: return "CAST";
299 case CALL: return "CALL";
300 case PARAM: return "PARAM ";
301 case NULLOP: return "NULLOP";
302 case BLOCK: return "BLOCK";
303 case LABEL: return "LABEL";
304 case RECEIVE: return "RECEIVE";
305 case SEND: return "SEND";
307 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
311 /*-----------------------------------------------------------------*/
312 /*-----------------------------------------------------------------*/
314 debugLogRegType (short type)
316 if(!pic16_ralloc_debug)return NULL;
318 case REG_GPR: return "REG_GPR";
319 case REG_PTR: return "REG_PTR";
320 case REG_CND: return "REG_CND";
322 sprintf (buffer, "unknown reg type %d", type);
327 /*-----------------------------------------------------------------*/
328 /*-----------------------------------------------------------------*/
329 static int regname2key(char const *name)
338 key += (*name++) + 1;
342 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
346 /*-----------------------------------------------------------------*/
347 /* newReg - allocate and init memory for a new register */
348 /*-----------------------------------------------------------------*/
349 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
354 dReg = Safe_calloc(1,sizeof(regs));
356 dReg->pc_type = pc_type;
359 dReg->name = Safe_strdup(name);
361 sprintf(buffer,"r0x%02X", dReg->rIdx);
364 dReg->name = Safe_strdup(buffer);
372 if(type == REG_SFR) {
374 dReg->address = rIdx;
375 dReg->accessBank = 1;
379 dReg->accessBank = 0;
382 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
386 dReg->reg_alias = NULL;
387 dReg->reglives.usedpFlows = newSet();
388 dReg->reglives.assignedpFlows = newSet();
391 if(!(type == REG_SFR && alias == 0x80))
392 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
397 /*-----------------------------------------------------------------*/
398 /* regWithIdx - Search through a set of registers that matches idx */
399 /*-----------------------------------------------------------------*/
401 regWithIdx (set *dRegs, int idx, int fixed)
405 for (dReg = setFirstItem(dRegs) ; dReg ;
406 dReg = setNextItem(dRegs)) {
408 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
416 /*-----------------------------------------------------------------*/
417 /* regFindFree - Search for a free register in a set of registers */
418 /*-----------------------------------------------------------------*/
420 regFindFree (set *dRegs)
424 for (dReg = setFirstItem(dRegs) ; dReg ;
425 dReg = setNextItem(dRegs)) {
427 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
428 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
437 /*-----------------------------------------------------------------*/
438 /* pic16_initStack - allocate registers for a pseudo stack */
439 /*-----------------------------------------------------------------*/
440 void pic16_initStack(int base_address, int size)
445 pic16_Gstack_base_addr = base_address;
446 //fprintf(stderr,"initStack");
448 for(i = 0; i<size; i++)
449 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
452 /*-----------------------------------------------------------------*
453 *-----------------------------------------------------------------*/
455 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
457 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
459 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
461 reg->wasUsed = 0; // we do not know if they are going to be used at all
462 reg->accessBank = 1; // implicit add access Bank
464 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
466 return addSet(&pic16_dynProcessorRegs, reg);
469 /*-----------------------------------------------------------------*
470 *-----------------------------------------------------------------*/
473 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
475 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
477 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
481 return addSet(&pic16_dynInternalRegs,reg);
486 /*-----------------------------------------------------------------*/
487 /* allocReg - allocates register of given type */
488 /*-----------------------------------------------------------------*/
490 allocReg (short type)
495 if(dynrIdx > pic16_nRegs)
499 /* try to reuse some unused registers */
500 reg = regFindFree( pic16_dynAllocRegs );
503 // fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
507 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
508 // addSet(&pic16_dynAllocRegs, reg);
511 addSet(&pic16_dynAllocRegs, reg);
512 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
516 debugLog ("%s of type %s for register rIdx: %d\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1);
518 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
519 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
522 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
523 reg->isLocal = 1; /* this is a local frame register */
528 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
529 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
532 return (reg); // addSet(&pic16_dynAllocRegs,reg);
537 /*-----------------------------------------------------------------*/
538 /* pic16_dirregWithName - search for register by name */
539 /*-----------------------------------------------------------------*/
541 pic16_dirregWithName (char *name)
549 /* hash the name to get a key */
551 hkey = regname2key(name);
553 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
555 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
559 if(STRCASECMP(reg->name, name) == 0) {
560 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
564 reg = hTabNextItemWK (dynDirectRegNames);
568 return NULL; // name wasn't found in the hash table
571 /*-----------------------------------------------------------------*/
572 /* pic16_allocregWithName - search for register by name */
573 /*-----------------------------------------------------------------*/
575 pic16_allocregWithName (char *name)
583 /* hash the name to get a key */
585 hkey = regname2key(name);
587 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
589 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
593 if(STRCASECMP(reg->name, name) == 0) {
597 reg = hTabNextItemWK (dynAllocRegNames);
601 return NULL; // name wasn't found in the hash table
606 /*-----------------------------------------------------------------*/
607 /* pic16_procregWithName - search for register by name */
608 /*-----------------------------------------------------------------*/
610 pic16_procregWithName (char *name)
618 /* hash the name to get a key */
620 hkey = regname2key(name);
622 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
624 reg = hTabFirstItemWK(dynProcRegNames, hkey);
628 if(STRCASECMP(reg->name, name) == 0) {
632 reg = hTabNextItemWK (dynProcRegNames);
636 return NULL; // name wasn't found in the hash table
640 regs *pic16_regWithName(char *name)
644 reg = pic16_dirregWithName( name );
647 reg = pic16_procregWithName( name );
650 reg = pic16_allocregWithName( name );
657 /*-----------------------------------------------------------------*/
658 /* pic16_allocDirReg - allocates register of given type */
659 /*-----------------------------------------------------------------*/
661 pic16_allocDirReg (operand *op )
667 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
668 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
672 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
674 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
675 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
678 if(pic16_debug_verbose) {
679 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
680 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
681 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
682 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
683 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
684 IN_STACK( OP_SYM_ETYPE(op)),
685 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
686 IS_REGPARM(OP_SYM_ETYPE(op)),
689 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
690 OP_SYMBOL(op)->name);
698 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
699 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
703 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
704 if(pic16_debug_verbose)
706 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
707 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
712 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
713 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
716 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
717 debugLog(" %d const char\n",__LINE__);
718 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
719 // fprintf(stderr, " %d const char\n",__LINE__);
720 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
724 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
725 if (IS_CODE ( OP_SYM_ETYPE(op)) )
726 debugLog(" %d code space\n",__LINE__);
728 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
729 debugLog(" %d integral\n",__LINE__);
731 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
732 debugLog(" %d literal\n",__LINE__);
734 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
735 debugLog(" %d specifier\n",__LINE__);
737 debugAopGet(NULL, op);
741 reg = pic16_dirregWithName(name);
745 int regtype = REG_GPR;
747 /* if this is at an absolute address, then get the address. */
748 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
749 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
750 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
753 /* Register wasn't found in hash, so let's create
754 * a new one and put it in the hash table AND in the
755 * dynDirectRegNames set */
756 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
757 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
762 if(OP_SYMBOL(op)->onStack) {
763 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
764 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
767 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
768 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
771 if(pic16_debug_verbose)
773 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
774 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
775 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
776 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
777 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
778 IN_STACK( OP_SYM_ETYPE(op)),
779 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
781 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
782 OP_SYMBOL(op)->name);
787 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
788 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
791 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
792 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
793 // reg->type = REG_SFR;
796 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
797 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
798 addSet(&pic16_dynDirectBitRegs, reg);
801 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
802 // addSet(&pic16_dynDirectRegs, reg);
804 checkAddReg(&pic16_dynDirectRegs, reg);
808 // debugLog (" -- %s is declared at address 0x30000x\n",name);
809 return (reg); /* This was NULL before, but since we found it
810 * why not just return it?! */
813 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
815 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
817 /* work around for user defined registers in access bank */
818 if((reg->address>= 0x00 && reg->address < 0x80)
819 || (reg->address >= 0xf80 && reg->address <= 0xfff))
822 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
828 /*-----------------------------------------------------------------*/
829 /* pic16_allocRegByName - allocates register of given type */
830 /*-----------------------------------------------------------------*/
832 pic16_allocRegByName (char *name, int size, operand *op)
838 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
842 /* First, search the hash table to see if there is a register with this name */
843 reg = pic16_dirregWithName(name);
847 /* Register wasn't found in hash, so let's create
848 * a new one and put it in the hash table AND in the
849 * dynDirectRegNames set */
851 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
853 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
855 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
856 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
858 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
859 addSet(&pic16_dynDirectRegs, reg);
865 /*-----------------------------------------------------------------*/
866 /* RegWithIdx - returns pointer to register with index number */
867 /*-----------------------------------------------------------------*/
868 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
873 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
874 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
879 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
881 debugLog ("Found a Dynamic Register!\n");
884 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
885 debugLog ("Found a Direct Register!\n");
891 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
892 debugLog ("Found a Stack Register!\n");
897 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
898 debugLog ("Found a Processor Register!\n");
912 /*-----------------------------------------------------------------*/
913 /* pic16_regWithIdx - returns pointer to register with index number*/
914 /*-----------------------------------------------------------------*/
916 pic16_regWithIdx (int idx)
920 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
923 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
927 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
934 /*-----------------------------------------------------------------*/
935 /* pic16_regWithIdx - returns pointer to register with index number */
936 /*-----------------------------------------------------------------*/
938 pic16_allocWithIdx (int idx)
943 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
944 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
946 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
948 debugLog ("Found a Dynamic Register!\n");
949 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
950 debugLog ("Found a Stack Register!\n");
951 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
952 debugLog ("Found a Processor Register!\n");
953 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
954 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
955 debugLog ("Found an Internal Register!\n");
958 debugLog ("Dynamic Register not found\n");
961 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
962 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
963 "regWithIdx not found");
973 /*-----------------------------------------------------------------*/
974 /*-----------------------------------------------------------------*/
976 pic16_findFreeReg(short type)
983 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
985 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
989 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1001 /*-----------------------------------------------------------------*/
1002 /* freeReg - frees a register */
1003 /*-----------------------------------------------------------------*/
1005 freeReg (regs * reg)
1007 debugLog ("%s\n", __FUNCTION__);
1008 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1013 /*-----------------------------------------------------------------*/
1014 /* nFreeRegs - returns number of free registers */
1015 /*-----------------------------------------------------------------*/
1017 nFreeRegs (int type)
1023 /* although I fixed the register allocation/freeing scheme
1024 * the for loop below doesn't give valid results. I do not
1025 * know why yet. -- VR 10-Jan-2003 */
1030 /* dynamically allocate as many as we need and worry about
1031 * fitting them into a PIC later */
1033 debugLog ("%s\n", __FUNCTION__);
1035 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1036 if((reg->type == type) && reg->isFree)nfr++;
1038 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1042 /*-----------------------------------------------------------------*/
1043 /* nfreeRegsType - free registers with type */
1044 /*-----------------------------------------------------------------*/
1046 nfreeRegsType (int type)
1049 debugLog ("%s\n", __FUNCTION__);
1050 if (type == REG_PTR)
1052 if ((nfr = nFreeRegs (type)) == 0)
1053 return nFreeRegs (REG_GPR);
1056 return nFreeRegs (type);
1059 static void writeSetUsedRegs(FILE *of, set *dRegs)
1064 for (dReg = setFirstItem(dRegs) ; dReg ;
1065 dReg = setNextItem(dRegs)) {
1068 fprintf (of, "\t%s\n",dReg->name);
1074 extern void pic16_groupRegistersInSection(set *regset);
1076 extern void pic16_dump_equates(FILE *of, set *equs);
1077 //extern void pic16_dump_map(void);
1078 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1079 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1080 extern void pic16_dump_int_registers(FILE *of, set *section);
1081 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1083 extern void pic16_dump_gsection(FILE *of, set *sections);
1085 static void packBits(set *bregs)
1089 regs *bitfield=NULL;
1090 regs *relocbitfield=NULL;
1096 for (regset = bregs ; regset ;
1097 regset = regset->next) {
1099 breg = regset->item;
1100 breg->isBitField = 1;
1101 //fprintf(stderr,"bit reg: %s\n",breg->name);
1104 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1106 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1107 breg->rIdx = breg->address & 7;
1108 breg->address >>= 3;
1111 sprintf (buffer, "fbitfield%02x", breg->address);
1112 //fprintf(stderr,"new bit field\n");
1113 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1114 bitfield->isBitField = 1;
1115 bitfield->isFixed = 1;
1116 bitfield->address = breg->address;
1117 addSet(&pic16_dynDirectRegs,bitfield);
1118 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1120 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1123 breg->reg_alias = bitfield;
1127 if(!relocbitfield || bit_no >7) {
1130 sprintf (buffer, "bitfield%d", byte_no);
1131 //fprintf(stderr,"new relocatable bit field\n");
1132 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1133 relocbitfield->isBitField = 1;
1134 addSet(&pic16_dynDirectRegs,relocbitfield);
1135 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1139 breg->reg_alias = relocbitfield;
1140 breg->address = rDirectIdx; /* byte_no; */
1141 breg->rIdx = bit_no++;
1147 void pic16_writeUsedRegs(FILE *of)
1149 packBits(pic16_dynDirectBitRegs);
1151 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1152 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1154 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1155 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1157 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1158 pic16_groupRegistersInSection(pic16_dynStackRegs);
1160 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1161 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1163 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1164 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1166 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1167 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1171 pic16_dump_equates(of, pic16_equ_data);
1173 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1174 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1176 /* dump initialised data */
1177 pic16_dump_isection(of, rel_idataSymSet, 0);
1178 pic16_dump_isection(of, fix_idataSymSet, 1);
1180 /* dump internal registers */
1181 pic16_dump_int_registers(of, pic16_int_regs);
1183 /* dump generic section variables */
1184 pic16_dump_gsection(of, sectNames);
1186 /* dump other variables */
1187 pic16_dump_usection(of, pic16_rel_udata, 0);
1188 pic16_dump_usection(of, pic16_fix_udata, 1);
1193 /*-----------------------------------------------------------------*/
1194 /* computeSpillable - given a point find the spillable live ranges */
1195 /*-----------------------------------------------------------------*/
1197 computeSpillable (iCode * ic)
1201 debugLog ("%s\n", __FUNCTION__);
1202 /* spillable live ranges are those that are live at this
1203 point . the following categories need to be subtracted
1205 a) - those that are already spilt
1206 b) - if being used by this one
1207 c) - defined by this one */
1209 spillable = bitVectCopy (ic->rlive);
1211 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1213 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1214 bitVectUnSetBit (spillable, ic->defKey);
1215 spillable = bitVectIntersect (spillable, _G.regAssigned);
1220 /*-----------------------------------------------------------------*/
1221 /* noSpilLoc - return true if a variable has no spil location */
1222 /*-----------------------------------------------------------------*/
1224 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1226 debugLog ("%s\n", __FUNCTION__);
1227 return (sym->usl.spillLoc ? 0 : 1);
1230 /*-----------------------------------------------------------------*/
1231 /* hasSpilLoc - will return 1 if the symbol has spil location */
1232 /*-----------------------------------------------------------------*/
1234 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1236 debugLog ("%s\n", __FUNCTION__);
1237 return (sym->usl.spillLoc ? 1 : 0);
1240 /*-----------------------------------------------------------------*/
1241 /* directSpilLoc - will return 1 if the splilocation is in direct */
1242 /*-----------------------------------------------------------------*/
1244 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1246 debugLog ("%s\n", __FUNCTION__);
1247 if (sym->usl.spillLoc &&
1248 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1254 /*-----------------------------------------------------------------*/
1255 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1256 /* but is not used as a pointer */
1257 /*-----------------------------------------------------------------*/
1259 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1261 debugLog ("%s\n", __FUNCTION__);
1262 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1265 /*-----------------------------------------------------------------*/
1266 /* rematable - will return 1 if the remat flag is set */
1267 /*-----------------------------------------------------------------*/
1269 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1271 debugLog ("%s\n", __FUNCTION__);
1275 /*-----------------------------------------------------------------*/
1276 /* notUsedInRemaining - not used or defined in remain of the block */
1277 /*-----------------------------------------------------------------*/
1279 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1281 debugLog ("%s\n", __FUNCTION__);
1282 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1283 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1286 /*-----------------------------------------------------------------*/
1287 /* allLRs - return true for all */
1288 /*-----------------------------------------------------------------*/
1290 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1292 debugLog ("%s\n", __FUNCTION__);
1296 /*-----------------------------------------------------------------*/
1297 /* liveRangesWith - applies function to a given set of live range */
1298 /*-----------------------------------------------------------------*/
1300 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1301 eBBlock * ebp, iCode * ic)
1306 debugLog ("%s\n", __FUNCTION__);
1307 if (!lrs || !lrs->size)
1310 for (i = 1; i < lrs->size; i++)
1313 if (!bitVectBitValue (lrs, i))
1316 /* if we don't find it in the live range
1317 hash table we are in serious trouble */
1318 if (!(sym = hTabItemWithKey (liveRanges, i)))
1320 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1321 "liveRangesWith could not find liveRange");
1325 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1326 addSetHead (&rset, sym);
1333 /*-----------------------------------------------------------------*/
1334 /* leastUsedLR - given a set determines which is the least used */
1335 /*-----------------------------------------------------------------*/
1337 leastUsedLR (set * sset)
1339 symbol *sym = NULL, *lsym = NULL;
1341 debugLog ("%s\n", __FUNCTION__);
1342 sym = lsym = setFirstItem (sset);
1347 for (; lsym; lsym = setNextItem (sset))
1350 /* if usage is the same then prefer
1351 the spill the smaller of the two */
1352 if (lsym->used == sym->used)
1353 if (getSize (lsym->type) < getSize (sym->type))
1357 if (lsym->used < sym->used)
1362 setToNull ((void *) &sset);
1367 /*-----------------------------------------------------------------*/
1368 /* noOverLap - will iterate through the list looking for over lap */
1369 /*-----------------------------------------------------------------*/
1371 noOverLap (set * itmpStack, symbol * fsym)
1374 debugLog ("%s\n", __FUNCTION__);
1377 for (sym = setFirstItem (itmpStack); sym;
1378 sym = setNextItem (itmpStack))
1380 if (sym->liveTo > fsym->liveFrom)
1388 /*-----------------------------------------------------------------*/
1389 /* isFree - will return 1 if the a free spil location is found */
1390 /*-----------------------------------------------------------------*/
1395 V_ARG (symbol **, sloc);
1396 V_ARG (symbol *, fsym);
1398 debugLog ("%s\n", __FUNCTION__);
1399 /* if already found */
1403 /* if it is free && and the itmp assigned to
1404 this does not have any overlapping live ranges
1405 with the one currently being assigned and
1406 the size can be accomodated */
1408 noOverLap (sym->usl.itmpStack, fsym) &&
1409 getSize (sym->type) >= getSize (fsym->type))
1418 /*-----------------------------------------------------------------*/
1419 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1420 /*-----------------------------------------------------------------*/
1422 spillLRWithPtrReg (symbol * forSym)
1428 debugLog ("%s\n", __FUNCTION__);
1429 if (!_G.regAssigned ||
1430 bitVectIsZero (_G.regAssigned))
1433 r0 = pic16_regWithIdx (R0_IDX);
1434 r1 = pic16_regWithIdx (R1_IDX);
1436 /* for all live ranges */
1437 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1438 lrsym = hTabNextItem (liveRanges, &k))
1442 /* if no registers assigned to it or
1444 /* if it does not overlap with this then
1445 not need to spill it */
1447 if (lrsym->isspilt || !lrsym->nRegs ||
1448 (lrsym->liveTo < forSym->liveFrom))
1451 /* go thru the registers : if it is either
1452 r0 or r1 then spil it */
1453 for (j = 0; j < lrsym->nRegs; j++)
1454 if (lrsym->regs[j] == r0 ||
1455 lrsym->regs[j] == r1)
1464 /*-----------------------------------------------------------------*/
1465 /* createStackSpil - create a location on the stack to spil */
1466 /*-----------------------------------------------------------------*/
1468 createStackSpil (symbol * sym)
1470 symbol *sloc = NULL;
1471 int useXstack, model, noOverlay;
1473 char slocBuffer[30];
1474 debugLog ("%s\n", __FUNCTION__);
1476 /* first go try and find a free one that is already
1477 existing on the stack */
1478 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1480 /* found a free one : just update & return */
1481 sym->usl.spillLoc = sloc;
1484 addSetHead (&sloc->usl.itmpStack, sym);
1488 /* could not then have to create one , this is the hard part
1489 we need to allocate this on the stack : this is really a
1490 hack!! but cannot think of anything better at this time */
1492 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1494 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1495 __FILE__, __LINE__);
1499 sloc = newiTemp (slocBuffer);
1501 /* set the type to the spilling symbol */
1502 sloc->type = copyLinkChain (sym->type);
1503 sloc->etype = getSpec (sloc->type);
1504 SPEC_SCLS (sloc->etype) = S_DATA;
1505 SPEC_EXTR (sloc->etype) = 0;
1506 SPEC_STAT (sloc->etype) = 0;
1508 /* we don't allow it to be allocated`
1509 onto the external stack since : so we
1510 temporarily turn it off ; we also
1511 turn off memory model to prevent
1512 the spil from going to the external storage
1513 and turn off overlaying
1516 useXstack = options.useXstack;
1517 model = options.model;
1518 noOverlay = options.noOverlay;
1519 options.noOverlay = 1;
1520 options.model = options.useXstack = 0;
1524 options.useXstack = useXstack;
1525 options.model = model;
1526 options.noOverlay = noOverlay;
1527 sloc->isref = 1; /* to prevent compiler warning */
1529 /* if it is on the stack then update the stack */
1530 if (IN_STACK (sloc->etype))
1532 currFunc->stack += getSize (sloc->type);
1533 _G.stackExtend += getSize (sloc->type);
1536 _G.dataExtend += getSize (sloc->type);
1538 /* add it to the _G.stackSpil set */
1539 addSetHead (&_G.stackSpil, sloc);
1540 sym->usl.spillLoc = sloc;
1543 /* add it to the set of itempStack set
1544 of the spill location */
1545 addSetHead (&sloc->usl.itmpStack, sym);
1549 /*-----------------------------------------------------------------*/
1550 /* isSpiltOnStack - returns true if the spil location is on stack */
1551 /*-----------------------------------------------------------------*/
1553 isSpiltOnStack (symbol * sym)
1557 debugLog ("%s\n", __FUNCTION__);
1564 /* if (sym->_G.stackSpil) */
1567 if (!sym->usl.spillLoc)
1570 etype = getSpec (sym->usl.spillLoc->type);
1571 if (IN_STACK (etype))
1577 /*-----------------------------------------------------------------*/
1578 /* spillThis - spils a specific operand */
1579 /*-----------------------------------------------------------------*/
1581 spillThis (symbol * sym)
1584 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1586 /* if this is rematerializable or has a spillLocation
1587 we are okay, else we need to create a spillLocation
1589 if (!(sym->remat || sym->usl.spillLoc))
1590 createStackSpil (sym);
1593 /* mark it has spilt & put it in the spilt set */
1595 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1597 bitVectUnSetBit (_G.regAssigned, sym->key);
1599 for (i = 0; i < sym->nRegs; i++)
1603 freeReg (sym->regs[i]);
1604 sym->regs[i] = NULL;
1607 /* if spilt on stack then free up r0 & r1
1608 if they could have been assigned to some
1610 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1613 spillLRWithPtrReg (sym);
1616 if (sym->usl.spillLoc && !sym->remat)
1617 sym->usl.spillLoc->allocreq = 1;
1621 /*-----------------------------------------------------------------*/
1622 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1623 /*-----------------------------------------------------------------*/
1625 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1627 bitVect *lrcs = NULL;
1631 debugLog ("%s\n", __FUNCTION__);
1632 /* get the spillable live ranges */
1633 lrcs = computeSpillable (ic);
1635 /* get all live ranges that are rematerizable */
1636 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1639 /* return the least used of these */
1640 return leastUsedLR (selectS);
1643 /* get live ranges with spillLocations in direct space */
1644 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1646 sym = leastUsedLR (selectS);
1647 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1648 sym->usl.spillLoc->rname :
1649 sym->usl.spillLoc->name));
1651 /* mark it as allocation required */
1652 sym->usl.spillLoc->allocreq = 1;
1656 /* if the symbol is local to the block then */
1657 if (forSym->liveTo < ebp->lSeq)
1660 /* check if there are any live ranges allocated
1661 to registers that are not used in this block */
1662 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1664 sym = leastUsedLR (selectS);
1665 /* if this is not rematerializable */
1674 /* check if there are any live ranges that not
1675 used in the remainder of the block */
1676 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1678 sym = leastUsedLR (selectS);
1681 sym->remainSpil = 1;
1688 /* find live ranges with spillocation && not used as pointers */
1689 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1692 sym = leastUsedLR (selectS);
1693 /* mark this as allocation required */
1694 sym->usl.spillLoc->allocreq = 1;
1698 /* find live ranges with spillocation */
1699 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1702 sym = leastUsedLR (selectS);
1703 sym->usl.spillLoc->allocreq = 1;
1707 /* couldn't find then we need to create a spil
1708 location on the stack , for which one? the least
1710 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1713 /* return a created spil location */
1714 sym = createStackSpil (leastUsedLR (selectS));
1715 sym->usl.spillLoc->allocreq = 1;
1719 /* this is an extreme situation we will spill
1720 this one : happens very rarely but it does happen */
1726 /*-----------------------------------------------------------------*/
1727 /* spilSomething - spil some variable & mark registers as free */
1728 /*-----------------------------------------------------------------*/
1730 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1735 debugLog ("%s\n", __FUNCTION__);
1736 /* get something we can spil */
1737 ssym = selectSpil (ic, ebp, forSym);
1739 /* mark it as spilt */
1741 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1743 /* mark it as not register assigned &
1744 take it away from the set */
1745 bitVectUnSetBit (_G.regAssigned, ssym->key);
1747 /* mark the registers as free */
1748 for (i = 0; i < ssym->nRegs; i++)
1750 freeReg (ssym->regs[i]);
1752 /* if spilt on stack then free up r0 & r1
1753 if they could have been assigned to as gprs */
1754 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1757 spillLRWithPtrReg (ssym);
1760 /* if this was a block level spil then insert push & pop
1761 at the start & end of block respectively */
1762 if (ssym->blockSpil)
1764 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1765 /* add push to the start of the block */
1766 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1767 ebp->sch->next : ebp->sch));
1768 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1769 /* add pop to the end of the block */
1770 addiCodeToeBBlock (ebp, nic, NULL);
1773 /* if spilt because not used in the remainder of the
1774 block then add a push before this instruction and
1775 a pop at the end of the block */
1776 if (ssym->remainSpil)
1779 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1780 /* add push just before this instruction */
1781 addiCodeToeBBlock (ebp, nic, ic);
1783 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1784 /* add pop to the end of the block */
1785 addiCodeToeBBlock (ebp, nic, NULL);
1794 /*-----------------------------------------------------------------*/
1795 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1796 /*-----------------------------------------------------------------*/
1798 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1803 debugLog ("%s\n", __FUNCTION__);
1805 /* try for a ptr type */
1806 if ((reg = allocReg (REG_PTR)))
1809 /* try for gpr type */
1810 if ((reg = allocReg (REG_GPR)))
1813 /* we have to spil */
1814 if (!spilSomething (ic, ebp, sym))
1817 /* make sure partially assigned registers aren't reused */
1818 for (j=0; j<=sym->nRegs; j++)
1820 sym->regs[j]->isFree = 0;
1822 /* this looks like an infinite loop but
1823 in really selectSpil will abort */
1827 /*-----------------------------------------------------------------*/
1828 /* getRegGpr - will try for GPR if not spil */
1829 /*-----------------------------------------------------------------*/
1831 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1836 debugLog ("%s\n", __FUNCTION__);
1838 /* try for gpr type */
1839 if ((reg = allocReg (REG_GPR)))
1842 if (!pic16_ptrRegReq)
1843 if ((reg = allocReg (REG_PTR)))
1846 /* we have to spil */
1847 if (!spilSomething (ic, ebp, sym))
1850 /* make sure partially assigned registers aren't reused */
1851 for (j=0; j<=sym->nRegs; j++)
1853 sym->regs[j]->isFree = 0;
1855 /* this looks like an infinite loop but
1856 in really selectSpil will abort */
1860 /*-----------------------------------------------------------------*/
1861 /* symHasReg - symbol has a given register */
1862 /*-----------------------------------------------------------------*/
1864 symHasReg (symbol * sym, regs * reg)
1868 debugLog ("%s\n", __FUNCTION__);
1869 for (i = 0; i < sym->nRegs; i++)
1870 if (sym->regs[i] == reg)
1876 /*-----------------------------------------------------------------*/
1877 /* deassignLRs - check the live to and if they have registers & are */
1878 /* not spilt then free up the registers */
1879 /*-----------------------------------------------------------------*/
1881 deassignLRs (iCode * ic, eBBlock * ebp)
1887 debugLog ("%s\n", __FUNCTION__);
1888 for (sym = hTabFirstItem (liveRanges, &k); sym;
1889 sym = hTabNextItem (liveRanges, &k))
1892 symbol *psym = NULL;
1893 /* if it does not end here */
1894 if (sym->liveTo > ic->seq)
1897 /* if it was spilt on stack then we can
1898 mark the stack spil location as free */
1903 sym->usl.spillLoc->isFree = 1;
1909 if (!bitVectBitValue (_G.regAssigned, sym->key))
1912 /* special case check if this is an IFX &
1913 the privious one was a pop and the
1914 previous one was not spilt then keep track
1916 if (ic->op == IFX && ic->prev &&
1917 ic->prev->op == IPOP &&
1918 !ic->prev->parmPush &&
1919 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1920 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1926 bitVectUnSetBit (_G.regAssigned, sym->key);
1928 /* if the result of this one needs registers
1929 and does not have it then assign it right
1931 if (IC_RESULT (ic) &&
1932 !(SKIP_IC2 (ic) || /* not a special icode */
1933 ic->op == JUMPTABLE ||
1938 POINTER_SET (ic)) &&
1939 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1940 result->liveTo > ic->seq && /* and will live beyond this */
1941 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1942 result->regType == sym->regType && /* same register types */
1943 result->nRegs && /* which needs registers */
1944 !result->isspilt && /* and does not already have them */
1946 !bitVectBitValue (_G.regAssigned, result->key) &&
1947 /* the number of free regs + number of regs in this LR
1948 can accomodate the what result Needs */
1949 ((nfreeRegsType (result->regType) +
1950 sym->nRegs) >= result->nRegs)
1954 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1956 result->regs[i] = sym->regs[i];
1958 result->regs[i] = getRegGpr (ic, ebp, result);
1960 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1964 /* free the remaining */
1965 for (; i < sym->nRegs; i++)
1969 if (!symHasReg (psym, sym->regs[i]))
1970 freeReg (sym->regs[i]);
1973 freeReg (sym->regs[i]);
1980 /*-----------------------------------------------------------------*/
1981 /* reassignLR - reassign this to registers */
1982 /*-----------------------------------------------------------------*/
1984 reassignLR (operand * op)
1986 symbol *sym = OP_SYMBOL (op);
1989 debugLog ("%s\n", __FUNCTION__);
1990 /* not spilt any more */
1991 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1992 bitVectUnSetBit (_G.spiltSet, sym->key);
1994 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1998 for (i = 0; i < sym->nRegs; i++)
1999 sym->regs[i]->isFree = 0;
2002 /*-----------------------------------------------------------------*/
2003 /* willCauseSpill - determines if allocating will cause a spill */
2004 /*-----------------------------------------------------------------*/
2006 willCauseSpill (int nr, int rt)
2008 debugLog ("%s\n", __FUNCTION__);
2009 /* first check if there are any avlb registers
2010 of te type required */
2013 /* special case for pointer type
2014 if pointer type not avlb then
2015 check for type gpr */
2016 if (nFreeRegs (rt) >= nr)
2018 if (nFreeRegs (REG_GPR) >= nr)
2023 if (pic16_ptrRegReq)
2025 if (nFreeRegs (rt) >= nr)
2030 if (nFreeRegs (REG_PTR) +
2031 nFreeRegs (REG_GPR) >= nr)
2036 debugLog (" ... yep it will (cause a spill)\n");
2037 /* it will cause a spil */
2041 /*-----------------------------------------------------------------*/
2042 /* positionRegs - the allocator can allocate same registers to res- */
2043 /* ult and operand, if this happens make sure they are in the same */
2044 /* position as the operand otherwise chaos results */
2045 /*-----------------------------------------------------------------*/
2047 positionRegs (symbol * result, symbol * opsym, int lineno)
2049 int count = min (result->nRegs, opsym->nRegs);
2050 int i, j = 0, shared = 0;
2052 debugLog ("%s\n", __FUNCTION__);
2053 /* if the result has been spilt then cannot share */
2058 /* first make sure that they actually share */
2059 for (i = 0; i < count; i++)
2061 for (j = 0; j < count; j++)
2063 if (result->regs[i] == opsym->regs[j] && i != j)
2073 regs *tmp = result->regs[i];
2074 result->regs[i] = result->regs[j];
2075 result->regs[j] = tmp;
2080 /*------------------------------------------------------------------*/
2081 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2082 /* it should either have registers or have beed spilled. Otherwise, */
2083 /* there was an uninitialized variable, so just spill this to get */
2084 /* the operand in a valid state. */
2085 /*------------------------------------------------------------------*/
2087 verifyRegsAssigned (operand *op, iCode * ic)
2092 if (!IS_ITEMP (op)) return;
2094 sym = OP_SYMBOL (op);
2095 if (sym->isspilt) return;
2096 if (!sym->nRegs) return;
2097 if (sym->regs[0]) return;
2099 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2100 sym->prereqv ? sym->prereqv->name : sym->name);
2105 /*-----------------------------------------------------------------*/
2106 /* serialRegAssign - serially allocate registers to the variables */
2107 /*-----------------------------------------------------------------*/
2109 serialRegAssign (eBBlock ** ebbs, int count)
2113 debugLog ("%s\n", __FUNCTION__);
2114 /* for all blocks */
2115 for (i = 0; i < count; i++)
2120 if (ebbs[i]->noPath &&
2121 (ebbs[i]->entryLabel != entryLabel &&
2122 ebbs[i]->entryLabel != returnLabel))
2125 /* of all instructions do */
2126 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2129 debugLog (" op: %s\n", decodeOp (ic->op));
2131 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2132 pic16_allocDirReg(IC_RESULT(ic));
2134 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2135 pic16_allocDirReg(IC_LEFT(ic));
2137 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2138 pic16_allocDirReg(IC_RIGHT(ic));
2140 /* if this is an ipop that means some live
2141 range will have to be assigned again */
2143 reassignLR (IC_LEFT (ic));
2145 /* if result is present && is a true symbol */
2146 if (IC_RESULT (ic) && ic->op != IFX &&
2147 IS_TRUE_SYMOP (IC_RESULT (ic)))
2148 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2150 /* take away registers from live
2151 ranges that end at this instruction */
2152 deassignLRs (ic, ebbs[i]);
2154 /* some don't need registers */
2155 if (SKIP_IC2 (ic) ||
2156 ic->op == JUMPTABLE ||
2160 (IC_RESULT (ic) && POINTER_SET (ic)))
2163 /* now we need to allocate registers
2164 only for the result */
2167 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2173 /* if it does not need or is spilt
2174 or is already assigned to registers
2175 or will not live beyond this instructions */
2178 bitVectBitValue (_G.regAssigned, sym->key) ||
2179 sym->liveTo <= ic->seq)
2182 /* if some liverange has been spilt at the block level
2183 and this one live beyond this block then spil this
2185 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2190 /* if trying to allocate this will cause
2191 a spill and there is nothing to spill
2192 or this one is rematerializable then
2194 willCS = willCauseSpill (sym->nRegs, sym->regType);
2195 spillable = computeSpillable (ic);
2197 (willCS && bitVectIsZero (spillable)))
2205 /* If the live range preceeds the point of definition
2206 then ideally we must take into account registers that
2207 have been allocated after sym->liveFrom but freed
2208 before ic->seq. This is complicated, so spill this
2209 symbol instead and let fillGaps handle the allocation. */
2210 if (sym->liveFrom < ic->seq)
2216 /* if it has a spillocation & is used less than
2217 all other live ranges then spill this */
2219 if (sym->usl.spillLoc) {
2220 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2221 allLRs, ebbs[i], ic));
2222 if (leastUsed && leastUsed->used > sym->used) {
2227 /* if none of the liveRanges have a spillLocation then better
2228 to spill this one than anything else already assigned to registers */
2229 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2230 /* if this is local to this block then we might find a block spil */
2231 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2239 if (ic->op == RECEIVE)
2240 debugLog ("When I get clever, I'll optimize the receive logic\n");
2242 /* if we need ptr regs for the right side
2244 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2245 <= (unsigned) PTRSIZE)
2250 /* else we assign registers to it */
2251 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2253 debugLog (" %d - nRegs: %d\n", __LINE__, sym->nRegs);
2255 bitVectDebugOn(_G.regAssigned, debugF);
2257 for (j = 0; j < sym->nRegs; j++)
2259 if (sym->regType == REG_PTR)
2260 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2262 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2264 /* if the allocation falied which means
2265 this was spilt then break */
2269 debugLog (" %d - \n", __LINE__);
2271 /* if it shares registers with operands make sure
2272 that they are in the same position */
2273 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2274 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2275 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2276 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2277 /* do the same for the right operand */
2278 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2279 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2280 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2281 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2283 debugLog (" %d - \n", __LINE__);
2286 debugLog (" %d - \n", __LINE__);
2295 /* Check for and fix any problems with uninitialized operands */
2296 for (i = 0; i < count; i++)
2300 if (ebbs[i]->noPath &&
2301 (ebbs[i]->entryLabel != entryLabel &&
2302 ebbs[i]->entryLabel != returnLabel))
2305 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2312 verifyRegsAssigned (IC_COND (ic), ic);
2316 if (ic->op == JUMPTABLE)
2318 verifyRegsAssigned (IC_JTCOND (ic), ic);
2322 verifyRegsAssigned (IC_RESULT (ic), ic);
2323 verifyRegsAssigned (IC_LEFT (ic), ic);
2324 verifyRegsAssigned (IC_RIGHT (ic), ic);
2330 /*-----------------------------------------------------------------*/
2331 /* rUmaskForOp :- returns register mask for an operand */
2332 /*-----------------------------------------------------------------*/
2334 rUmaskForOp (operand * op)
2340 debugLog ("%s\n", __FUNCTION__);
2341 /* only temporaries are assigned registers */
2345 sym = OP_SYMBOL (op);
2347 /* if spilt or no registers assigned to it
2349 if (sym->isspilt || !sym->nRegs)
2352 rumask = newBitVect (pic16_nRegs);
2354 for (j = 0; j < sym->nRegs; j++)
2356 rumask = bitVectSetBit (rumask,
2357 sym->regs[j]->rIdx);
2363 /*-----------------------------------------------------------------*/
2364 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2365 /*-----------------------------------------------------------------*/
2367 regsUsedIniCode (iCode * ic)
2369 bitVect *rmask = newBitVect (pic16_nRegs);
2371 debugLog ("%s\n", __FUNCTION__);
2372 /* do the special cases first */
2375 rmask = bitVectUnion (rmask,
2376 rUmaskForOp (IC_COND (ic)));
2380 /* for the jumptable */
2381 if (ic->op == JUMPTABLE)
2383 rmask = bitVectUnion (rmask,
2384 rUmaskForOp (IC_JTCOND (ic)));
2389 /* of all other cases */
2391 rmask = bitVectUnion (rmask,
2392 rUmaskForOp (IC_LEFT (ic)));
2396 rmask = bitVectUnion (rmask,
2397 rUmaskForOp (IC_RIGHT (ic)));
2400 rmask = bitVectUnion (rmask,
2401 rUmaskForOp (IC_RESULT (ic)));
2407 /*-----------------------------------------------------------------*/
2408 /* createRegMask - for each instruction will determine the regsUsed */
2409 /*-----------------------------------------------------------------*/
2411 createRegMask (eBBlock ** ebbs, int count)
2415 debugLog ("%s\n", __FUNCTION__);
2416 /* for all blocks */
2417 for (i = 0; i < count; i++)
2421 if (ebbs[i]->noPath &&
2422 (ebbs[i]->entryLabel != entryLabel &&
2423 ebbs[i]->entryLabel != returnLabel))
2426 /* for all instructions */
2427 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2432 if (SKIP_IC2 (ic) || !ic->rlive)
2435 /* first mark the registers used in this
2437 ic->rUsed = regsUsedIniCode (ic);
2438 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2440 /* now create the register mask for those
2441 registers that are in use : this is a
2442 super set of ic->rUsed */
2443 ic->rMask = newBitVect (pic16_nRegs + 1);
2445 /* for all live Ranges alive at this point */
2446 for (j = 1; j < ic->rlive->size; j++)
2451 /* if not alive then continue */
2452 if (!bitVectBitValue (ic->rlive, j))
2455 /* find the live range we are interested in */
2456 if (!(sym = hTabItemWithKey (liveRanges, j)))
2458 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2459 "createRegMask cannot find live range");
2463 /* if no register assigned to it */
2464 if (!sym->nRegs || sym->isspilt)
2467 /* for all the registers allocated to it */
2468 for (k = 0; k < sym->nRegs; k++)
2471 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2477 /*-----------------------------------------------------------------*/
2478 /* rematStr - returns the rematerialized string for a remat var */
2479 /*-----------------------------------------------------------------*/
2481 rematStr (symbol * sym)
2484 iCode *ic = sym->rematiCode;
2485 symbol *psym = NULL;
2487 debugLog ("%s\n", __FUNCTION__);
2489 //printf ("%s\n", s);
2491 /* if plus or minus print the right hand side */
2493 if (ic->op == '+' || ic->op == '-') {
2495 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2497 sprintf (s, "(%s %c 0x%04x)",
2498 OP_SYMBOL (IC_LEFT (ric))->rname,
2500 (int) operandLitValue (IC_RIGHT (ic)));
2503 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2505 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2506 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2511 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2512 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2514 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2519 /*-----------------------------------------------------------------*/
2520 /* rematStr - returns the rematerialized string for a remat var */
2521 /*-----------------------------------------------------------------*/
2523 rematStr (symbol * sym)
2526 iCode *ic = sym->rematiCode;
2528 debugLog ("%s\n", __FUNCTION__);
2533 /* if plus or minus print the right hand side */
2535 if (ic->op == '+' || ic->op == '-') {
2536 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2539 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2543 if (ic->op == '+' || ic->op == '-')
2545 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2546 sprintf (s, "(%s %c 0x%04x)",
2547 OP_SYMBOL (IC_LEFT (ric))->rname,
2549 (int) operandLitValue (IC_RIGHT (ic)));
2552 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2554 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2558 /* we reached the end */
2559 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2563 printf ("%s\n", buffer);
2568 /*-----------------------------------------------------------------*/
2569 /* regTypeNum - computes the type & number of registers required */
2570 /*-----------------------------------------------------------------*/
2578 debugLog ("%s\n", __FUNCTION__);
2579 /* for each live range do */
2580 for (sym = hTabFirstItem (liveRanges, &k); sym;
2581 sym = hTabNextItem (liveRanges, &k)) {
2583 debugLog (" %d - %s\n", __LINE__, sym->rname);
2584 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2586 /* if used zero times then no registers needed */
2587 if ((sym->liveTo - sym->liveFrom) == 0)
2591 /* if the live range is a temporary */
2594 debugLog (" %d - itemp register\n", __LINE__);
2596 /* if the type is marked as a conditional */
2597 if (sym->regType == REG_CND)
2600 /* if used in return only then we don't
2602 if (sym->ruonly || sym->accuse) {
2603 if (IS_AGGREGATE (sym->type) || sym->isptr)
2604 sym->type = aggrToPtr (sym->type, FALSE);
2605 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2610 /* if the symbol has only one definition &
2611 that definition is a get_pointer and the
2612 pointer we are getting is rematerializable and
2615 if (bitVectnBitsOn (sym->defs) == 1 &&
2616 (ic = hTabItemWithKey (iCodehTab,
2617 bitVectFirstBit (sym->defs))) &&
2619 !IS_BITVAR (sym->etype) &&
2620 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2622 if (ptrPseudoSymSafe (sym, ic)) {
2626 debugLog (" %d - \n", __LINE__);
2628 /* create a psuedo symbol & force a spil */
2629 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2630 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2631 psym->type = sym->type;
2632 psym->etype = sym->etype;
2633 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2634 strcpy (psym->rname, psym->name);
2636 sym->usl.spillLoc = psym;
2640 /* if in data space or idata space then try to
2641 allocate pointer register */
2645 /* if not then we require registers */
2646 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2647 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2648 getSize (sym->type));
2652 if(IS_PTR_CONST (sym->type)) {
2654 if(IS_CODEPTR (sym->type)) {
2656 // what IS this ???? (HJD)
2657 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2658 sym->nRegs = 3; // patch 14
2661 if (sym->nRegs > 4) {
2662 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2663 printTypeChain (sym->type, stderr);
2664 fprintf (stderr, "\n");
2667 /* determine the type of register required */
2668 if (sym->nRegs == 1 &&
2669 IS_PTR (sym->type) &&
2671 sym->regType = REG_PTR;
2673 sym->regType = REG_GPR;
2676 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2680 /* for the first run we don't provide */
2681 /* registers for true symbols we will */
2682 /* see how things go */
2687 static DEFSETFUNC (markRegFree)
2689 ((regs *)item)->isFree = 1;
2694 DEFSETFUNC (pic16_deallocReg)
2696 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2697 ((regs *)item)->isFree = 1;
2698 ((regs *)item)->wasUsed = 0;
2702 /*-----------------------------------------------------------------*/
2703 /* freeAllRegs - mark all registers as free */
2704 /*-----------------------------------------------------------------*/
2706 pic16_freeAllRegs ()
2708 debugLog ("%s\n", __FUNCTION__);
2710 applyToSet(pic16_dynAllocRegs,markRegFree);
2711 applyToSet(pic16_dynStackRegs,markRegFree);
2714 /*-----------------------------------------------------------------*/
2715 /*-----------------------------------------------------------------*/
2717 pic16_deallocateAllRegs ()
2719 debugLog ("%s\n", __FUNCTION__);
2721 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2725 /*-----------------------------------------------------------------*/
2726 /* deallocStackSpil - this will set the stack pointer back */
2727 /*-----------------------------------------------------------------*/
2729 DEFSETFUNC (deallocStackSpil)
2733 debugLog ("%s\n", __FUNCTION__);
2738 /*-----------------------------------------------------------------*/
2739 /* farSpacePackable - returns the packable icode for far variables */
2740 /*-----------------------------------------------------------------*/
2742 farSpacePackable (iCode * ic)
2746 debugLog ("%s\n", __FUNCTION__);
2747 /* go thru till we find a definition for the
2748 symbol on the right */
2749 for (dic = ic->prev; dic; dic = dic->prev)
2752 /* if the definition is a call then no */
2753 if ((dic->op == CALL || dic->op == PCALL) &&
2754 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2759 /* if shift by unknown amount then not */
2760 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2761 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2764 /* if pointer get and size > 1 */
2765 if (POINTER_GET (dic) &&
2766 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2769 if (POINTER_SET (dic) &&
2770 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2773 /* if any three is a true symbol in far space */
2774 if (IC_RESULT (dic) &&
2775 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2776 isOperandInFarSpace (IC_RESULT (dic)))
2779 if (IC_RIGHT (dic) &&
2780 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2781 isOperandInFarSpace (IC_RIGHT (dic)) &&
2782 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2785 if (IC_LEFT (dic) &&
2786 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2787 isOperandInFarSpace (IC_LEFT (dic)) &&
2788 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2791 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2793 if ((dic->op == LEFT_OP ||
2794 dic->op == RIGHT_OP ||
2796 IS_OP_LITERAL (IC_RIGHT (dic)))
2806 /*-----------------------------------------------------------------*/
2807 /* packRegsForAssign - register reduction for assignment */
2808 /*-----------------------------------------------------------------*/
2810 packRegsForAssign (iCode * ic, eBBlock * ebp)
2815 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2816 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2817 debugAopGet (" result:", IC_RESULT (ic));
2818 debugAopGet (" left:", IC_LEFT (ic));
2819 debugAopGet (" right:", IC_RIGHT (ic));
2821 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2823 debugLog(" %d - actuall processing\n", __LINE__ );
2825 if (!IS_ITEMP (IC_RESULT (ic))) {
2826 pic16_allocDirReg(IC_RESULT (ic));
2827 debugLog (" %d - result is not temp\n", __LINE__);
2831 /* See BUGLOG0001 - VR */
2833 if (!IS_ITEMP (IC_RIGHT (ic))) {
2834 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2835 pic16_allocDirReg(IC_RIGHT (ic));
2840 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2841 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2843 debugLog (" %d - not packing - right side fails \n", __LINE__);
2847 /* if the true symbol is defined in far space or on stack
2848 then we should not since this will increase register pressure */
2849 if (isOperandInFarSpace (IC_RESULT (ic)))
2851 if ((dic = farSpacePackable (ic)))
2858 /* find the definition of iTempNN scanning backwards if we find a
2859 a use of the true symbol before we find the definition then
2861 for (dic = ic->prev; dic; dic = dic->prev)
2864 /* if there is a function call and this is
2865 a parameter & not my parameter then don't pack it */
2866 if ((dic->op == CALL || dic->op == PCALL) &&
2867 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2868 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2870 debugLog (" %d - \n", __LINE__);
2879 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2881 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2882 IS_OP_VOLATILE (IC_RESULT (dic)))
2884 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2890 if( IS_SYMOP( IC_RESULT(dic)) &&
2891 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2893 debugLog (" %d - result is bitfield\n", __LINE__);
2899 if (IS_SYMOP (IC_RESULT (dic)) &&
2900 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2902 /* A previous result was assigned to the same register - we'll our definition */
2903 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2904 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2905 if (POINTER_SET (dic))
2911 if (IS_SYMOP (IC_RIGHT (dic)) &&
2912 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2913 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2915 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2920 if (IS_SYMOP (IC_LEFT (dic)) &&
2921 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2922 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2924 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2929 if (POINTER_SET (dic) &&
2930 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2932 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2940 return 0; /* did not find */
2943 /* This code is taken from the hc08 port. Do not know
2944 * if it fits for pic16, but I leave it here just in case */
2946 /* if assignment then check that right is not a bit */
2947 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2948 sym_link *etype = operandType (IC_RIGHT (dic));
2950 if (IS_BITFIELD (etype)) {
2951 /* if result is a bit too then it's ok */
2952 etype = operandType (IC_RESULT (dic));
2953 if (!IS_BITFIELD (etype)) {
2954 debugLog(" %d bitfields\n");
2961 /* if the result is on stack or iaccess then it must be
2962 the same atleast one of the operands */
2963 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2964 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2966 /* the operation has only one symbol
2967 operator then we can pack */
2968 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2969 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2972 if (!((IC_LEFT (dic) &&
2973 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2975 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2979 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2980 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2981 /* found the definition */
2982 /* replace the result with the result of */
2983 /* this assignment and remove this assignment */
2984 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2985 IC_RESULT (dic) = IC_RESULT (ic);
2987 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2989 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2991 /* delete from liverange table also
2992 delete from all the points inbetween and the new
2994 for (sic = dic; sic != ic; sic = sic->next)
2996 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2997 if (IS_ITEMP (IC_RESULT (dic)))
2998 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3001 remiCodeFromeBBlock (ebp, ic);
3002 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3004 debugLog(" %d\n", __LINE__ );
3005 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3006 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3014 #define NO_packRegsForAccUse
3015 #define NO_packRegsForSupport
3016 #define NO_packRegsForOneuse
3017 #define NO_cast_peep
3022 #ifndef NO_packRegsForSupport
3023 /*-----------------------------------------------------------------*/
3024 /* findAssignToSym : scanning backwards looks for first assig found */
3025 /*-----------------------------------------------------------------*/
3027 findAssignToSym (operand * op, iCode * ic)
3031 debugLog ("%s\n", __FUNCTION__);
3032 for (dic = ic->prev; dic; dic = dic->prev)
3035 /* if definition by assignment */
3036 if (dic->op == '=' &&
3037 !POINTER_SET (dic) &&
3038 IC_RESULT (dic)->key == op->key
3039 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3043 /* we are interested only if defined in far space */
3044 /* or in stack space in case of + & - */
3046 /* if assigned to a non-symbol then return
3048 if (!IS_SYMOP (IC_RIGHT (dic)))
3051 /* if the symbol is in far space then
3053 if (isOperandInFarSpace (IC_RIGHT (dic)))
3056 /* for + & - operations make sure that
3057 if it is on the stack it is the same
3058 as one of the three operands */
3059 if ((ic->op == '+' || ic->op == '-') &&
3060 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3062 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3063 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3064 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3072 /* if we find an usage then we cannot delete it */
3073 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3076 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3079 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3083 /* now make sure that the right side of dic
3084 is not defined between ic & dic */
3087 iCode *sic = dic->next;
3089 for (; sic != ic; sic = sic->next)
3090 if (IC_RESULT (sic) &&
3091 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3102 #ifndef NO_packRegsForSupport
3103 /*-----------------------------------------------------------------*/
3104 /* packRegsForSupport :- reduce some registers for support calls */
3105 /*-----------------------------------------------------------------*/
3107 packRegsForSupport (iCode * ic, eBBlock * ebp)
3111 debugLog ("%s\n", __FUNCTION__);
3112 /* for the left & right operand :- look to see if the
3113 left was assigned a true symbol in far space in that
3114 case replace them */
3115 if (IS_ITEMP (IC_LEFT (ic)) &&
3116 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3118 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3124 debugAopGet ("removing left:", IC_LEFT (ic));
3126 /* found it we need to remove it from the
3128 for (sic = dic; sic != ic; sic = sic->next)
3129 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3131 IC_LEFT (ic)->operand.symOperand =
3132 IC_RIGHT (dic)->operand.symOperand;
3133 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3134 remiCodeFromeBBlock (ebp, dic);
3135 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3136 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3140 /* do the same for the right operand */
3143 IS_ITEMP (IC_RIGHT (ic)) &&
3144 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3146 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3152 /* if this is a subtraction & the result
3153 is a true symbol in far space then don't pack */
3154 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3156 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3157 if (IN_FARSPACE (SPEC_OCLS (etype)))
3161 debugAopGet ("removing right:", IC_RIGHT (ic));
3163 /* found it we need to remove it from the
3165 for (sic = dic; sic != ic; sic = sic->next)
3166 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3168 IC_RIGHT (ic)->operand.symOperand =
3169 IC_RIGHT (dic)->operand.symOperand;
3170 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3172 remiCodeFromeBBlock (ebp, dic);
3173 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3174 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3183 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3185 #ifndef NO_packRegsForOneuse
3186 /*-----------------------------------------------------------------*/
3187 /* packRegsForOneuse : - will reduce some registers for single Use */
3188 /*-----------------------------------------------------------------*/
3190 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3195 debugLog ("%s\n", __FUNCTION__);
3196 /* if returning a literal then do nothing */
3200 /* only upto 2 bytes since we cannot predict
3201 the usage of b, & acc */
3202 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3207 /* this routine will mark the a symbol as used in one
3208 instruction use only && if the definition is local
3209 (ie. within the basic block) && has only one definition &&
3210 that definition is either a return value from a
3211 function or does not contain any variables in
3213 uses = bitVectCopy (OP_USES (op));
3214 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3215 if (!bitVectIsZero (uses)) /* has other uses */
3218 /* if it has only one defintion */
3219 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3220 return NULL; /* has more than one definition */
3222 /* get that definition */
3224 hTabItemWithKey (iCodehTab,
3225 bitVectFirstBit (OP_DEFS (op)))))
3228 /* found the definition now check if it is local */
3229 if (dic->seq < ebp->fSeq ||
3230 dic->seq > ebp->lSeq)
3231 return NULL; /* non-local */
3233 /* now check if it is the return from
3235 if (dic->op == CALL || dic->op == PCALL)
3237 if (ic->op != SEND && ic->op != RETURN &&
3238 !POINTER_SET(ic) && !POINTER_GET(ic))
3240 OP_SYMBOL (op)->ruonly = 1;
3247 /* otherwise check that the definition does
3248 not contain any symbols in far space */
3249 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3250 isOperandInFarSpace (IC_RIGHT (dic)) ||
3251 IS_OP_RUONLY (IC_LEFT (ic)) ||
3252 IS_OP_RUONLY (IC_RIGHT (ic)))
3257 /* if pointer set then make sure the pointer
3259 if (POINTER_SET (dic) &&
3260 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3263 if (POINTER_GET (dic) &&
3264 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3269 /* also make sure the intervenening instructions
3270 don't have any thing in far space */
3271 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3274 /* if there is an intervening function call then no */
3275 if (dic->op == CALL || dic->op == PCALL)
3277 /* if pointer set then make sure the pointer
3279 if (POINTER_SET (dic) &&
3280 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3283 if (POINTER_GET (dic) &&
3284 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3287 /* if address of & the result is remat then okay */
3288 if (dic->op == ADDRESS_OF &&
3289 OP_SYMBOL (IC_RESULT (dic))->remat)
3292 /* if operand has size of three or more & this
3293 operation is a '*','/' or '%' then 'b' may
3295 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3296 getSize (operandType (op)) >= 3)
3299 /* if left or right or result is in far space */
3300 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3301 isOperandInFarSpace (IC_RIGHT (dic)) ||
3302 isOperandInFarSpace (IC_RESULT (dic)) ||
3303 IS_OP_RUONLY (IC_LEFT (dic)) ||
3304 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3305 IS_OP_RUONLY (IC_RESULT (dic)))
3311 OP_SYMBOL (op)->ruonly = 1;
3318 /*-----------------------------------------------------------------*/
3319 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3320 /*-----------------------------------------------------------------*/
3322 isBitwiseOptimizable (iCode * ic)
3324 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3325 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3327 debugLog ("%s\n", __FUNCTION__);
3328 /* bitwise operations are considered optimizable
3329 under the following conditions (Jean-Louis VERN)
3341 if (IS_LITERAL (rtype) ||
3342 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3349 #ifndef NO_packRegsForAccUse
3351 /*-----------------------------------------------------------------*/
3352 /* packRegsForAccUse - pack registers for acc use */
3353 /*-----------------------------------------------------------------*/
3355 packRegsForAccUse (iCode * ic)
3359 debugLog ("%s\n", __FUNCTION__);
3361 /* if this is an aggregate, e.g. a one byte char array */
3362 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3365 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3367 /* if + or - then it has to be one byte result */
3368 if ((ic->op == '+' || ic->op == '-')
3369 && getSize (operandType (IC_RESULT (ic))) > 1)
3372 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3373 /* if shift operation make sure right side is not a literal */
3374 if (ic->op == RIGHT_OP &&
3375 (isOperandLiteral (IC_RIGHT (ic)) ||
3376 getSize (operandType (IC_RESULT (ic))) > 1))
3379 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3380 if (ic->op == LEFT_OP &&
3381 (isOperandLiteral (IC_RIGHT (ic)) ||
3382 getSize (operandType (IC_RESULT (ic))) > 1))
3385 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3386 if (IS_BITWISE_OP (ic) &&
3387 getSize (operandType (IC_RESULT (ic))) > 1)
3391 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3392 /* has only one definition */
3393 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3396 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3397 /* has only one use */
3398 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3401 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3402 /* and the usage immediately follows this iCode */
3403 if (!(uic = hTabItemWithKey (iCodehTab,
3404 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3407 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3408 if (ic->next != uic)
3411 /* if it is a conditional branch then we definitely can */
3415 if (uic->op == JUMPTABLE)
3418 /* if the usage is not is an assignment
3419 or an arithmetic / bitwise / shift operation then not */
3420 if (POINTER_SET (uic) &&
3421 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3424 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3425 if (uic->op != '=' &&
3426 !IS_ARITHMETIC_OP (uic) &&
3427 !IS_BITWISE_OP (uic) &&
3428 uic->op != LEFT_OP &&
3429 uic->op != RIGHT_OP)
3432 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3433 /* if used in ^ operation then make sure right is not a
3435 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3438 /* if shift operation make sure right side is not a literal */
3439 if (uic->op == RIGHT_OP &&
3440 (isOperandLiteral (IC_RIGHT (uic)) ||
3441 getSize (operandType (IC_RESULT (uic))) > 1))
3444 if (uic->op == LEFT_OP &&
3445 (isOperandLiteral (IC_RIGHT (uic)) ||
3446 getSize (operandType (IC_RESULT (uic))) > 1))
3449 /* make sure that the result of this icode is not on the
3450 stack, since acc is used to compute stack offset */
3451 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3452 OP_SYMBOL (IC_RESULT (uic))->onStack)
3455 /* if either one of them in far space then we cannot */
3456 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3457 isOperandInFarSpace (IC_LEFT (uic))) ||
3458 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3459 isOperandInFarSpace (IC_RIGHT (uic))))
3462 /* if the usage has only one operand then we can */
3463 if (IC_LEFT (uic) == NULL ||
3464 IC_RIGHT (uic) == NULL)
3467 /* make sure this is on the left side if not
3468 a '+' since '+' is commutative */
3469 if (ic->op != '+' &&
3470 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3474 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3475 /* if one of them is a literal then we can */
3476 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3477 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3478 (getSize (operandType (IC_RESULT (uic))) <= 1))
3480 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3485 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3486 /* if the other one is not on stack then we can */
3487 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3488 (IS_ITEMP (IC_RIGHT (uic)) ||
3489 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3490 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3493 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3494 (IS_ITEMP (IC_LEFT (uic)) ||
3495 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3496 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3502 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3503 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3510 /*-----------------------------------------------------------------*/
3511 /* packForPush - hueristics to reduce iCode for pushing */
3512 /*-----------------------------------------------------------------*/
3514 packForReceive (iCode * ic, eBBlock * ebp)
3518 debugLog ("%s\n", __FUNCTION__);
3519 debugAopGet (" result:", IC_RESULT (ic));
3520 debugAopGet (" left:", IC_LEFT (ic));
3521 debugAopGet (" right:", IC_RIGHT (ic));
3526 for (dic = ic->next; dic; dic = dic->next)
3531 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3532 debugLog (" used on left\n");
3533 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3534 debugLog (" used on right\n");
3535 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3536 debugLog (" used on result\n");
3538 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3539 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3544 debugLog (" hey we can remove this unnecessary assign\n");
3546 /*-----------------------------------------------------------------*/
3547 /* packForPush - hueristics to reduce iCode for pushing */
3548 /*-----------------------------------------------------------------*/
3550 packForPush (iCode * ic, eBBlock * ebp)
3554 debugLog ("%s\n", __FUNCTION__);
3555 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3558 /* must have only definition & one usage */
3559 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3560 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3563 /* find the definition */
3564 if (!(dic = hTabItemWithKey (iCodehTab,
3565 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3568 if (dic->op != '=' || POINTER_SET (dic))
3571 /* we now we know that it has one & only one def & use
3572 and the that the definition is an assignment */
3573 IC_LEFT (ic) = IC_RIGHT (dic);
3575 remiCodeFromeBBlock (ebp, dic);
3576 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3577 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3580 static void printSymType(char * str, sym_link *sl)
3582 if(!pic16_ralloc_debug)return;
3584 debugLog (" %s Symbol type: ",str);
3585 printTypeChain( sl, debugF);
3589 /*-----------------------------------------------------------------*/
3590 /* some debug code to print the symbol S_TYPE. Note that
3591 * the function checkSClass in src/SDCCsymt.c dinks with
3592 * the S_TYPE in ways the PIC port doesn't fully like...*/
3593 /*-----------------------------------------------------------------*/
3594 static void isData(sym_link *sl)
3598 if(!pic16_ralloc_debug)return;
3605 for ( ; sl; sl=sl->next) {
3607 switch (SPEC_SCLS(sl)) {
3608 case S_DATA: fprintf (of, "data "); break;
3609 case S_XDATA: fprintf (of, "xdata "); break;
3610 case S_SFR: fprintf (of, "sfr "); break;
3611 case S_SBIT: fprintf (of, "sbit "); break;
3612 case S_CODE: fprintf (of, "code "); break;
3613 case S_IDATA: fprintf (of, "idata "); break;
3614 case S_PDATA: fprintf (of, "pdata "); break;
3615 case S_LITERAL: fprintf (of, "literal "); break;
3616 case S_STACK: fprintf (of, "stack "); break;
3617 case S_XSTACK: fprintf (of, "xstack "); break;
3618 case S_BIT: fprintf (of, "bit "); break;
3619 case S_EEPROM: fprintf (of, "eeprom "); break;
3628 /*--------------------------------------------------------------------*/
3629 /* pic16_packRegisters - does some transformations to reduce */
3630 /* register pressure */
3632 /*--------------------------------------------------------------------*/
3634 pic16_packRegisters (eBBlock * ebp)
3639 debugLog ("%s\n", __FUNCTION__);
3645 /* look for assignments of the form */
3646 /* iTempNN = TRueSym (someoperation) SomeOperand */
3648 /* TrueSym := iTempNN:1 */
3649 for (ic = ebp->sch; ic; ic = ic->next)
3651 // debugLog("%d\n", __LINE__);
3652 /* find assignment of the form TrueSym := iTempNN:1 */
3653 /* see BUGLOG0001 for workaround with the CAST - VR */
3654 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3655 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3656 change += packRegsForAssign (ic, ebp);
3660 if (POINTER_SET (ic))
3661 debugLog ("pointer is set\n");
3662 debugAopGet (" result:", IC_RESULT (ic));
3663 debugAopGet (" left:", IC_LEFT (ic));
3664 debugAopGet (" right:", IC_RIGHT (ic));
3673 for (ic = ebp->sch; ic; ic = ic->next) {
3675 if(IS_SYMOP ( IC_LEFT(ic))) {
3676 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3678 debugAopGet ("x left:", IC_LEFT (ic));
3680 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3682 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3684 debugLog (" is a pointer\n");
3686 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3687 debugLog (" is a ptr\n");
3689 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3690 debugLog (" is volatile\n");
3694 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3695 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3696 pic16_allocDirReg(IC_LEFT (ic));
3699 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3702 if(IS_SYMOP ( IC_RIGHT(ic))) {
3703 debugAopGet (" right:", IC_RIGHT (ic));
3704 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3707 if(IS_SYMOP ( IC_RESULT(ic))) {
3708 debugAopGet (" result:", IC_RESULT (ic));
3709 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3712 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3713 debugAopGet (" right:", IC_RIGHT (ic));
3714 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3715 // pic16_allocDirReg(IC_RIGHT(ic));
3718 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3719 debugAopGet (" result:", IC_RESULT (ic));
3720 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3721 // pic16_allocDirReg(IC_RESULT(ic));
3725 if (POINTER_SET (ic))
3726 debugLog (" %d - Pointer set\n", __LINE__);
3729 /* if this is an itemp & result of a address of a true sym
3730 then mark this as rematerialisable */
3731 if (ic->op == ADDRESS_OF &&
3732 IS_ITEMP (IC_RESULT (ic)) &&
3733 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3734 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3735 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3738 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3740 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3741 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3742 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3746 /* if straight assignment then carry remat flag if
3747 this is the only definition */
3748 if (ic->op == '=' &&
3749 !POINTER_SET (ic) &&
3750 IS_SYMOP (IC_RIGHT (ic)) &&
3751 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3752 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3754 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3756 OP_SYMBOL (IC_RESULT (ic))->remat =
3757 OP_SYMBOL (IC_RIGHT (ic))->remat;
3758 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3759 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3762 /* if this is a +/- operation with a rematerizable
3763 then mark this as rematerializable as well */
3764 if ((ic->op == '+' || ic->op == '-') &&
3765 (IS_SYMOP (IC_LEFT (ic)) &&
3766 IS_ITEMP (IC_RESULT (ic)) &&
3767 OP_SYMBOL (IC_LEFT (ic))->remat &&
3768 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3769 IS_OP_LITERAL (IC_RIGHT (ic))))
3771 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3773 operandLitValue (IC_RIGHT (ic));
3774 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3775 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3776 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3779 /* mark the pointer usages */
3780 if (POINTER_SET (ic))
3782 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3783 debugLog (" marking as a pointer (set) =>");
3784 debugAopGet (" result:", IC_RESULT (ic));
3786 if (POINTER_GET (ic))
3788 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3789 debugLog (" marking as a pointer (get) =>");
3790 debugAopGet (" left:", IC_LEFT (ic));
3793 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3797 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3798 /* if we are using a symbol on the stack
3799 then we should say pic16_ptrRegReq */
3800 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3801 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3802 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3803 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3804 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3805 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3809 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3810 if (IS_SYMOP (IC_LEFT (ic)))
3811 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3812 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3813 if (IS_SYMOP (IC_RIGHT (ic)))
3814 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3815 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3816 if (IS_SYMOP (IC_RESULT (ic)))
3817 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3818 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3821 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3825 /* if the condition of an if instruction
3826 is defined in the previous instruction then
3827 mark the itemp as a conditional */
3828 if ((IS_CONDITIONAL (ic) ||
3829 ((ic->op == BITWISEAND ||
3832 isBitwiseOptimizable (ic))) &&
3833 ic->next && ic->next->op == IFX &&
3834 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3835 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3838 debugLog (" %d\n", __LINE__);
3839 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3843 debugLog(" %d\n", __LINE__);
3845 #ifndef NO_packRegsForSupport
3846 /* reduce for support function calls */
3847 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3848 packRegsForSupport (ic, ebp);
3851 /* if a parameter is passed, it's in W, so we may not
3852 need to place a copy in a register */
3853 if (ic->op == RECEIVE)
3854 packForReceive (ic, ebp);
3856 #ifndef NO_packRegsForOneuse
3857 /* some cases the redundant moves can
3858 can be eliminated for return statements */
3859 if ((ic->op == RETURN || ic->op == SEND) &&
3860 !isOperandInFarSpace (IC_LEFT (ic)) &&
3862 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3865 #ifndef NO_packRegsForOneuse
3866 /* if pointer set & left has a size more than
3867 one and right is not in far space */
3868 if (POINTER_SET (ic) &&
3869 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3870 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3871 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3872 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3874 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3877 #ifndef NO_packRegsForOneuse
3878 /* if pointer get */
3879 if (POINTER_GET (ic) &&
3880 !isOperandInFarSpace (IC_RESULT (ic)) &&
3881 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3882 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3883 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3885 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3886 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3889 #ifndef NO_cast_peep
3890 /* if this is cast for intergral promotion then
3891 check if only use of the definition of the
3892 operand being casted/ if yes then replace
3893 the result of that arithmetic operation with
3894 this result and get rid of the cast */
3895 if (ic->op == CAST) {
3897 sym_link *fromType = operandType (IC_RIGHT (ic));
3898 sym_link *toType = operandType (IC_LEFT (ic));
3900 debugLog (" %d - casting\n", __LINE__);
3902 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3903 getSize (fromType) != getSize (toType)) {
3906 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3909 if (IS_ARITHMETIC_OP (dic)) {
3910 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3912 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3913 IC_RESULT (dic) = IC_RESULT (ic);
3914 remiCodeFromeBBlock (ebp, ic);
3915 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3916 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3917 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3921 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3925 /* if the type from and type to are the same
3926 then if this is the only use then packit */
3927 if (compareType (operandType (IC_RIGHT (ic)),
3928 operandType (IC_LEFT (ic))) == 1) {
3930 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3933 debugLog(" %d\n", __LINE__);
3935 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3936 IC_RESULT (dic) = IC_RESULT (ic);
3937 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3938 remiCodeFromeBBlock (ebp, ic);
3939 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3940 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3948 iTempNN := (some variable in farspace) V1
3953 if (ic->op == IPUSH)
3955 packForPush (ic, ebp);
3959 #ifndef NO_packRegsForAccUse
3960 /* pack registers for accumulator use, when the
3961 result of an arithmetic or bit wise operation
3962 has only one use, that use is immediately following
3963 the defintion and the using iCode has only one
3964 operand or has two operands but one is literal &
3965 the result of that operation is not on stack then
3966 we can leave the result of this operation in acc:b
3968 if ((IS_ARITHMETIC_OP (ic)
3970 || IS_BITWISE_OP (ic)
3972 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3975 IS_ITEMP (IC_RESULT (ic)) &&
3976 getSize (operandType (IC_RESULT (ic))) <= 1)
3978 packRegsForAccUse (ic);
3985 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3989 if (!pic16_ralloc_debug || !debugF)
3992 for (i = 0; i < count; i++)
3994 fprintf (debugF, "\n----------------------------------------------------------------\n");
3995 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3996 ebbs[i]->entryLabel->name,
3999 ebbs[i]->isLastInLoop);
4000 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4005 fprintf (debugF, "visited %d : hasFcall = %d\n",
4009 fprintf (debugF, "\ndefines bitVector :");
4010 bitVectDebugOn (ebbs[i]->defSet, debugF);
4011 fprintf (debugF, "\nlocal defines bitVector :");
4012 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4013 fprintf (debugF, "\npointers Set bitvector :");
4014 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4015 fprintf (debugF, "\nin pointers Set bitvector :");
4016 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4017 fprintf (debugF, "\ninDefs Set bitvector :");
4018 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4019 fprintf (debugF, "\noutDefs Set bitvector :");
4020 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4021 fprintf (debugF, "\nusesDefs Set bitvector :");
4022 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4023 fprintf (debugF, "\n----------------------------------------------------------------\n");
4024 printiCChain (ebbs[i]->sch, debugF);
4027 /*-----------------------------------------------------------------*/
4028 /* pic16_assignRegisters - assigns registers to each live range as need */
4029 /*-----------------------------------------------------------------*/
4031 pic16_assignRegisters (eBBlock ** ebbs, int count)
4036 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4037 debugLog ("\nebbs before optimizing:\n");
4038 dumpEbbsToDebug (ebbs, count);
4040 setToNull ((void *) &_G.funcrUsed);
4041 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4044 /* change assignments this will remove some
4045 live ranges reducing some register pressure */
4046 for (i = 0; i < count; i++)
4047 pic16_packRegisters (ebbs[i]);
4054 debugLog("dir registers allocated so far:\n");
4055 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4058 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4059 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4060 reg = hTabNextItem(dynDirectRegNames, &hkey);
4065 /* liveranges probably changed by register packing
4066 so we compute them again */
4067 recomputeLiveRanges (ebbs, count);
4069 if (options.dump_pack)
4070 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4072 /* first determine for each live range the number of
4073 registers & the type of registers required for each */
4076 /* and serially allocate registers */
4077 serialRegAssign (ebbs, count);
4079 // debugLog ("ebbs after serialRegAssign:\n");
4080 // dumpEbbsToDebug (ebbs, count);
4083 //pic16_freeAllRegs();
4085 /* if stack was extended then tell the user */
4088 /* werror(W_TOOMANY_SPILS,"stack", */
4089 /* _G.stackExtend,currFunc->name,""); */
4095 /* werror(W_TOOMANY_SPILS,"data space", */
4096 /* _G.dataExtend,currFunc->name,""); */
4100 /* after that create the register mask
4101 for each of the instruction */
4102 createRegMask (ebbs, count);
4104 /* redo that offsets for stacked automatic variables */
4105 redoStackOffsets ();
4107 if (options.dump_rassgn)
4108 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4110 /* now get back the chain */
4111 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4113 debugLog ("ebbs after optimizing:\n");
4114 dumpEbbsToDebug (ebbs, count);
4119 /* free up any _G.stackSpil locations allocated */
4120 applyToSet (_G.stackSpil, deallocStackSpil);
4122 setToNull ((void *) &_G.stackSpil);
4123 setToNull ((void *) &_G.spiltSet);
4124 /* mark all registers as free */
4125 pic16_freeAllRegs ();
4127 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");