1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
35 #define FENTRY2 1 ? (void)0 : printf
37 #define STRCASECMP strcasecmp
38 //#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0)
39 #define FENTRY2 1 ? (void)0 : printf
42 /* this should go in SDCCicode.h, but it doesn't. */
43 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
45 /*-----------------------------------------------------------------*/
46 /* At this point we start getting processor specific although */
47 /* some routines are non-processor specific & can be reused when */
48 /* targetting other processors. The decision for this will have */
49 /* to be made on a routine by routine basis */
50 /* routines used to pack registers are most definitely not reusable */
51 /* since the pack the registers depending strictly on the MCU */
52 /*-----------------------------------------------------------------*/
54 extern void genpic14Code (iCode *);
55 extern void pic14_assignConfigWordValue(int address, int value);
65 bitVect *funcrUsed; /* registers used in a function */
71 /* Shared with gen.c */
72 int pic14_ptrRegReq; /* one byte pointer register required */
75 set *dynAllocRegs=NULL;
76 set *dynStackRegs=NULL;
77 set *dynProcessorRegs=NULL;
78 set *dynDirectRegs=NULL;
79 set *dynDirectBitRegs=NULL;
80 set *dynInternalRegs=NULL;
82 static hTab *dynDirectRegNames= NULL;
83 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 static int dynrIdx=0x20;
86 static int rDirectIdx=0;
88 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
90 int Gstack_base_addr=0; /* The starting address of registers that
91 * are used to pass and return parameters */
97 static void spillThis (symbol *);
99 static FILE *debugF = NULL;
100 /*-----------------------------------------------------------------*/
101 /* debugLog - open a file for debugging information */
102 /*-----------------------------------------------------------------*/
103 //static void debugLog(char *inst,char *fmt, ...)
105 debugLog (char *fmt,...)
107 static int append = 0; // First time through, open the file without append.
110 //char *bufferP=buffer;
113 if (!debug || !dstFileName)
119 /* create the file name */
120 strcpy (buffer, dstFileName);
121 strcat (buffer, ".d");
123 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
125 werror (E_FILE_OPEN_ERR, buffer);
128 append = 1; // Next time debubLog is called, we'll append the debug info
134 vsprintf (buffer, fmt, ap);
136 fprintf (debugF, "%s", buffer);
137 //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
139 while (isspace((unsigned char)*bufferP)) bufferP++;
141 if (bufferP && *bufferP)
142 lineCurr = (lineCurr ?
143 connectLine(lineCurr,newLineNode(lb)) :
144 (lineHead = newLineNode(lb)));
145 lineCurr->isInline = _G.inLine;
146 lineCurr->isDebug = _G.debugLine;
156 fputc ('\n', debugF);
158 /*-----------------------------------------------------------------*/
159 /* debugLogClose - closes the debug log file (if opened) */
160 /*-----------------------------------------------------------------*/
170 #define AOP(op) op->aop
173 debugAopGet (char *str, operand * op)
178 printOperand (op, debugF);
186 decodeOp (unsigned int op)
189 if (op < 128 && op > ' ')
191 buffer[0] = (op & 0xff);
198 case IDENTIFIER: return "IDENTIFIER";
199 case TYPE_NAME: return "TYPE_NAME";
200 case CONSTANT: return "CONSTANT";
201 case STRING_LITERAL: return "STRING_LITERAL";
202 case SIZEOF: return "SIZEOF";
203 case PTR_OP: return "PTR_OP";
204 case INC_OP: return "INC_OP";
205 case DEC_OP: return "DEC_OP";
206 case LEFT_OP: return "LEFT_OP";
207 case RIGHT_OP: return "RIGHT_OP";
208 case LE_OP: return "LE_OP";
209 case GE_OP: return "GE_OP";
210 case EQ_OP: return "EQ_OP";
211 case NE_OP: return "NE_OP";
212 case AND_OP: return "AND_OP";
213 case OR_OP: return "OR_OP";
214 case MUL_ASSIGN: return "MUL_ASSIGN";
215 case DIV_ASSIGN: return "DIV_ASSIGN";
216 case MOD_ASSIGN: return "MOD_ASSIGN";
217 case ADD_ASSIGN: return "ADD_ASSIGN";
218 case SUB_ASSIGN: return "SUB_ASSIGN";
219 case LEFT_ASSIGN: return "LEFT_ASSIGN";
220 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
221 case AND_ASSIGN: return "AND_ASSIGN";
222 case XOR_ASSIGN: return "XOR_ASSIGN";
223 case OR_ASSIGN: return "OR_ASSIGN";
224 case TYPEDEF: return "TYPEDEF";
225 case EXTERN: return "EXTERN";
226 case STATIC: return "STATIC";
227 case AUTO: return "AUTO";
228 case REGISTER: return "REGISTER";
229 case CODE: return "CODE";
230 case EEPROM: return "EEPROM";
231 case INTERRUPT: return "INTERRUPT";
232 case SFR: return "SFR";
233 case AT: return "AT";
234 case SBIT: return "SBIT";
235 case REENTRANT: return "REENTRANT";
236 case USING: return "USING";
237 case XDATA: return "XDATA";
238 case DATA: return "DATA";
239 case IDATA: return "IDATA";
240 case PDATA: return "PDATA";
241 case VAR_ARGS: return "VAR_ARGS";
242 case CRITICAL: return "CRITICAL";
243 case NONBANKED: return "NONBANKED";
244 case BANKED: return "BANKED";
245 case CHAR: return "CHAR";
246 case SHORT: return "SHORT";
247 case INT: return "INT";
248 case LONG: return "LONG";
249 case SIGNED: return "SIGNED";
250 case UNSIGNED: return "UNSIGNED";
251 case FLOAT: return "FLOAT";
252 case DOUBLE: return "DOUBLE";
253 case CONST: return "CONST";
254 case VOLATILE: return "VOLATILE";
255 case VOID: return "VOID";
256 case BIT: return "BIT";
257 case STRUCT: return "STRUCT";
258 case UNION: return "UNION";
259 case ENUM: return "ENUM";
260 case ELIPSIS: return "ELIPSIS";
261 case RANGE: return "RANGE";
262 case FAR: return "FAR";
263 case CASE: return "CASE";
264 case DEFAULT: return "DEFAULT";
265 case IF: return "IF";
266 case ELSE: return "ELSE";
267 case SWITCH: return "SWITCH";
268 case WHILE: return "WHILE";
269 case DO: return "DO";
270 case FOR: return "FOR";
271 case GOTO: return "GOTO";
272 case CONTINUE: return "CONTINUE";
273 case BREAK: return "BREAK";
274 case RETURN: return "RETURN";
275 case INLINEASM: return "INLINEASM";
276 case IFX: return "IFX";
277 case ADDRESS_OF: return "ADDRESS_OF";
278 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
279 case SPIL: return "SPIL";
280 case UNSPIL: return "UNSPIL";
281 case GETHBIT: return "GETHBIT";
282 case BITWISEAND: return "BITWISEAND";
283 case UNARYMINUS: return "UNARYMINUS";
284 case IPUSH: return "IPUSH";
285 case IPOP: return "IPOP";
286 case PCALL: return "PCALL";
287 case ENDFUNCTION: return "ENDFUNCTION";
288 case JUMPTABLE: return "JUMPTABLE";
289 case RRC: return "RRC";
290 case RLC: return "RLC";
291 case CAST: return "CAST";
292 case CALL: return "CALL";
293 case PARAM: return "PARAM ";
294 case NULLOP: return "NULLOP";
295 case BLOCK: return "BLOCK";
296 case LABEL: return "LABEL";
297 case RECEIVE: return "RECEIVE";
298 case SEND: return "SEND";
300 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
303 /*-----------------------------------------------------------------*/
304 /*-----------------------------------------------------------------*/
306 debugLogRegType (short type)
311 case REG_GPR: return "REG_GPR";
312 case REG_PTR: return "REG_PTR";
313 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
320 /*-----------------------------------------------------------------*/
321 /*-----------------------------------------------------------------*/
322 static int regname2key(char const *name)
331 key += (*name++) + 1;
335 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
339 static regs *regWithIdx (set *dRegs, int idx, int fixed);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
348 /* check whether a matching register already exists */
349 dReg = dirregWithName( name );
351 //printf( "%s: already present: %s\n", __FUNCTION__, name );
354 dReg = regWithIdx( dynDirectRegs, rIdx, 0 );
355 if (!dReg) dReg = regWithIdx( dynDirectRegs, rIdx, 1 );
358 //printf( "%s: already present %s (idx:%d/%x)", __FUNCTION__, name, rIdx, rIdx );
362 dReg = Safe_calloc(1,sizeof(regs));
364 dReg->pc_type = pc_type;
367 dReg->name = Safe_strdup(name);
369 sprintf(buffer,"r0x%02X", dReg->rIdx);
370 dReg->name = Safe_strdup(buffer);
386 dReg->reg_alias = NULL;
387 dReg->reglives.usedpFlows = newSet();
388 dReg->reglives.assignedpFlows = newSet();
390 hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
392 debugLog( "%s: Created register %s (%p).\n",
393 __FUNCTION__, dReg->name, __builtin_return_address(0) );
395 debugLog( "%s: Created register %s.\n",
396 __FUNCTION__, dReg->name);
401 /*-----------------------------------------------------------------*/
402 /* regWithIdx - Search through a set of registers that matches idx */
403 /*-----------------------------------------------------------------*/
405 regWithIdx (set *dRegs, int idx, int fixed)
409 for (dReg = setFirstItem(dRegs) ; dReg ;
410 dReg = setNextItem(dRegs)) {
412 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
420 /*-----------------------------------------------------------------*/
421 /* regWithName - Search through a set of registers that matches name */
422 /*-----------------------------------------------------------------*/
424 regWithName (set *dRegs, const char *name)
428 for (dReg = setFirstItem(dRegs) ; dReg ;
429 dReg = setNextItem(dRegs)) {
431 if((strcmp(name,dReg->name)==0)) {
439 /*-----------------------------------------------------------------*/
440 /* regWithName - Search for a registers that matches name */
441 /*-----------------------------------------------------------------*/
443 regFindWithName (const char *name)
447 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
448 debugLog ("Found a Direct Register!\n");
451 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
452 debugLog ("Found a Direct Bit Register!\n");
456 if (*name=='_') name++; // Step passed '_'
458 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
459 debugLog ("Found a Dynamic Register!\n");
462 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
463 debugLog ("Found a Processor Register!\n");
466 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
467 debugLog ("Found an Internal Register!\n");
470 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
471 debugLog ("Found an Stack Register!\n");
478 /*-----------------------------------------------------------------*/
479 /* regFindFree - Search for a free register in a set of registers */
480 /*-----------------------------------------------------------------*/
482 regFindFree (set *dRegs)
486 for (dReg = setFirstItem(dRegs) ; dReg ;
487 dReg = setNextItem(dRegs)) {
495 /*-----------------------------------------------------------------*/
496 /* initStack - allocate registers for a pseudo stack */
497 /*-----------------------------------------------------------------*/
498 void initStack(int base_address, int size)
503 Gstack_base_addr = base_address;
505 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
507 for(i = 0; i<size; i++) {
510 SNPRINTF(&buffer[0], 16, "STK%02d", i);
511 r = newReg(REG_STK, PO_GPR_TEMP,base_address,buffer,1,0);
512 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
516 r->alias = 0x180; // Using shared memory for pseudo stack
517 addSet(&dynStackRegs,r);
522 /*-----------------------------------------------------------------*
523 *-----------------------------------------------------------------*/
525 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
528 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
529 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
532 /*-----------------------------------------------------------------*
533 *-----------------------------------------------------------------*/
536 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
538 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
540 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
543 return addSet(&dynInternalRegs,reg);
548 /*-----------------------------------------------------------------*/
549 /* allocReg - allocates register of given type */
550 /*-----------------------------------------------------------------*/
552 allocReg (short type)
556 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
557 //fprintf(stderr,"allocReg\n");
559 reg = pic14_findFreeReg (type);
567 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
572 /*-----------------------------------------------------------------*/
573 /* dirregWithName - search for register by name */
574 /*-----------------------------------------------------------------*/
576 dirregWithName (char *name)
584 /* hash the name to get a key */
586 hkey = regname2key(name);
588 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
592 if(STRCASECMP(reg->name, name) == 0) {
596 reg = hTabNextItemWK (dynDirectRegNames);
600 return NULL; // name wasn't found in the hash table
603 int IS_CONFIG_ADDRESS(int address)
606 return ((address == 0x2007) || (address == 0x2008));
609 /*-----------------------------------------------------------------*/
610 /* allocNewDirReg - allocates a new register of given type */
611 /*-----------------------------------------------------------------*/
613 allocNewDirReg (sym_link *symlnk,const char *name)
617 sym_link *spec = getSpec (symlnk);
619 /* if this is at an absolute address, then get the address. */
620 if (SPEC_ABSA (spec) ) {
621 address = SPEC_ADDR (spec);
622 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
625 /* Register wasn't found in hash, so let's create
626 * a new one and put it in the hash table AND in the
627 * dynDirectRegNames set */
628 if (IS_CONFIG_ADDRESS(address)) {
629 debugLog (" -- %s is declared at address 0x2007\n",name);
634 if (IS_BITVAR (spec))
641 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
642 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
644 if (SPEC_ABSA (spec) ) {
648 if (IS_BITVAR (spec)) {
649 addSet(&dynDirectBitRegs, reg);
652 addSet(&dynDirectRegs, reg);
654 if (!IS_STATIC (spec)) {
657 if (IS_EXTERN (spec)) {
663 if (address && reg) {
665 reg->address = address;
666 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
672 /*-----------------------------------------------------------------*/
673 /* allocDirReg - allocates register of given type */
674 /*-----------------------------------------------------------------*/
676 allocDirReg (operand *op )
683 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
687 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
689 /* If the symbol is at a fixed address, then remove the leading underscore
690 * from the name. This is hack to allow the .asm include file named registers
691 * to match the .c declared register names */
693 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
696 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
698 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
699 debugLog(" %d const char\n",__LINE__);
700 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
703 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
704 if (IS_CODE ( OP_SYM_ETYPE(op)) )
705 debugLog(" %d code space\n",__LINE__);
707 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
708 debugLog(" %d integral\n",__LINE__);
709 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
710 debugLog(" %d literal\n",__LINE__);
711 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
712 debugLog(" %d specifier\n",__LINE__);
713 debugAopGet(NULL, op);
716 if (IS_CODE ( OP_SYM_ETYPE(op)) )
719 /* First, search the hash table to see if there is a register with this name */
720 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
721 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
724 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
725 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
727 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
728 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
731 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
733 reg = dirregWithName(name);
740 /* if this is at an absolute address, then get the address. */
741 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
742 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
743 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
746 /* Register wasn't found in hash, so let's create
747 * a new one and put it in the hash table AND in the
748 * dynDirectRegNames set */
749 if(!IS_CONFIG_ADDRESS(address)) {
750 //fprintf(stderr,"allocating new reg %s\n",name);
752 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
753 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
755 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
757 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
759 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
763 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
764 addSet(&dynDirectBitRegs, reg);
767 addSet(&dynDirectRegs, reg);
769 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
772 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
778 debugLog (" -- %s is declared at address 0x2007\n",name);
783 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
785 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
786 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
791 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
793 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
794 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
797 allocNewDirReg (OP_SYM_TYPE(op),name);
804 /*-----------------------------------------------------------------*/
805 /* allocRegByName - allocates register with given name */
806 /*-----------------------------------------------------------------*/
808 allocRegByName (char *name, int size)
814 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
818 /* First, search the hash table to see if there is a register with this name */
819 reg = dirregWithName(name);
825 /* Register wasn't found in hash, so let's create
826 * a new one and put it in the hash table AND in the
827 * dynDirectRegNames set */
828 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
829 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
830 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
831 if (strcmp(reg->name+1,sym->name)==0) {
832 unsigned a = SPEC_ADDR(sym->etype);
836 if (!IS_STATIC (sym->etype)) {
839 if (IS_EXTERN (sym->etype)) {
842 if (IS_BITVAR (sym->etype))
849 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
850 if (strcmp(reg->name+1,sym->name)==0) {
851 unsigned a = SPEC_ADDR(sym->etype);
853 if (!IS_STATIC (sym->etype)) {
856 if (IS_EXTERN (sym->etype)) {
859 if (IS_BITVAR (sym->etype))
867 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
869 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
870 if (reg->isBitField) {
871 addSet(&dynDirectBitRegs, reg);
873 addSet(&dynDirectRegs, reg);
879 /*-----------------------------------------------------------------*/
880 /* RegWithIdx - returns pointer to register with index number */
881 /*-----------------------------------------------------------------*/
883 typeRegWithIdx (int idx, int type, int fixed)
888 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
893 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
895 debugLog ("Found a Dynamic Register!\n");
898 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
899 debugLog ("Found a Direct Register!\n");
905 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
906 debugLog ("Found a Stack Register!\n");
910 werror (E_STACK_OUT, "Register");
911 /* return an existing register just to avoid the SDCC crash */
912 return regWithIdx ( dynStackRegs, 0x7f, fixed);
916 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
917 debugLog ("Found a Processor Register!\n");
931 /*-----------------------------------------------------------------*/
932 /* pic14_regWithIdx - returns pointer to register with index number*/
933 /*-----------------------------------------------------------------*/
935 pic14_regWithIdx (int idx)
939 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
942 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
948 /*-----------------------------------------------------------------*/
949 /* pic14_regWithIdx - returns pointer to register with index number */
950 /*-----------------------------------------------------------------*/
952 pic14_allocWithIdx (int idx)
957 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
959 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
961 debugLog ("Found a Dynamic Register!\n");
962 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
963 debugLog ("Found a Stack Register!\n");
964 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
965 debugLog ("Found a Processor Register!\n");
966 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
967 debugLog ("Found an Internal Register!\n");
968 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
969 debugLog ("Found an Internal Register!\n");
972 debugLog ("Dynamic Register not found\n");
975 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
976 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
977 "regWithIdx not found");
987 /*-----------------------------------------------------------------*/
988 /*-----------------------------------------------------------------*/
990 pic14_findFreeReg(short type)
997 if((dReg = regFindFree(dynAllocRegs)) != NULL)
999 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1003 if((dReg = regFindFree(dynStackRegs)) != NULL)
1015 /*-----------------------------------------------------------------*/
1016 /* freeReg - frees a register */
1017 /*-----------------------------------------------------------------*/
1019 freeReg (regs * reg)
1021 debugLog ("%s\n", __FUNCTION__);
1026 /*-----------------------------------------------------------------*/
1027 /* nFreeRegs - returns number of free registers */
1028 /*-----------------------------------------------------------------*/
1030 nFreeRegs (int type)
1032 /* dynamically allocate as many as we need and worry about
1033 * fitting them into a PIC later */
1040 debugLog ("%s\n", __FUNCTION__);
1041 for (i = 0; i < pic14_nRegs; i++)
1042 if (regspic14[i].isFree && regspic14[i].type == type)
1048 /*-----------------------------------------------------------------*/
1049 /* nfreeRegsType - free registers with type */
1050 /*-----------------------------------------------------------------*/
1052 nfreeRegsType (int type)
1055 debugLog ("%s\n", __FUNCTION__);
1056 if (type == REG_PTR)
1058 if ((nfr = nFreeRegs (type)) == 0)
1059 return nFreeRegs (REG_GPR);
1062 return nFreeRegs (type);
1065 void writeSetUsedRegs(FILE *of, set *dRegs)
1070 for (dReg = setFirstItem(dRegs) ; dReg ;
1071 dReg = setNextItem(dRegs)) {
1074 fprintf (of, "\t%s\n",dReg->name);
1078 extern void assignFixedRegisters(set *regset);
1079 extern void assignRelocatableRegisters(set *regset,int used);
1080 extern void dump_map(void);
1081 extern void dump_sfr(FILE *of);
1083 void packBits(set *bregs)
1087 regs *bitfield=NULL;
1088 regs *relocbitfield=NULL;
1094 for (regset = bregs ; regset ;
1095 regset = regset->next) {
1097 breg = regset->item;
1098 breg->isBitField = 1;
1099 //fprintf(stderr,"bit reg: %s\n",breg->name);
1102 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1104 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1105 breg->rIdx = breg->address & 7;
1106 breg->address >>= 3;
1109 //sprintf (buffer, "fbitfield%02x", breg->address);
1110 sprintf (buffer, "0x%02x", breg->address);
1111 //fprintf(stderr,"new bit field\n");
1112 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1113 bitfield->isBitField = 1;
1114 bitfield->isFixed = 1;
1115 bitfield->address = breg->address;
1116 //addSet(&dynDirectRegs,bitfield);
1117 addSet(&dynInternalRegs,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);
1133 relocbitfield->isBitField = 1;
1134 //addSet(&dynDirectRegs,relocbitfield);
1135 addSet(&dynInternalRegs,relocbitfield);
1136 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1140 breg->reg_alias = relocbitfield;
1141 breg->address = rDirectIdx; /* byte_no; */
1142 breg->rIdx = bit_no++;
1150 void bitEQUs(FILE *of, set *bregs)
1152 regs *breg,*bytereg;
1155 //fprintf(stderr," %s\n",__FUNCTION__);
1156 for (breg = setFirstItem(bregs) ; breg ;
1157 breg = setNextItem(bregs)) {
1159 //fprintf(stderr,"bit reg: %s\n",breg->name);
1161 bytereg = breg->reg_alias;
1163 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1166 breg->rIdx & 0x0007);
1169 //fprintf(stderr, "bit field is not assigned to a register\n");
1170 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1180 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1185 for (reg = setFirstItem(fregs) ; reg ;
1186 reg = setNextItem(fregs)) {
1188 //if(!reg->isEmitted && reg->wasUsed) {
1191 fprintf (of, "%s\tEQU\t0x%03x\n",
1195 fprintf (of, "%s\tEQU\t0x%03x\n",
1203 void writeUsedRegs(FILE *of)
1205 packBits(dynDirectBitRegs);
1207 assignFixedRegisters(dynInternalRegs);
1208 assignFixedRegisters(dynAllocRegs);
1209 assignFixedRegisters(dynStackRegs);
1210 assignFixedRegisters(dynDirectRegs);
1212 assignRelocatableRegisters(dynInternalRegs,0);
1213 assignRelocatableRegisters(dynAllocRegs,0);
1214 assignRelocatableRegisters(dynStackRegs,0);
1216 assignRelocatableRegisters(dynDirectRegs,0);
1218 assignRelocatableRegisters(dynDirectRegs,0);
1219 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1224 bitEQUs(of,dynDirectBitRegs);
1226 aliasEQUs(of,dynAllocRegs,0);
1227 aliasEQUs(of,dynDirectRegs,0);
1228 aliasEQUs(of,dynStackRegs,0);
1229 aliasEQUs(of,dynProcessorRegs,1);
1234 /*-----------------------------------------------------------------*/
1235 /* allDefsOutOfRange - all definitions are out of a range */
1236 /*-----------------------------------------------------------------*/
1238 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1242 debugLog ("%s\n", __FUNCTION__);
1246 for (i = 0; i < defs->size; i++)
1250 if (bitVectBitValue (defs, i) &&
1251 (ic = hTabItemWithKey (iCodehTab, i)) &&
1252 (ic->seq >= fseq && ic->seq <= toseq))
1262 /*-----------------------------------------------------------------*/
1263 /* computeSpillable - given a point find the spillable live ranges */
1264 /*-----------------------------------------------------------------*/
1266 computeSpillable (iCode * ic)
1270 debugLog ("%s\n", __FUNCTION__);
1271 /* spillable live ranges are those that are live at this
1272 point . the following categories need to be subtracted
1274 a) - those that are already spilt
1275 b) - if being used by this one
1276 c) - defined by this one */
1278 spillable = bitVectCopy (ic->rlive);
1280 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1282 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1283 bitVectUnSetBit (spillable, ic->defKey);
1284 spillable = bitVectIntersect (spillable, _G.regAssigned);
1289 /*-----------------------------------------------------------------*/
1290 /* noSpilLoc - return true if a variable has no spil location */
1291 /*-----------------------------------------------------------------*/
1293 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1295 debugLog ("%s\n", __FUNCTION__);
1296 return (sym->usl.spillLoc ? 0 : 1);
1299 /*-----------------------------------------------------------------*/
1300 /* hasSpilLoc - will return 1 if the symbol has spil location */
1301 /*-----------------------------------------------------------------*/
1303 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1305 debugLog ("%s\n", __FUNCTION__);
1306 return (sym->usl.spillLoc ? 1 : 0);
1309 /*-----------------------------------------------------------------*/
1310 /* directSpilLoc - will return 1 if the splilocation is in direct */
1311 /*-----------------------------------------------------------------*/
1313 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1315 debugLog ("%s\n", __FUNCTION__);
1316 if (sym->usl.spillLoc &&
1317 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1323 /*-----------------------------------------------------------------*/
1324 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1325 /* but is not used as a pointer */
1326 /*-----------------------------------------------------------------*/
1328 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1330 debugLog ("%s\n", __FUNCTION__);
1331 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1334 /*-----------------------------------------------------------------*/
1335 /* rematable - will return 1 if the remat flag is set */
1336 /*-----------------------------------------------------------------*/
1338 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1340 debugLog ("%s\n", __FUNCTION__);
1344 /*-----------------------------------------------------------------*/
1345 /* notUsedInRemaining - not used or defined in remain of the block */
1346 /*-----------------------------------------------------------------*/
1348 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1350 debugLog ("%s\n", __FUNCTION__);
1351 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1352 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1355 /*-----------------------------------------------------------------*/
1356 /* allLRs - return true for all */
1357 /*-----------------------------------------------------------------*/
1359 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1361 debugLog ("%s\n", __FUNCTION__);
1365 /*-----------------------------------------------------------------*/
1366 /* liveRangesWith - applies function to a given set of live range */
1367 /*-----------------------------------------------------------------*/
1369 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1370 eBBlock * ebp, iCode * ic)
1375 debugLog ("%s\n", __FUNCTION__);
1376 if (!lrs || !lrs->size)
1379 for (i = 1; i < lrs->size; i++)
1382 if (!bitVectBitValue (lrs, i))
1385 /* if we don't find it in the live range
1386 hash table we are in serious trouble */
1387 if (!(sym = hTabItemWithKey (liveRanges, i)))
1389 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1390 "liveRangesWith could not find liveRange");
1394 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1395 addSetHead (&rset, sym);
1402 /*-----------------------------------------------------------------*/
1403 /* leastUsedLR - given a set determines which is the least used */
1404 /*-----------------------------------------------------------------*/
1406 leastUsedLR (set * sset)
1408 symbol *sym = NULL, *lsym = NULL;
1410 debugLog ("%s\n", __FUNCTION__);
1411 sym = lsym = setFirstItem (sset);
1416 for (; lsym; lsym = setNextItem (sset))
1419 /* if usage is the same then prefer
1420 the spill the smaller of the two */
1421 if (lsym->used == sym->used)
1422 if (getSize (lsym->type) < getSize (sym->type))
1426 if (lsym->used < sym->used)
1431 setToNull ((void *) &sset);
1436 /*-----------------------------------------------------------------*/
1437 /* noOverLap - will iterate through the list looking for over lap */
1438 /*-----------------------------------------------------------------*/
1440 noOverLap (set * itmpStack, symbol * fsym)
1443 debugLog ("%s\n", __FUNCTION__);
1446 for (sym = setFirstItem (itmpStack); sym;
1447 sym = setNextItem (itmpStack))
1449 if (sym->liveTo > fsym->liveFrom)
1457 /*-----------------------------------------------------------------*/
1458 /* isFree - will return 1 if the a free spil location is found */
1459 /*-----------------------------------------------------------------*/
1464 V_ARG (symbol **, sloc);
1465 V_ARG (symbol *, fsym);
1467 debugLog ("%s\n", __FUNCTION__);
1468 /* if already found */
1472 /* if it is free && and the itmp assigned to
1473 this does not have any overlapping live ranges
1474 with the one currently being assigned and
1475 the size can be accomodated */
1477 noOverLap (sym->usl.itmpStack, fsym) &&
1478 getSize (sym->type) >= getSize (fsym->type))
1487 /*-----------------------------------------------------------------*/
1488 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1489 /*-----------------------------------------------------------------*/
1491 spillLRWithPtrReg (symbol * forSym)
1497 debugLog ("%s\n", __FUNCTION__);
1498 if (!_G.regAssigned ||
1499 bitVectIsZero (_G.regAssigned))
1502 r0 = pic14_regWithIdx (R0_IDX);
1503 r1 = pic14_regWithIdx (R1_IDX);
1505 /* for all live ranges */
1506 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1507 lrsym = hTabNextItem (liveRanges, &k))
1511 /* if no registers assigned to it or
1513 /* if it does not overlap with this then
1514 not need to spill it */
1516 if (lrsym->isspilt || !lrsym->nRegs ||
1517 (lrsym->liveTo < forSym->liveFrom))
1520 /* go thru the registers : if it is either
1521 r0 or r1 then spil it */
1522 for (j = 0; j < lrsym->nRegs; j++)
1523 if (lrsym->regs[j] == r0 ||
1524 lrsym->regs[j] == r1)
1533 /*-----------------------------------------------------------------*/
1534 /* createStackSpil - create a location on the stack to spil */
1535 /*-----------------------------------------------------------------*/
1537 createStackSpil (symbol * sym)
1539 symbol *sloc = NULL;
1540 int useXstack, model, noOverlay;
1542 char slocBuffer[30];
1543 debugLog ("%s\n", __FUNCTION__);
1547 /* first go try and find a free one that is already
1548 existing on the stack */
1549 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1551 /* found a free one : just update & return */
1552 sym->usl.spillLoc = sloc;
1555 addSetHead (&sloc->usl.itmpStack, sym);
1559 /* could not then have to create one , this is the hard part
1560 we need to allocate this on the stack : this is really a
1561 hack!! but cannot think of anything better at this time */
1563 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1565 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1566 __FILE__, __LINE__);
1570 sloc = newiTemp (slocBuffer);
1572 /* set the type to the spilling symbol */
1573 sloc->type = copyLinkChain (sym->type);
1574 sloc->etype = getSpec (sloc->type);
1575 SPEC_SCLS (sloc->etype) = S_DATA;
1576 SPEC_EXTR (sloc->etype) = 0;
1577 SPEC_STAT (sloc->etype) = 0;
1579 /* we don't allow it to be allocated`
1580 onto the external stack since : so we
1581 temporarily turn it off ; we also
1582 turn off memory model to prevent
1583 the spil from going to the external storage
1584 and turn off overlaying
1587 useXstack = options.useXstack;
1588 model = options.model;
1589 noOverlay = options.noOverlay;
1590 options.noOverlay = 1;
1591 options.model = options.useXstack = 0;
1595 options.useXstack = useXstack;
1596 options.model = model;
1597 options.noOverlay = noOverlay;
1598 sloc->isref = 1; /* to prevent compiler warning */
1600 /* if it is on the stack then update the stack */
1601 if (IN_STACK (sloc->etype))
1603 currFunc->stack += getSize (sloc->type);
1604 _G.stackExtend += getSize (sloc->type);
1607 _G.dataExtend += getSize (sloc->type);
1609 /* add it to the _G.stackSpil set */
1610 addSetHead (&_G.stackSpil, sloc);
1611 sym->usl.spillLoc = sloc;
1614 /* add it to the set of itempStack set
1615 of the spill location */
1616 addSetHead (&sloc->usl.itmpStack, sym);
1620 /*-----------------------------------------------------------------*/
1621 /* isSpiltOnStack - returns true if the spil location is on stack */
1622 /*-----------------------------------------------------------------*/
1624 isSpiltOnStack (symbol * sym)
1628 debugLog ("%s\n", __FUNCTION__);
1637 /* if (sym->_G.stackSpil) */
1640 if (!sym->usl.spillLoc)
1643 etype = getSpec (sym->usl.spillLoc->type);
1644 if (IN_STACK (etype))
1650 /*-----------------------------------------------------------------*/
1651 /* spillThis - spils a specific operand */
1652 /*-----------------------------------------------------------------*/
1654 spillThis (symbol * sym)
1657 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1658 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1660 /* if this is rematerializable or has a spillLocation
1661 we are okay, else we need to create a spillLocation
1663 if (!(sym->remat || sym->usl.spillLoc))
1664 createStackSpil (sym);
1667 /* mark it has spilt & put it in the spilt set */
1669 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1671 bitVectUnSetBit (_G.regAssigned, sym->key);
1673 for (i = 0; i < sym->nRegs; i++)
1677 freeReg (sym->regs[i]);
1678 sym->regs[i] = NULL;
1682 /* if spilt on stack then free up r0 & r1
1683 if they could have been assigned to some
1685 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1688 spillLRWithPtrReg (sym);
1691 if (sym->usl.spillLoc && !sym->remat)
1692 sym->usl.spillLoc->allocreq = 1;
1697 /*-----------------------------------------------------------------*/
1698 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1699 /*-----------------------------------------------------------------*/
1701 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1703 bitVect *lrcs = NULL;
1707 debugLog ("%s\n", __FUNCTION__);
1709 /* get the spillable live ranges */
1710 lrcs = computeSpillable (ic);
1713 /* get all live ranges that are rematerizable */
1714 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1716 /* return the least used of these */
1717 return leastUsedLR (selectS);
1720 /* get live ranges with spillLocations in direct space */
1721 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1723 sym = leastUsedLR (selectS);
1724 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1725 sym->usl.spillLoc->rname :
1726 sym->usl.spillLoc->name));
1728 /* mark it as allocation required */
1729 sym->usl.spillLoc->allocreq = 1;
1733 /* if the symbol is local to the block then */
1734 if (forSym->liveTo < ebp->lSeq)
1737 /* check if there are any live ranges allocated
1738 to registers that are not used in this block */
1739 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1741 sym = leastUsedLR (selectS);
1742 /* if this is not rematerializable */
1751 /* check if there are any live ranges that not
1752 used in the remainder of the block */
1753 if (!_G.blockSpil &&
1754 !isiCodeInFunctionCall (ic) &&
1755 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1757 sym = leastUsedLR (selectS);
1760 sym->remainSpil = 1;
1767 /* find live ranges with spillocation && not used as pointers */
1768 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1771 sym = leastUsedLR (selectS);
1772 /* mark this as allocation required */
1773 sym->usl.spillLoc->allocreq = 1;
1777 /* find live ranges with spillocation */
1778 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1781 sym = leastUsedLR (selectS);
1782 sym->usl.spillLoc->allocreq = 1;
1786 /* couldn't find then we need to create a spil
1787 location on the stack , for which one? the least
1789 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1792 /* return a created spil location */
1793 sym = createStackSpil (leastUsedLR (selectS));
1794 sym->usl.spillLoc->allocreq = 1;
1798 /* this is an extreme situation we will spill
1799 this one : happens very rarely but it does happen */
1805 /*-----------------------------------------------------------------*/
1806 /* spilSomething - spil some variable & mark registers as free */
1807 /*-----------------------------------------------------------------*/
1809 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1814 debugLog ("%s\n", __FUNCTION__);
1815 /* get something we can spil */
1816 ssym = selectSpil (ic, ebp, forSym);
1818 /* mark it as spilt */
1820 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1822 /* mark it as not register assigned &
1823 take it away from the set */
1824 bitVectUnSetBit (_G.regAssigned, ssym->key);
1826 /* mark the registers as free */
1827 for (i = 0; i < ssym->nRegs; i++)
1829 freeReg (ssym->regs[i]);
1831 /* if spilt on stack then free up r0 & r1
1832 if they could have been assigned to as gprs */
1833 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1836 spillLRWithPtrReg (ssym);
1839 /* if this was a block level spil then insert push & pop
1840 at the start & end of block respectively */
1841 if (ssym->blockSpil)
1843 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1844 /* add push to the start of the block */
1845 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1846 ebp->sch->next : ebp->sch));
1847 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1848 /* add pop to the end of the block */
1849 addiCodeToeBBlock (ebp, nic, NULL);
1852 /* if spilt because not used in the remainder of the
1853 block then add a push before this instruction and
1854 a pop at the end of the block */
1855 if (ssym->remainSpil)
1858 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1859 /* add push just before this instruction */
1860 addiCodeToeBBlock (ebp, nic, ic);
1862 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1863 /* add pop to the end of the block */
1864 addiCodeToeBBlock (ebp, nic, NULL);
1873 /*-----------------------------------------------------------------*/
1874 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1875 /*-----------------------------------------------------------------*/
1877 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1882 debugLog ("%s\n", __FUNCTION__);
1884 /* try for a ptr type */
1885 if ((reg = allocReg (REG_PTR)))
1888 /* try for gpr type */
1889 if ((reg = allocReg (REG_GPR)))
1892 /* we have to spil */
1893 if (!spilSomething (ic, ebp, sym))
1896 /* make sure partially assigned registers aren't reused */
1897 for (j=0; j<=sym->nRegs; j++)
1899 sym->regs[j]->isFree = 0;
1901 /* this looks like an infinite loop but
1902 in really selectSpil will abort */
1906 /*-----------------------------------------------------------------*/
1907 /* getRegGpr - will try for GPR if not spil */
1908 /*-----------------------------------------------------------------*/
1910 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1915 debugLog ("%s\n", __FUNCTION__);
1917 /* try for gpr type */
1918 if ((reg = allocReg (REG_GPR)))
1921 if (!pic14_ptrRegReq)
1922 if ((reg = allocReg (REG_PTR)))
1925 /* we have to spil */
1926 if (!spilSomething (ic, ebp, sym))
1929 /* make sure partially assigned registers aren't reused */
1930 for (j=0; j<=sym->nRegs; j++)
1932 sym->regs[j]->isFree = 0;
1934 /* this looks like an infinite loop but
1935 in really selectSpil will abort */
1939 /*-----------------------------------------------------------------*/
1940 /* symHasReg - symbol has a given register */
1941 /*-----------------------------------------------------------------*/
1943 symHasReg (symbol * sym, regs * reg)
1947 debugLog ("%s\n", __FUNCTION__);
1948 for (i = 0; i < sym->nRegs; i++)
1949 if (sym->regs[i] == reg)
1955 /*-----------------------------------------------------------------*/
1956 /* deassignLRs - check the live to and if they have registers & are */
1957 /* not spilt then free up the registers */
1958 /*-----------------------------------------------------------------*/
1960 deassignLRs (iCode * ic, eBBlock * ebp)
1966 debugLog ("%s\n", __FUNCTION__);
1967 for (sym = hTabFirstItem (liveRanges, &k); sym;
1968 sym = hTabNextItem (liveRanges, &k))
1971 symbol *psym = NULL;
1972 /* if it does not end here */
1973 if (sym->liveTo > ic->seq)
1976 /* Prevent the result from being assigned the same registers as (one)
1977 * operand as many genXXX-functions fail otherwise.
1978 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1979 * are known to fail. */
1980 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1984 case '=': /* assignment */
1985 case BITWISEAND: /* bitwise AND */
1986 case '|': /* bitwise OR */
1987 case '^': /* bitwise XOR */
1988 case '~': /* bitwise negate */
1989 case RLC: /* rotate through carry */
1992 case '+': /* addition */
1993 case '-': /* subtraction */
1994 /* go ahead, these are safe to use with
1995 * non-disjoint register sets */
1999 /* do not release operand registers */
2000 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
2005 /* if it was spilt on stack then we can
2006 mark the stack spil location as free */
2011 sym->usl.spillLoc->isFree = 1;
2017 if (!bitVectBitValue (_G.regAssigned, sym->key))
2019 /* special case check if this is an IFX &
2020 the privious one was a pop and the
2021 previous one was not spilt then keep track
2023 if (ic->op == IFX && ic->prev &&
2024 ic->prev->op == IPOP &&
2025 !ic->prev->parmPush &&
2026 IS_SYMOP(IC_LEFT (ic->prev)) &&
2027 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2028 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2034 bitVectUnSetBit (_G.regAssigned, sym->key);
2036 /* if the result of this one needs registers
2037 and does not have it then assign it right
2039 if (IC_RESULT (ic) &&
2040 !(SKIP_IC2 (ic) || /* not a special icode */
2041 ic->op == JUMPTABLE ||
2046 POINTER_SET (ic)) &&
2047 IS_SYMOP (IC_RESULT (ic)) &&
2048 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2049 result->liveTo > ic->seq && /* and will live beyond this */
2050 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2051 result->liveFrom == ic->seq && /* does not start before here */
2052 result->regType == sym->regType && /* same register types */
2053 result->regType == sym->regType && /* same register types */
2054 result->nRegs && /* which needs registers */
2055 !result->isspilt && /* and does not already have them */
2057 !bitVectBitValue (_G.regAssigned, result->key) &&
2058 /* the number of free regs + number of regs in this LR
2059 can accomodate the what result Needs */
2060 ((nfreeRegsType (result->regType) +
2061 sym->nRegs) >= result->nRegs)
2065 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2067 result->regs[i] = sym->regs[i];
2069 result->regs[i] = getRegGpr (ic, ebp, result);
2071 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2075 /* free the remaining */
2076 for (; i < sym->nRegs; i++)
2080 if (!symHasReg (psym, sym->regs[i]))
2081 freeReg (sym->regs[i]);
2084 freeReg (sym->regs[i]);
2091 /*-----------------------------------------------------------------*/
2092 /* reassignLR - reassign this to registers */
2093 /*-----------------------------------------------------------------*/
2095 reassignLR (operand * op)
2097 symbol *sym = OP_SYMBOL (op);
2100 debugLog ("%s\n", __FUNCTION__);
2101 /* not spilt any more */
2102 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2103 bitVectUnSetBit (_G.spiltSet, sym->key);
2105 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2109 for (i = 0; i < sym->nRegs; i++)
2110 sym->regs[i]->isFree = 0;
2113 /*-----------------------------------------------------------------*/
2114 /* willCauseSpill - determines if allocating will cause a spill */
2115 /*-----------------------------------------------------------------*/
2117 willCauseSpill (int nr, int rt)
2119 debugLog ("%s\n", __FUNCTION__);
2120 /* first check if there are any avlb registers
2121 of te type required */
2124 /* special case for pointer type
2125 if pointer type not avlb then
2126 check for type gpr */
2127 if (nFreeRegs (rt) >= nr)
2129 if (nFreeRegs (REG_GPR) >= nr)
2134 if (pic14_ptrRegReq)
2136 if (nFreeRegs (rt) >= nr)
2141 if (nFreeRegs (REG_PTR) +
2142 nFreeRegs (REG_GPR) >= nr)
2147 debugLog (" ... yep it will (cause a spill)\n");
2148 /* it will cause a spil */
2152 /*-----------------------------------------------------------------*/
2153 /* positionRegs - the allocator can allocate same registers to res- */
2154 /* ult and operand, if this happens make sure they are in the same */
2155 /* position as the operand otherwise chaos results */
2156 /*-----------------------------------------------------------------*/
2158 positionRegs (symbol * result, symbol * opsym, int lineno)
2160 int count = min (result->nRegs, opsym->nRegs);
2161 int i, j = 0, shared = 0;
2163 debugLog ("%s\n", __FUNCTION__);
2164 /* if the result has been spilt then cannot share */
2169 /* first make sure that they actually share */
2170 for (i = 0; i < count; i++)
2172 for (j = 0; j < count; j++)
2174 if (result->regs[i] == opsym->regs[j] && i != j)
2184 regs *tmp = result->regs[i];
2185 result->regs[i] = result->regs[j];
2186 result->regs[j] = tmp;
2191 /*------------------------------------------------------------------*/
2192 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2193 /* it should either have registers or have beed spilled. Otherwise, */
2194 /* there was an uninitialized variable, so just spill this to get */
2195 /* the operand in a valid state. */
2196 /*------------------------------------------------------------------*/
2198 verifyRegsAssigned (operand *op, iCode * ic)
2203 if (!IS_ITEMP (op)) return;
2205 sym = OP_SYMBOL (op);
2206 if (sym->isspilt) return;
2207 if (!sym->nRegs) return;
2208 if (sym->regs[0]) return;
2210 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2211 sym->prereqv ? sym->prereqv->name : sym->name);
2216 /*-----------------------------------------------------------------*/
2217 /* serialRegAssign - serially allocate registers to the variables */
2218 /*-----------------------------------------------------------------*/
2220 serialRegAssign (eBBlock ** ebbs, int count)
2224 debugLog ("%s\n", __FUNCTION__);
2225 /* for all blocks */
2226 for (i = 0; i < count; i++)
2231 if (ebbs[i]->noPath &&
2232 (ebbs[i]->entryLabel != entryLabel &&
2233 ebbs[i]->entryLabel != returnLabel))
2236 /* of all instructions do */
2237 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2239 debugLog (" op: %s\n", decodeOp (ic->op));
2241 /* if this is an ipop that means some live
2242 range will have to be assigned again */
2244 reassignLR (IC_LEFT (ic));
2246 /* if result is present && is a true symbol */
2247 if (IC_RESULT (ic) && ic->op != IFX &&
2248 IS_TRUE_SYMOP (IC_RESULT (ic)))
2249 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2251 /* take away registers from live
2252 ranges that end at this instruction */
2253 deassignLRs (ic, ebbs[i]);
2255 /* some don't need registers */
2256 if (SKIP_IC2 (ic) ||
2257 ic->op == JUMPTABLE ||
2261 (IC_RESULT (ic) && POINTER_SET (ic)))
2264 /* now we need to allocate registers
2265 only for the result */
2266 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2268 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2274 /* Make sure any spill location is definately allocated */
2275 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2276 !sym->usl.spillLoc->allocreq)
2278 sym->usl.spillLoc->allocreq++;
2281 /* if it does not need or is spilt
2282 or is already assigned to registers
2283 or will not live beyond this instructions */
2286 bitVectBitValue (_G.regAssigned, sym->key) ||
2287 sym->liveTo <= ic->seq)
2290 /* if some liverange has been spilt at the block level
2291 and this one live beyond this block then spil this
2293 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2298 /* if trying to allocate this will cause
2299 a spill and there is nothing to spill
2300 or this one is rematerializable then
2302 willCS = willCauseSpill (sym->nRegs, sym->regType);
2303 spillable = computeSpillable (ic);
2305 (willCS && bitVectIsZero (spillable)))
2313 /* If the live range preceeds the point of definition
2314 then ideally we must take into account registers that
2315 have been allocated after sym->liveFrom but freed
2316 before ic->seq. This is complicated, so spill this
2317 symbol instead and let fillGaps handle the allocation. */
2318 if (sym->liveFrom < ic->seq)
2324 /* if it has a spillocation & is used less than
2325 all other live ranges then spill this */
2327 if (sym->usl.spillLoc) {
2328 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2329 allLRs, ebbs[i], ic));
2330 if (leastUsed && leastUsed->used > sym->used) {
2335 /* if none of the liveRanges have a spillLocation then better
2336 to spill this one than anything else already assigned to registers */
2337 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2338 /* if this is local to this block then we might find a block spil */
2339 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2347 if (ic->op == RECEIVE)
2348 debugLog ("When I get clever, I'll optimize the receive logic\n");
2350 /* if we need ptr regs for the right side
2352 if (POINTER_GET (ic)
2353 && IS_SYMOP(IC_LEFT(ic))
2354 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2355 <= (unsigned) PTRSIZE)
2360 /* else we assign registers to it */
2361 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2363 debugLog (" %d - \n", __LINE__);
2365 bitVectDebugOn(_G.regAssigned, debugF);
2366 for (j = 0; j < sym->nRegs; j++)
2368 if (sym->regType == REG_PTR)
2369 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2371 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2373 /* if the allocation failed which means
2374 this was spilt then break */
2378 debugLog (" %d - \n", __LINE__);
2380 /* if it shares registers with operands make sure
2381 that they are in the same position */
2382 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2383 IS_SYMOP(IC_RESULT(ic)) &&
2384 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2385 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2386 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2387 /* do the same for the right operand */
2388 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2389 IS_SYMOP(IC_RESULT(ic)) &&
2390 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2391 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2392 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2394 debugLog (" %d - \n", __LINE__);
2397 debugLog (" %d - \n", __LINE__);
2406 /* Check for and fix any problems with uninitialized operands */
2407 for (i = 0; i < count; i++)
2411 if (ebbs[i]->noPath &&
2412 (ebbs[i]->entryLabel != entryLabel &&
2413 ebbs[i]->entryLabel != returnLabel))
2416 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2423 verifyRegsAssigned (IC_COND (ic), ic);
2427 if (ic->op == JUMPTABLE)
2429 verifyRegsAssigned (IC_JTCOND (ic), ic);
2433 verifyRegsAssigned (IC_RESULT (ic), ic);
2434 verifyRegsAssigned (IC_LEFT (ic), ic);
2435 verifyRegsAssigned (IC_RIGHT (ic), ic);
2441 /*-----------------------------------------------------------------*/
2442 /* rUmaskForOp :- returns register mask for an operand */
2443 /*-----------------------------------------------------------------*/
2445 rUmaskForOp (operand * op)
2451 debugLog ("%s\n", __FUNCTION__);
2452 /* only temporaries are assigned registers */
2456 sym = OP_SYMBOL (op);
2458 /* if spilt or no registers assigned to it
2460 if (sym->isspilt || !sym->nRegs)
2463 rumask = newBitVect (pic14_nRegs);
2465 for (j = 0; j < sym->nRegs; j++)
2467 rumask = bitVectSetBit (rumask,
2468 sym->regs[j]->rIdx);
2474 /*-----------------------------------------------------------------*/
2475 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2476 /*-----------------------------------------------------------------*/
2478 regsUsedIniCode (iCode * ic)
2480 bitVect *rmask = newBitVect (pic14_nRegs);
2482 debugLog ("%s\n", __FUNCTION__);
2483 /* do the special cases first */
2486 rmask = bitVectUnion (rmask,
2487 rUmaskForOp (IC_COND (ic)));
2491 /* for the jumptable */
2492 if (ic->op == JUMPTABLE)
2494 rmask = bitVectUnion (rmask,
2495 rUmaskForOp (IC_JTCOND (ic)));
2500 /* of all other cases */
2502 rmask = bitVectUnion (rmask,
2503 rUmaskForOp (IC_LEFT (ic)));
2507 rmask = bitVectUnion (rmask,
2508 rUmaskForOp (IC_RIGHT (ic)));
2511 rmask = bitVectUnion (rmask,
2512 rUmaskForOp (IC_RESULT (ic)));
2518 /*-----------------------------------------------------------------*/
2519 /* createRegMask - for each instruction will determine the regsUsed */
2520 /*-----------------------------------------------------------------*/
2522 createRegMask (eBBlock ** ebbs, int count)
2526 debugLog ("%s\n", __FUNCTION__);
2527 /* for all blocks */
2528 for (i = 0; i < count; i++)
2532 if (ebbs[i]->noPath &&
2533 (ebbs[i]->entryLabel != entryLabel &&
2534 ebbs[i]->entryLabel != returnLabel))
2537 /* for all instructions */
2538 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2543 if (SKIP_IC2 (ic) || !ic->rlive)
2546 /* first mark the registers used in this
2548 ic->rUsed = regsUsedIniCode (ic);
2549 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2551 /* now create the register mask for those
2552 registers that are in use : this is a
2553 super set of ic->rUsed */
2554 ic->rMask = newBitVect (pic14_nRegs + 1);
2556 /* for all live Ranges alive at this point */
2557 for (j = 1; j < ic->rlive->size; j++)
2562 /* if not alive then continue */
2563 if (!bitVectBitValue (ic->rlive, j))
2566 /* find the live range we are interested in */
2567 if (!(sym = hTabItemWithKey (liveRanges, j)))
2569 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2570 "createRegMask cannot find live range");
2574 /* if no register assigned to it */
2575 if (!sym->nRegs || sym->isspilt)
2578 /* for all the registers allocated to it */
2579 for (k = 0; k < sym->nRegs; k++)
2582 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2588 /* This was the active version */
2589 /*-----------------------------------------------------------------*/
2590 /* rematStr - returns the rematerialized string for a remat var */
2591 /*-----------------------------------------------------------------*/
2593 rematStr (symbol * sym)
2596 iCode *ic = sym->rematiCode;
2597 symbol *psym = NULL;
2599 debugLog ("%s\n", __FUNCTION__);
2601 //printf ("%s\n", s);
2603 /* if plus or minus print the right hand side */
2605 if (ic->op == '+' || ic->op == '-') {
2607 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2609 sprintf (s, "(%s %c 0x%04x)",
2610 OP_SYMBOL (IC_LEFT (ric))->rname,
2612 (int) operandLitValue (IC_RIGHT (ic)));
2615 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2617 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2618 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2623 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2624 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2626 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2632 /* deprecated version */
2633 /*-----------------------------------------------------------------*/
2634 /* rematStr - returns the rematerialized string for a remat var */
2635 /*-----------------------------------------------------------------*/
2637 rematStr (symbol * sym)
2640 iCode *ic = sym->rematiCode;
2642 debugLog ("%s\n", __FUNCTION__);
2647 /* if plus or minus print the right hand side */
2649 if (ic->op == '+' || ic->op == '-') {
2650 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2653 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2657 if (ic->op == '+' || ic->op == '-')
2659 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2660 sprintf (s, "(%s %c 0x%04x)",
2661 OP_SYMBOL (IC_LEFT (ric))->rname,
2663 (int) operandLitValue (IC_RIGHT (ic)));
2666 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2668 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2672 /* we reached the end */
2673 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2677 printf ("%s\n", buffer);
2682 /*-----------------------------------------------------------------*/
2683 /* regTypeNum - computes the type & number of registers required */
2684 /*-----------------------------------------------------------------*/
2692 debugLog ("%s\n", __FUNCTION__);
2693 /* for each live range do */
2694 for (sym = hTabFirstItem (liveRanges, &k); sym;
2695 sym = hTabNextItem (liveRanges, &k)) {
2697 debugLog (" %d - %s\n", __LINE__, sym->rname);
2699 /* if used zero times then no registers needed */
2700 if ((sym->liveTo - sym->liveFrom) == 0)
2704 /* if the live range is a temporary */
2707 debugLog (" %d - itemp register\n", __LINE__);
2709 /* if the type is marked as a conditional */
2710 if (sym->regType == REG_CND)
2713 /* if used in return only then we don't
2716 if (IS_AGGREGATE (sym->type) || sym->isptr)
2717 sym->type = aggrToPtr (sym->type, FALSE);
2718 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2724 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2725 // sym->type = aggrToPtr (sym->type, FALSE);
2726 debugLog (" %d - used as a return\n", __LINE__);
2731 /* if the symbol has only one definition &
2732 that definition is a get_pointer and the
2733 pointer we are getting is rematerializable and
2737 if (bitVectnBitsOn (sym->defs) == 1 &&
2738 (ic = hTabItemWithKey (iCodehTab,
2739 bitVectFirstBit (sym->defs))) &&
2741 !IS_BITVAR (sym->etype) &&
2742 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2744 if (ptrPseudoSymSafe (sym, ic)) {
2748 debugLog (" %d - \n", __LINE__);
2750 /* create a pseudo symbol & force a spil */
2751 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2752 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2753 psym->type = sym->type;
2754 psym->etype = sym->etype;
2755 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2756 strcpy (psym->rname, psym->name);
2758 sym->usl.spillLoc = psym;
2762 /* if in data space or idata space then try to
2763 allocate pointer register */
2768 /* if not then we require registers */
2769 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2770 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2771 getSize (sym->type));
2774 if(IS_PTR_CONST (sym->type)) {
2775 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2779 if (sym->nRegs > 4) {
2780 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2781 printTypeChain (sym->type, stderr);
2782 fprintf (stderr, "\n");
2785 /* determine the type of register required */
2786 if (sym->nRegs == 1 &&
2787 IS_PTR (sym->type) &&
2789 sym->regType = REG_PTR;
2791 sym->regType = REG_GPR;
2794 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2798 /* for the first run we don't provide */
2799 /* registers for true symbols we will */
2800 /* see how things go */
2805 DEFSETFUNC (markRegFree)
2807 ((regs *)item)->isFree = 1;
2812 DEFSETFUNC (deallocReg)
2814 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2815 ((regs *)item)->isFree = 1;
2816 ((regs *)item)->wasUsed = 0;
2820 /*-----------------------------------------------------------------*/
2821 /* freeAllRegs - mark all registers as free */
2822 /*-----------------------------------------------------------------*/
2824 pic14_freeAllRegs ()
2828 debugLog ("%s\n", __FUNCTION__);
2830 applyToSet(dynAllocRegs,markRegFree);
2831 applyToSet(dynStackRegs,markRegFree);
2834 for (i = 0; i < pic14_nRegs; i++)
2835 regspic14[i].isFree = 1;
2839 /*-----------------------------------------------------------------*/
2840 /*-----------------------------------------------------------------*/
2842 pic14_deallocateAllRegs ()
2846 debugLog ("%s\n", __FUNCTION__);
2848 applyToSet(dynAllocRegs,deallocReg);
2851 for (i = 0; i < pic14_nRegs; i++) {
2852 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2853 regspic14[i].isFree = 1;
2854 regspic14[i].wasUsed = 0;
2861 /*-----------------------------------------------------------------*/
2862 /* deallocStackSpil - this will set the stack pointer back */
2863 /*-----------------------------------------------------------------*/
2865 DEFSETFUNC (deallocStackSpil)
2869 debugLog ("%s\n", __FUNCTION__);
2874 /*-----------------------------------------------------------------*/
2875 /* farSpacePackable - returns the packable icode for far variables */
2876 /*-----------------------------------------------------------------*/
2878 farSpacePackable (iCode * ic)
2882 debugLog ("%s\n", __FUNCTION__);
2883 /* go thru till we find a definition for the
2884 symbol on the right */
2885 for (dic = ic->prev; dic; dic = dic->prev)
2888 /* if the definition is a call then no */
2889 if ((dic->op == CALL || dic->op == PCALL) &&
2890 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2895 /* if shift by unknown amount then not */
2896 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2897 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2900 /* if pointer get and size > 1 */
2901 if (POINTER_GET (dic) &&
2902 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2905 if (POINTER_SET (dic) &&
2906 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2909 /* if any three is a true symbol in far space */
2910 if (IC_RESULT (dic) &&
2911 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2912 isOperandInFarSpace (IC_RESULT (dic)))
2915 if (IC_RIGHT (dic) &&
2916 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2917 isOperandInFarSpace (IC_RIGHT (dic)) &&
2918 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2921 if (IC_LEFT (dic) &&
2922 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2923 isOperandInFarSpace (IC_LEFT (dic)) &&
2924 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2927 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2929 if ((dic->op == LEFT_OP ||
2930 dic->op == RIGHT_OP ||
2932 IS_OP_LITERAL (IC_RIGHT (dic)))
2942 /*-----------------------------------------------------------------*/
2943 /* packRegsForAssign - register reduction for assignment */
2944 /*-----------------------------------------------------------------*/
2946 packRegsForAssign (iCode * ic, eBBlock * ebp)
2951 debugLog ("%s\n", __FUNCTION__);
2953 debugAopGet (" result:", IC_RESULT (ic));
2954 debugAopGet (" left:", IC_LEFT (ic));
2955 debugAopGet (" right:", IC_RIGHT (ic));
2957 /* if this is at an absolute address, then get the address. */
2958 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2959 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2960 debugLog (" %d - found config word declaration\n", __LINE__);
2961 if(IS_VALOP(IC_RIGHT(ic))) {
2962 debugLog (" setting config word to %x\n",
2963 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2964 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2965 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2968 /* remove the assignment from the iCode chain. */
2970 remiCodeFromeBBlock (ebp, ic);
2971 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2972 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2979 if (!IS_ITEMP (IC_RESULT (ic))) {
2980 allocDirReg(IC_RESULT (ic));
2981 debugLog (" %d - result is not temp\n", __LINE__);
2984 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2985 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2986 allocDirReg(IC_LEFT (ic));
2990 if (!IS_ITEMP (IC_RIGHT (ic))) {
2991 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2993 /* only pack if this is not a function pointer */
2994 if (!IS_REF (IC_RIGHT (ic)))
2995 allocDirReg(IC_RIGHT (ic));
2999 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3000 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3002 debugLog (" %d - not packing - right side fails \n", __LINE__);
3006 /* if the true symbol is defined in far space or on stack
3007 then we should not since this will increase register pressure */
3008 if (isOperandInFarSpace (IC_RESULT (ic)))
3010 if ((dic = farSpacePackable (ic)))
3016 /* find the definition of iTempNN scanning backwards if we find a
3017 a use of the true symbol before we find the definition then
3019 for (dic = ic->prev; dic; dic = dic->prev)
3022 /* if there is a function call and this is
3023 a parameter & not my parameter then don't pack it */
3024 if ((dic->op == CALL || dic->op == PCALL) &&
3025 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3026 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3028 debugLog (" %d - \n", __LINE__);
3036 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3037 IS_OP_VOLATILE (IC_RESULT (dic)))
3039 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3044 if (IS_SYMOP (IC_RESULT (dic)) &&
3045 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3047 /* A previous result was assigned to the same register - we'll our definition */
3048 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3049 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3050 if (POINTER_SET (dic))
3056 if (IS_SYMOP (IC_RIGHT (dic)) &&
3057 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3058 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3060 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3065 if (IS_SYMOP (IC_LEFT (dic)) &&
3066 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3067 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3069 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3074 if (POINTER_SET (dic) &&
3075 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3077 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3085 return 0; /* did not find */
3087 /* if the result is on stack or iaccess then it must be
3088 the same at least one of the operands */
3089 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3090 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3093 /* the operation has only one symbol
3094 operator then we can pack */
3095 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3096 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3099 if (!((IC_LEFT (dic) &&
3100 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3102 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3106 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3107 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3108 /* found the definition */
3109 /* replace the result with the result of */
3110 /* this assignment and remove this assignment */
3111 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3112 IC_RESULT (dic) = IC_RESULT (ic);
3114 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3116 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3118 /* delete from liverange table also
3119 delete from all the points inbetween and the new
3121 for (sic = dic; sic != ic; sic = sic->next)
3123 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3124 if (IS_ITEMP (IC_RESULT (dic)))
3125 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3128 remiCodeFromeBBlock (ebp, ic);
3129 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3130 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3131 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3137 /*-----------------------------------------------------------------*/
3138 /* findAssignToSym : scanning backwards looks for first assig found */
3139 /*-----------------------------------------------------------------*/
3141 findAssignToSym (operand * op, iCode * ic)
3145 debugLog ("%s\n", __FUNCTION__);
3146 for (dic = ic->prev; dic; dic = dic->prev)
3149 /* if definition by assignment */
3150 if (dic->op == '=' &&
3151 !POINTER_SET (dic) &&
3152 IC_RESULT (dic)->key == op->key
3153 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3157 /* we are interested only if defined in far space */
3158 /* or in stack space in case of + & - */
3160 /* if assigned to a non-symbol then return
3162 if (!IS_SYMOP (IC_RIGHT (dic)))
3165 /* if the symbol is in far space then
3167 if (isOperandInFarSpace (IC_RIGHT (dic)))
3170 /* for + & - operations make sure that
3171 if it is on the stack it is the same
3172 as one of the three operands */
3173 if ((ic->op == '+' || ic->op == '-') &&
3174 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3177 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3178 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3179 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3187 /* if we find an usage then we cannot delete it */
3188 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3191 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3194 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3198 /* now make sure that the right side of dic
3199 is not defined between ic & dic */
3202 iCode *sic = dic->next;
3204 for (; sic != ic; sic = sic->next)
3205 if (IC_RESULT (sic) &&
3206 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3215 /*-----------------------------------------------------------------*/
3216 /* packRegsForSupport :- reduce some registers for support calls */
3217 /*-----------------------------------------------------------------*/
3219 packRegsForSupport (iCode * ic, eBBlock * ebp)
3223 debugLog ("%s\n", __FUNCTION__);
3224 /* for the left & right operand :- look to see if the
3225 left was assigned a true symbol in far space in that
3226 case replace them */
3227 if (IS_ITEMP (IC_LEFT (ic)) &&
3228 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3230 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3236 debugAopGet ("removing left:", IC_LEFT (ic));
3238 /* found it we need to remove it from the
3240 for (sic = dic; sic != ic; sic = sic->next)
3241 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3243 IC_LEFT (ic)->operand.symOperand =
3244 IC_RIGHT (dic)->operand.symOperand;
3245 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3246 remiCodeFromeBBlock (ebp, dic);
3247 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3248 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3252 /* do the same for the right operand */
3255 IS_ITEMP (IC_RIGHT (ic)) &&
3256 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3258 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3264 /* if this is a subtraction & the result
3265 is a true symbol in far space then don't pack */
3266 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3268 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3269 if (IN_FARSPACE (SPEC_OCLS (etype)))
3273 debugAopGet ("removing right:", IC_RIGHT (ic));
3275 /* found it we need to remove it from the
3277 for (sic = dic; sic != ic; sic = sic->next)
3278 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3280 IC_RIGHT (ic)->operand.symOperand =
3281 IC_RIGHT (dic)->operand.symOperand;
3282 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3284 remiCodeFromeBBlock (ebp, dic);
3285 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3286 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3293 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3296 /*-----------------------------------------------------------------*/
3297 /* packRegsForOneuse : - will reduce some registers for single Use */
3298 /*-----------------------------------------------------------------*/
3300 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3305 debugLog ("%s\n", __FUNCTION__);
3306 /* if returning a literal then do nothing */
3310 /* only upto 2 bytes since we cannot predict
3311 the usage of b, & acc */
3312 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3317 /* this routine will mark the a symbol as used in one
3318 instruction use only && if the definition is local
3319 (ie. within the basic block) && has only one definition &&
3320 that definition is either a return value from a
3321 function or does not contain any variables in
3323 uses = bitVectCopy (OP_USES (op));
3324 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3325 if (!bitVectIsZero (uses)) /* has other uses */
3328 /* if it has only one defintion */
3329 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3330 return NULL; /* has more than one definition */
3332 /* get that definition */
3334 hTabItemWithKey (iCodehTab,
3335 bitVectFirstBit (OP_DEFS (op)))))
3338 /* found the definition now check if it is local */
3339 if (dic->seq < ebp->fSeq ||
3340 dic->seq > ebp->lSeq)
3341 return NULL; /* non-local */
3343 /* now check if it is the return from
3345 if (dic->op == CALL || dic->op == PCALL)
3347 if (ic->op != SEND && ic->op != RETURN &&
3348 !POINTER_SET(ic) && !POINTER_GET(ic))
3350 OP_SYMBOL (op)->ruonly = 1;
3357 /* otherwise check that the definition does
3358 not contain any symbols in far space */
3359 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3360 isOperandInFarSpace (IC_RIGHT (dic)) ||
3361 IS_OP_RUONLY (IC_LEFT (ic)) ||
3362 IS_OP_RUONLY (IC_RIGHT (ic)))
3367 /* if pointer set then make sure the pointer
3369 if (POINTER_SET (dic) &&
3370 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3373 if (POINTER_GET (dic) &&
3374 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3379 /* also make sure the intervenening instructions
3380 don't have any thing in far space */
3381 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3384 /* if there is an intervening function call then no */
3385 if (dic->op == CALL || dic->op == PCALL)
3387 /* if pointer set then make sure the pointer
3389 if (POINTER_SET (dic) &&
3390 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3393 if (POINTER_GET (dic) &&
3394 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3397 /* if address of & the result is remat then okay */
3398 if (dic->op == ADDRESS_OF &&
3399 OP_SYMBOL (IC_RESULT (dic))->remat)
3402 /* if operand has size of three or more & this
3403 operation is a '*','/' or '%' then 'b' may
3405 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3406 getSize (operandType (op)) >= 3)
3409 /* if left or right or result is in far space */
3410 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3411 isOperandInFarSpace (IC_RIGHT (dic)) ||
3412 isOperandInFarSpace (IC_RESULT (dic)) ||
3413 IS_OP_RUONLY (IC_LEFT (dic)) ||
3414 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3415 IS_OP_RUONLY (IC_RESULT (dic)))
3421 OP_SYMBOL (op)->ruonly = 1;
3426 /*-----------------------------------------------------------------*/
3427 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3428 /*-----------------------------------------------------------------*/
3430 isBitwiseOptimizable (iCode * ic)
3432 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3433 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3435 debugLog ("%s\n", __FUNCTION__);
3436 /* bitwise operations are considered optimizable
3437 under the following conditions (Jean-Louis VERN)
3449 if (IS_LITERAL (rtype) ||
3450 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3456 /*-----------------------------------------------------------------*/
3457 /* packRegsForAccUse - pack registers for acc use */
3458 /*-----------------------------------------------------------------*/
3460 packRegsForAccUse (iCode * ic)
3464 debugLog ("%s\n", __FUNCTION__);
3466 /* result too large for WREG? */
3467 if (getSize (operandType (IC_RESULT (ic))) > 1)
3470 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3471 * is never used as an operand to an instruction that
3472 * cannot have WREG as an operand (e.g. BTFSx cannot
3473 * operate on WREG...
3474 * For now, store all results into proper registers. */
3478 /* if this is an aggregate, e.g. a one byte char array */
3479 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3482 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3484 /* if + or - then it has to be one byte result */
3485 if ((ic->op == '+' || ic->op == '-')
3486 && getSize (operandType (IC_RESULT (ic))) > 1)
3489 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3490 /* if shift operation make sure right side is not a literal */
3491 if (ic->op == RIGHT_OP &&
3492 (isOperandLiteral (IC_RIGHT (ic)) ||
3493 getSize (operandType (IC_RESULT (ic))) > 1))
3496 if (ic->op == LEFT_OP &&
3497 (isOperandLiteral (IC_RIGHT (ic)) ||
3498 getSize (operandType (IC_RESULT (ic))) > 1))
3501 if (IS_BITWISE_OP (ic) &&
3502 getSize (operandType (IC_RESULT (ic))) > 1)
3506 /* has only one definition */
3507 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3510 /* has only one use */
3511 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3514 /* and the usage immediately follows this iCode */
3515 if (!(uic = hTabItemWithKey (iCodehTab,
3516 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3519 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3520 if (ic->next != uic)
3523 /* if it is a conditional branch then we definitely can */
3527 if (uic->op == JUMPTABLE)
3530 /* if the usage is not is an assignment
3531 or an arithmetic / bitwise / shift operation then not */
3532 if (POINTER_SET (uic) &&
3533 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3536 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3537 if (uic->op != '=' &&
3538 !IS_ARITHMETIC_OP (uic) &&
3539 !IS_BITWISE_OP (uic) &&
3540 uic->op != LEFT_OP &&
3541 uic->op != RIGHT_OP)
3544 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3545 /* if used in ^ operation then make sure right is not a
3547 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3550 /* if shift operation make sure right side is not a literal */
3551 if (uic->op == RIGHT_OP &&
3552 (isOperandLiteral (IC_RIGHT (uic)) ||
3553 getSize (operandType (IC_RESULT (uic))) > 1))
3556 if (uic->op == LEFT_OP &&
3557 (isOperandLiteral (IC_RIGHT (uic)) ||
3558 getSize (operandType (IC_RESULT (uic))) > 1))
3561 /* make sure that the result of this icode is not on the
3562 stack, since acc is used to compute stack offset */
3563 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3564 OP_SYMBOL (IC_RESULT (uic))->onStack)
3567 /* if either one of them in far space then we cannot */
3568 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3569 isOperandInFarSpace (IC_LEFT (uic))) ||
3570 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3571 isOperandInFarSpace (IC_RIGHT (uic))))
3574 /* if the usage has only one operand then we can */
3575 if (IC_LEFT (uic) == NULL ||
3576 IC_RIGHT (uic) == NULL)
3579 /* make sure this is on the left side if not
3580 a '+' since '+' is commutative */
3581 if (ic->op != '+' &&
3582 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3585 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3586 /* if one of them is a literal then we can */
3587 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3588 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3589 (getSize (operandType (IC_RESULT (uic))) <= 1))
3591 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3595 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3596 /* if the other one is not on stack then we can */
3597 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3598 (IS_ITEMP (IC_RIGHT (uic)) ||
3599 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3600 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3603 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3604 (IS_ITEMP (IC_LEFT (uic)) ||
3605 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3606 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3612 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3613 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3617 /*-----------------------------------------------------------------*/
3618 /* packForPush - hueristics to reduce iCode for pushing */
3619 /*-----------------------------------------------------------------*/
3621 packForReceive (iCode * ic, eBBlock * ebp)
3625 debugLog ("%s\n", __FUNCTION__);
3626 debugAopGet (" result:", IC_RESULT (ic));
3627 debugAopGet (" left:", IC_LEFT (ic));
3628 debugAopGet (" right:", IC_RIGHT (ic));
3633 for (dic = ic->next; dic; dic = dic->next)
3638 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3639 debugLog (" used on left\n");
3640 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3641 debugLog (" used on right\n");
3642 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3643 debugLog (" used on result\n");
3645 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3646 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3651 debugLog (" hey we can remove this unnecessary assign\n");
3653 /*-----------------------------------------------------------------*/
3654 /* packForPush - hueristics to reduce iCode for pushing */
3655 /*-----------------------------------------------------------------*/
3657 packForPush (iCode * ic, eBBlock * ebp)
3661 debugLog ("%s\n", __FUNCTION__);
3662 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3665 /* must have only definition & one usage */
3666 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3667 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3670 /* find the definition */
3671 if (!(dic = hTabItemWithKey (iCodehTab,
3672 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3675 if (dic->op != '=' || POINTER_SET (dic))
3678 /* we now we know that it has one & only one def & use
3679 and the that the definition is an assignment */
3680 IC_LEFT (ic) = IC_RIGHT (dic);
3682 remiCodeFromeBBlock (ebp, dic);
3683 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3684 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3687 void printSymType(char * str, sym_link *sl)
3689 debugLog (" %s Symbol type: ",str);
3690 printTypeChain( sl, debugF);
3695 /*-----------------------------------------------------------------*/
3696 /* some debug code to print the symbol S_TYPE. Note that
3697 * the function checkSClass in src/SDCCsymt.c dinks with
3698 * the S_TYPE in ways the PIC port doesn't fully like...*/
3699 /*-----------------------------------------------------------------*/
3700 void isData(sym_link *sl)
3710 for ( ; sl; sl=sl->next) {
3712 switch (SPEC_SCLS(sl)) {
3714 case S_DATA: fprintf (of, "data "); break;
3715 case S_XDATA: fprintf (of, "xdata "); break;
3716 case S_SFR: fprintf (of, "sfr "); break;
3717 case S_SBIT: fprintf (of, "sbit "); break;
3718 case S_CODE: fprintf (of, "code "); break;
3719 case S_IDATA: fprintf (of, "idata "); break;
3720 case S_PDATA: fprintf (of, "pdata "); break;
3721 case S_LITERAL: fprintf (of, "literal "); break;
3722 case S_STACK: fprintf (of, "stack "); break;
3723 case S_XSTACK: fprintf (of, "xstack "); break;
3724 case S_BIT: fprintf (of, "bit "); break;
3725 case S_EEPROM: fprintf (of, "eeprom "); break;
3735 /*-----------------------------------------------------------------*/
3736 /* packRegisters - does some transformations to reduce register */
3738 /*-----------------------------------------------------------------*/
3740 packRegisters (eBBlock * ebp)
3745 debugLog ("%s\n", __FUNCTION__);
3751 /* look for assignments of the form */
3752 /* iTempNN = TRueSym (someoperation) SomeOperand */
3754 /* TrueSym := iTempNN:1 */
3755 for (ic = ebp->sch; ic; ic = ic->next)
3758 /* find assignment of the form TrueSym := iTempNN:1 */
3759 if (ic->op == '=' && !POINTER_SET (ic))
3760 change += packRegsForAssign (ic, ebp);
3764 if (POINTER_SET (ic))
3765 debugLog ("pointer is set\n");
3766 debugAopGet (" result:", IC_RESULT (ic));
3767 debugAopGet (" left:", IC_LEFT (ic));
3768 debugAopGet (" right:", IC_RIGHT (ic));
3777 for (ic = ebp->sch; ic; ic = ic->next) {
3779 if(IS_SYMOP ( IC_LEFT(ic))) {
3780 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3782 debugAopGet (" left:", IC_LEFT (ic));
3783 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3784 debugLog (" is a pointer\n");
3786 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3787 debugLog (" is volatile\n");
3791 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3794 if(IS_SYMOP ( IC_RIGHT(ic))) {
3795 debugAopGet (" right:", IC_RIGHT (ic));
3796 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3799 if(IS_SYMOP ( IC_RESULT(ic))) {
3800 debugAopGet (" result:", IC_RESULT (ic));
3801 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3804 if (POINTER_SET (ic))
3805 debugLog (" %d - Pointer set\n", __LINE__);
3808 /* Look for two subsequent iCodes with */
3810 /* _c = iTemp & op; */
3811 /* and replace them by */
3814 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3816 ic->prev->op == '=' &&
3817 IS_ITEMP (IC_LEFT (ic)) &&
3818 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3819 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3821 iCode* ic_prev = ic->prev;
3822 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3824 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3825 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3827 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3828 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3829 prev_result_sym->liveTo == ic->seq)
3831 prev_result_sym->liveTo = ic_prev->seq;
3834 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3836 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3838 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3840 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3841 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3842 remiCodeFromeBBlock (ebp, ic_prev);
3843 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3847 /* if this is an itemp & result of a address of a true sym
3848 then mark this as rematerialisable */
3849 if (ic->op == ADDRESS_OF &&
3850 IS_ITEMP (IC_RESULT (ic)) &&
3851 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3852 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3853 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3856 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3858 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3859 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3860 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3864 /* if straight assignment then carry remat flag if
3865 this is the only definition */
3866 if (ic->op == '=' &&
3867 !POINTER_SET (ic) &&
3868 IS_SYMOP (IC_RIGHT (ic)) &&
3869 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3870 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3872 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3874 OP_SYMBOL (IC_RESULT (ic))->remat =
3875 OP_SYMBOL (IC_RIGHT (ic))->remat;
3876 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3877 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3880 /* if this is a +/- operation with a rematerizable
3881 then mark this as rematerializable as well */
3882 if ((ic->op == '+' || ic->op == '-') &&
3883 (IS_SYMOP (IC_LEFT (ic)) &&
3884 IS_ITEMP (IC_RESULT (ic)) &&
3885 OP_SYMBOL (IC_LEFT (ic))->remat &&
3886 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3887 IS_OP_LITERAL (IC_RIGHT (ic))))
3889 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3891 operandLitValue (IC_RIGHT (ic));
3892 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3893 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3894 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3897 /* mark the pointer usages */
3898 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3900 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3901 debugLog (" marking as a pointer (set) =>");
3902 debugAopGet (" result:", IC_RESULT (ic));
3904 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3906 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3907 debugLog (" marking as a pointer (get) =>");
3908 debugAopGet (" left:", IC_LEFT (ic));
3913 /* if we are using a symbol on the stack
3914 then we should say pic14_ptrRegReq */
3915 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3916 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3917 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3918 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3919 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3920 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3923 if (IS_SYMOP (IC_LEFT (ic)))
3924 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3925 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3926 if (IS_SYMOP (IC_RIGHT (ic)))
3927 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3928 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3929 if (IS_SYMOP (IC_RESULT (ic)))
3930 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3931 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3934 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3938 /* if the condition of an if instruction
3939 is defined in the previous instruction then
3940 mark the itemp as a conditional */
3941 if ((IS_CONDITIONAL (ic) ||
3942 ((ic->op == BITWISEAND ||
3945 isBitwiseOptimizable (ic))) &&
3946 ic->next && ic->next->op == IFX &&
3947 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3948 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3951 debugLog (" %d\n", __LINE__);
3952 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3956 /* reduce for support function calls */
3957 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3958 packRegsForSupport (ic, ebp);
3960 /* if a parameter is passed, it's in W, so we may not
3961 need to place a copy in a register */
3962 if (ic->op == RECEIVE)
3963 packForReceive (ic, ebp);
3965 /* some cases the redundant moves can
3966 can be eliminated for return statements */
3967 if ((ic->op == RETURN || ic->op == SEND) &&
3968 !isOperandInFarSpace (IC_LEFT (ic)) &&
3970 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3972 /* if pointer set & left has a size more than
3973 one and right is not in far space */
3974 if (POINTER_SET (ic) &&
3975 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3976 IS_SYMOP(IC_RESULT(ic)) &&
3977 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3978 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3979 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3981 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3983 /* if pointer get */
3984 if (POINTER_GET (ic) &&
3985 !isOperandInFarSpace (IC_RESULT (ic)) &&
3986 IS_SYMOP(IC_LEFT(ic)) &&
3987 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3988 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3989 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3991 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3994 /* if this is cast for intergral promotion then
3995 check if only use of the definition of the
3996 operand being casted/ if yes then replace
3997 the result of that arithmetic operation with
3998 this result and get rid of the cast */
3999 if (ic->op == CAST) {
4001 sym_link *fromType = operandType (IC_RIGHT (ic));
4002 sym_link *toType = operandType (IC_LEFT (ic));
4004 debugLog (" %d - casting\n", __LINE__);
4006 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4007 getSize (fromType) != getSize (toType)) {
4010 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4013 if (IS_ARITHMETIC_OP (dic)) {
4015 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4016 IC_RESULT (dic) = IC_RESULT (ic);
4017 remiCodeFromeBBlock (ebp, ic);
4018 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4019 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4020 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4024 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4028 /* if the type from and type to are the same
4029 then if this is the only use then packit */
4030 if (compareType (operandType (IC_RIGHT (ic)),
4031 operandType (IC_LEFT (ic))) == 1) {
4033 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4036 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4037 IC_RESULT (dic) = IC_RESULT (ic);
4038 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4039 remiCodeFromeBBlock (ebp, ic);
4040 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4041 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4049 iTempNN := (some variable in farspace) V1
4054 if (ic->op == IPUSH)
4056 packForPush (ic, ebp);
4060 /* pack registers for accumulator use, when the
4061 result of an arithmetic or bit wise operation
4062 has only one use, that use is immediately following
4063 the defintion and the using iCode has only one
4064 operand or has two operands but one is literal &
4065 the result of that operation is not on stack then
4066 we can leave the result of this operation in acc:b
4068 if ((IS_ARITHMETIC_OP (ic)
4070 || IS_BITWISE_OP (ic)
4072 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4075 IS_ITEMP (IC_RESULT (ic)) &&
4076 getSize (operandType (IC_RESULT (ic))) <= 2)
4078 packRegsForAccUse (ic);
4084 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4088 if (!debug || !debugF)
4091 for (i = 0; i < count; i++)
4093 fprintf (debugF, "\n----------------------------------------------------------------\n");
4094 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4095 ebbs[i]->entryLabel->name,
4098 ebbs[i]->isLastInLoop);
4099 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4104 fprintf (debugF, "visited %d : hasFcall = %d\n",
4108 fprintf (debugF, "\ndefines bitVector :");
4109 bitVectDebugOn (ebbs[i]->defSet, debugF);
4110 fprintf (debugF, "\nlocal defines bitVector :");
4111 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4112 fprintf (debugF, "\npointers Set bitvector :");
4113 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4114 fprintf (debugF, "\nin pointers Set bitvector :");
4115 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4116 fprintf (debugF, "\ninDefs Set bitvector :");
4117 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4118 fprintf (debugF, "\noutDefs Set bitvector :");
4119 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4120 fprintf (debugF, "\nusesDefs Set bitvector :");
4121 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4122 fprintf (debugF, "\n----------------------------------------------------------------\n");
4123 printiCChain (ebbs[i]->sch, debugF);
4126 /*-----------------------------------------------------------------*/
4127 /* assignRegisters - assigns registers to each live range as need */
4128 /*-----------------------------------------------------------------*/
4130 pic14_assignRegisters (ebbIndex * ebbi)
4132 eBBlock ** ebbs = ebbi->bbOrder;
4133 int count = ebbi->count;
4137 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4138 debugLog ("ebbs before optimizing:\n");
4139 dumpEbbsToDebug (ebbs, count);
4141 setToNull ((void *) &_G.funcrUsed);
4142 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4145 /* change assignments this will remove some
4146 live ranges reducing some register pressure */
4147 for (i = 0; i < count; i++)
4148 packRegisters (ebbs[i]);
4155 debugLog("dir registers allocated so far:\n");
4156 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4159 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4160 reg = hTabNextItem(dynDirectRegNames, &hkey);
4165 if (options.dump_pack)
4166 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4168 /* first determine for each live range the number of
4169 registers & the type of registers required for each */
4172 /* and serially allocate registers */
4173 serialRegAssign (ebbs, count);
4175 /* if stack was extended then tell the user */
4178 /* werror(W_TOOMANY_SPILS,"stack", */
4179 /* _G.stackExtend,currFunc->name,""); */
4185 /* werror(W_TOOMANY_SPILS,"data space", */
4186 /* _G.dataExtend,currFunc->name,""); */
4190 /* after that create the register mask
4191 for each of the instruction */
4192 createRegMask (ebbs, count);
4194 /* redo that offsets for stacked automatic variables */
4195 redoStackOffsets ();
4197 if (options.dump_rassgn)
4198 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4200 /* now get back the chain */
4201 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4203 debugLog ("ebbs after optimizing:\n");
4204 dumpEbbsToDebug (ebbs, count);
4209 /* free up any _G.stackSpil locations allocated */
4210 applyToSet (_G.stackSpil, deallocStackSpil);
4212 setToNull ((void *) &_G.stackSpil);
4213 setToNull ((void *) &_G.spiltSet);
4214 /* mark all registers as free */
4215 //pic14_freeAllRegs ();
4217 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");