1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
40 /*-----------------------------------------------------------------*/
41 /* At this point we start getting processor specific although */
42 /* some routines are non-processor specific & can be reused when */
43 /* targetting other processors. The decision for this will have */
44 /* to be made on a routine by routine basis */
45 /* routines used to pack registers are most definitely not reusable */
46 /* since the pack the registers depending strictly on the MCU */
47 /*-----------------------------------------------------------------*/
49 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
50 extern void genpic16Code (iCode *);
51 extern void pic16_assignConfigWordValue(int address, int value);
61 bitVect *funcrUsed; /* registers used in a function */
67 /* Shared with gen.c */
68 int pic16_ptrRegReq; /* one byte pointer register required */
71 set *pic16_dynAllocRegs=NULL;
72 set *pic16_dynStackRegs=NULL;
73 set *pic16_dynProcessorRegs=NULL;
74 set *pic16_dynDirectRegs=NULL;
75 set *pic16_dynDirectBitRegs=NULL;
76 set *pic16_dynInternalRegs=NULL;
78 static hTab *dynDirectRegNames= NULL;
79 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
81 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
82 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
83 set *pic16_equ_data=NULL; /* registers used by equates */
84 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
86 set *pic16_builtin_functions=NULL;
88 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
89 static int rDirectIdx=0;
91 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
93 int pic16_Gstack_base_addr=0; /* The starting address of registers that
94 * are used to pass and return parameters */
99 static void spillThis (symbol *);
100 int pic16_ralloc_debug = 0;
101 static FILE *debugF = NULL;
102 /*-----------------------------------------------------------------*/
103 /* debugLog - open a file for debugging information */
104 /*-----------------------------------------------------------------*/
105 //static void debugLog(char *inst,char *fmt, ...)
107 debugLog (char *fmt,...)
109 static int append = 0; // First time through, open the file without append.
112 //char *bufferP=buffer;
115 if (!pic16_ralloc_debug || !dstFileName)
121 /* create the file name */
122 strcpy (buffer, dstFileName);
123 strcat (buffer, ".d");
125 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
127 werror (E_FILE_OPEN_ERR, buffer);
130 append = 1; // Next time debubLog is called, we'll append the debug info
136 vsprintf (buffer, fmt, ap);
138 fprintf (debugF, "%s", buffer);
140 while (isspace(*bufferP)) bufferP++;
142 if (bufferP && *bufferP)
143 lineCurr = (lineCurr ?
144 connectLine(lineCurr,newLineNode(lb)) :
145 (lineHead = newLineNode(lb)));
146 lineCurr->isInline = _G.inLine;
147 lineCurr->isDebug = _G.debugLine;
156 if(!pic16_ralloc_debug)return;
159 fputc ('\n', debugF);
161 /*-----------------------------------------------------------------*/
162 /* debugLogClose - closes the debug log file (if opened) */
163 /*-----------------------------------------------------------------*/
173 #define AOP(op) op->aop
176 debugAopGet (char *str, operand * op)
178 if(!pic16_ralloc_debug)return NULL;
183 printOperand (op, debugF);
190 decodeOp (unsigned int op)
192 if (op < 128 && op > ' ') {
193 buffer[0] = (op & 0xff);
199 case IDENTIFIER: return "IDENTIFIER";
200 case TYPE_NAME: return "TYPE_NAME";
201 case CONSTANT: return "CONSTANT";
202 case STRING_LITERAL: return "STRING_LITERAL";
203 case SIZEOF: return "SIZEOF";
204 case PTR_OP: return "PTR_OP";
205 case INC_OP: return "INC_OP";
206 case DEC_OP: return "DEC_OP";
207 case LEFT_OP: return "LEFT_OP";
208 case RIGHT_OP: return "RIGHT_OP";
209 case LE_OP: return "LE_OP";
210 case GE_OP: return "GE_OP";
211 case EQ_OP: return "EQ_OP";
212 case NE_OP: return "NE_OP";
213 case AND_OP: return "AND_OP";
214 case OR_OP: return "OR_OP";
215 case MUL_ASSIGN: return "MUL_ASSIGN";
216 case DIV_ASSIGN: return "DIV_ASSIGN";
217 case MOD_ASSIGN: return "MOD_ASSIGN";
218 case ADD_ASSIGN: return "ADD_ASSIGN";
219 case SUB_ASSIGN: return "SUB_ASSIGN";
220 case LEFT_ASSIGN: return "LEFT_ASSIGN";
221 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
222 case AND_ASSIGN: return "AND_ASSIGN";
223 case XOR_ASSIGN: return "XOR_ASSIGN";
224 case OR_ASSIGN: return "OR_ASSIGN";
225 case TYPEDEF: return "TYPEDEF";
226 case EXTERN: return "EXTERN";
227 case STATIC: return "STATIC";
228 case AUTO: return "AUTO";
229 case REGISTER: return "REGISTER";
230 case CODE: return "CODE";
231 case EEPROM: return "EEPROM";
232 case INTERRUPT: return "INTERRUPT";
233 case SFR: return "SFR";
234 case AT: return "AT";
235 case SBIT: return "SBIT";
236 case REENTRANT: return "REENTRANT";
237 case USING: return "USING";
238 case XDATA: return "XDATA";
239 case DATA: return "DATA";
240 case IDATA: return "IDATA";
241 case PDATA: return "PDATA";
242 case VAR_ARGS: return "VAR_ARGS";
243 case CRITICAL: return "CRITICAL";
244 case NONBANKED: return "NONBANKED";
245 case BANKED: return "BANKED";
246 case CHAR: return "CHAR";
247 case SHORT: return "SHORT";
248 case INT: return "INT";
249 case LONG: return "LONG";
250 case SIGNED: return "SIGNED";
251 case UNSIGNED: return "UNSIGNED";
252 case FLOAT: return "FLOAT";
253 case DOUBLE: return "DOUBLE";
254 case CONST: return "CONST";
255 case VOLATILE: return "VOLATILE";
256 case VOID: return "VOID";
257 case BIT: return "BIT";
258 case STRUCT: return "STRUCT";
259 case UNION: return "UNION";
260 case ENUM: return "ENUM";
261 case ELIPSIS: return "ELIPSIS";
262 case RANGE: return "RANGE";
263 case FAR: return "FAR";
264 case CASE: return "CASE";
265 case DEFAULT: return "DEFAULT";
266 case IF: return "IF";
267 case ELSE: return "ELSE";
268 case SWITCH: return "SWITCH";
269 case WHILE: return "WHILE";
270 case DO: return "DO";
271 case FOR: return "FOR";
272 case GOTO: return "GOTO";
273 case CONTINUE: return "CONTINUE";
274 case BREAK: return "BREAK";
275 case RETURN: return "RETURN";
276 case INLINEASM: return "INLINEASM";
277 case IFX: return "IFX";
278 case ADDRESS_OF: return "ADDRESS_OF";
279 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
280 case SPIL: return "SPIL";
281 case UNSPIL: return "UNSPIL";
282 case GETHBIT: return "GETHBIT";
283 case BITWISEAND: return "BITWISEAND";
284 case UNARYMINUS: return "UNARYMINUS";
285 case IPUSH: return "IPUSH";
286 case IPOP: return "IPOP";
287 case PCALL: return "PCALL";
288 case ENDFUNCTION: return "ENDFUNCTION";
289 case JUMPTABLE: return "JUMPTABLE";
290 case RRC: return "RRC";
291 case RLC: return "RLC";
292 case CAST: return "CAST";
293 case CALL: return "CALL";
294 case PARAM: return "PARAM ";
295 case NULLOP: return "NULLOP";
296 case BLOCK: return "BLOCK";
297 case LABEL: return "LABEL";
298 case RECEIVE: return "RECEIVE";
299 case SEND: return "SEND";
301 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
305 /*-----------------------------------------------------------------*/
306 /*-----------------------------------------------------------------*/
308 debugLogRegType (short type)
310 if(!pic16_ralloc_debug)return NULL;
312 case REG_GPR: return "REG_GPR";
313 case REG_PTR: return "REG_PTR";
314 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
321 /*-----------------------------------------------------------------*/
322 /*-----------------------------------------------------------------*/
323 static int regname2key(char const *name)
332 key += (*name++) + 1;
336 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
348 dReg = Safe_calloc(1,sizeof(regs));
350 dReg->pc_type = pc_type;
353 dReg->name = Safe_strdup(name);
355 sprintf(buffer,"r0x%02X", dReg->rIdx);
358 dReg->name = Safe_strdup(buffer);
365 // dReg->isMapped = 0;
368 if(type == REG_SFR) {
370 dReg->address = rIdx;
371 dReg->accessBank = 1;
375 dReg->accessBank = 0;
378 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
382 dReg->reg_alias = NULL;
383 dReg->reglives.usedpFlows = newSet();
384 dReg->reglives.assignedpFlows = newSet();
387 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
392 /*-----------------------------------------------------------------*/
393 /* regWithIdx - Search through a set of registers that matches idx */
394 /*-----------------------------------------------------------------*/
396 regWithIdx (set *dRegs, int idx, int fixed)
400 for (dReg = setFirstItem(dRegs) ; dReg ;
401 dReg = setNextItem(dRegs)) {
403 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
411 /*-----------------------------------------------------------------*/
412 /* regFindFree - Search for a free register in a set of registers */
413 /*-----------------------------------------------------------------*/
415 regFindFree (set *dRegs)
419 for (dReg = setFirstItem(dRegs) ; dReg ;
420 dReg = setNextItem(dRegs)) {
422 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
423 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
432 /*-----------------------------------------------------------------*/
433 /* pic16_initStack - allocate registers for a pseudo stack */
434 /*-----------------------------------------------------------------*/
435 void pic16_initStack(int base_address, int size)
440 pic16_Gstack_base_addr = base_address;
441 //fprintf(stderr,"initStack");
443 for(i = 0; i<size; i++)
444 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
447 /*-----------------------------------------------------------------*
448 *-----------------------------------------------------------------*/
450 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
452 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
454 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
456 reg->wasUsed = 0; // we do not know if they are going to be used at all
457 reg->accessBank = 1; // implicit add access Bank
459 return addSet(&pic16_dynProcessorRegs, reg);
462 /*-----------------------------------------------------------------*
463 *-----------------------------------------------------------------*/
466 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
468 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
470 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
474 return addSet(&pic16_dynInternalRegs,reg);
479 /*-----------------------------------------------------------------*/
480 /* allocReg - allocates register of given type */
481 /*-----------------------------------------------------------------*/
483 allocReg (short type)
488 if(dynrIdx > pic16_nRegs)
492 /* try to reuse some unused registers */
493 reg = regFindFree( pic16_dynAllocRegs );
496 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
497 addSet(&pic16_dynAllocRegs, reg);
501 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
503 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
504 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
507 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
508 reg->isLocal = 1; /* this is a local frame register */
512 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
514 return (reg); // addSet(&pic16_dynAllocRegs,reg);
519 /*-----------------------------------------------------------------*/
520 /* pic16_dirregWithName - search for register by name */
521 /*-----------------------------------------------------------------*/
523 pic16_dirregWithName (char *name)
531 /* hash the name to get a key */
533 hkey = regname2key(name);
535 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
537 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
541 if(STRCASECMP(reg->name, name) == 0) {
545 reg = hTabNextItemWK (dynDirectRegNames);
549 return NULL; // name wasn't found in the hash table
552 static int IS_CONFIG_ADDRESS(int address)
555 return address >= 0x300000 && address <= 0x300000d;
558 /*-----------------------------------------------------------------*/
559 /* pic16_allocDirReg - allocates register of given type */
560 /*-----------------------------------------------------------------*/
562 pic16_allocDirReg (operand *op )
568 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
572 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
574 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { // patch 13
575 if(pic16_debug_verbose) //
577 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, //
578 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname); //
583 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
584 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
587 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
588 debugLog(" %d const char\n",__LINE__);
589 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
590 // fprintf(stderr, " %d const char\n",__LINE__);
591 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
595 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
596 if (IS_CODE ( OP_SYM_ETYPE(op)) )
597 debugLog(" %d code space\n",__LINE__);
599 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
600 debugLog(" %d integral\n",__LINE__);
602 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
603 debugLog(" %d literal\n",__LINE__);
605 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
606 debugLog(" %d specifier\n",__LINE__);
608 debugAopGet(NULL, op);
611 if (IS_CODE ( OP_SYM_ETYPE(op)) )
614 /* First, search the hash table to see if there is a register with this name */
615 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
617 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
621 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
622 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
624 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
625 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
628 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
630 reg = pic16_dirregWithName(name);
635 int regtype = REG_GPR;
637 /* if this is at an absolute address, then get the address. */
638 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
639 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
640 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
643 /* Register wasn't found in hash, so let's create
644 * a new one and put it in the hash table AND in the
645 * dynDirectRegNames set */
646 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
647 if(pic16_debug_verbose)
648 fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
649 OP_SYMBOL(op)->name);
650 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
654 if(!IS_CONFIG_ADDRESS(address)) {
655 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
657 if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
659 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) { // patch 13
660 if(pic16_debug_verbose) //
662 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__, //
663 OP_SYMBOL(op)->name); //
668 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
669 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
671 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
673 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
674 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
675 // reg->type = REG_SFR;
678 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
679 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
680 addSet(&pic16_dynDirectBitRegs, reg);
683 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
684 checkAddReg(&pic16_dynDirectRegs, reg);
688 debugLog (" -- %s is declared at address 0x30000x\n",name);
689 fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
695 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
697 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
699 /* work around for user defined registers in access bank */
700 if((reg->address < 0x80)
701 || (reg->address >= 0xf80))
704 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
710 /*-----------------------------------------------------------------*/
711 /* pic16_allocRegByName - allocates register of given type */
712 /*-----------------------------------------------------------------*/
714 pic16_allocRegByName (char *name, int size)
720 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
724 /* First, search the hash table to see if there is a register with this name */
725 reg = pic16_dirregWithName(name);
729 /* Register wasn't found in hash, so let's create
730 * a new one and put it in the hash table AND in the
731 * dynDirectRegNames set */
732 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
733 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
735 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
736 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
738 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
739 addSet(&pic16_dynDirectRegs, reg);
745 /*-----------------------------------------------------------------*/
746 /* RegWithIdx - returns pointer to register with index number */
747 /*-----------------------------------------------------------------*/
748 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
753 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
758 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
760 debugLog ("Found a Dynamic Register!\n");
763 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
764 debugLog ("Found a Direct Register!\n");
770 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
771 debugLog ("Found a Stack Register!\n");
776 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
777 debugLog ("Found a Processor Register!\n");
791 /*-----------------------------------------------------------------*/
792 /* pic16_regWithIdx - returns pointer to register with index number*/
793 /*-----------------------------------------------------------------*/
795 pic16_regWithIdx (int idx)
799 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
802 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
805 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
811 /*-----------------------------------------------------------------*/
812 /* pic16_regWithIdx - returns pointer to register with index number */
813 /*-----------------------------------------------------------------*/
815 pic16_allocWithIdx (int idx)
820 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
822 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
824 debugLog ("Found a Dynamic Register!\n");
825 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
826 debugLog ("Found a Stack Register!\n");
827 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
828 debugLog ("Found a Processor Register!\n");
829 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
830 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
831 debugLog ("Found an Internal Register!\n");
834 debugLog ("Dynamic Register not found\n");
837 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
838 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
839 "regWithIdx not found");
849 /*-----------------------------------------------------------------*/
850 /*-----------------------------------------------------------------*/
852 pic16_findFreeReg(short type)
859 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
861 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
865 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
877 /*-----------------------------------------------------------------*/
878 /* freeReg - frees a register */
879 /*-----------------------------------------------------------------*/
883 debugLog ("%s\n", __FUNCTION__);
884 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
889 /*-----------------------------------------------------------------*/
890 /* nFreeRegs - returns number of free registers */
891 /*-----------------------------------------------------------------*/
899 /* although I fixed the register allocation/freeing scheme
900 * the for loop below doesn't give valid results. I do not
901 * know why yet. -- VR 10-Jan-2003 */
906 /* dynamically allocate as many as we need and worry about
907 * fitting them into a PIC later */
909 debugLog ("%s\n", __FUNCTION__);
911 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
912 if((reg->type == type) && reg->isFree)nfr++;
914 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
918 /*-----------------------------------------------------------------*/
919 /* nfreeRegsType - free registers with type */
920 /*-----------------------------------------------------------------*/
922 nfreeRegsType (int type)
925 debugLog ("%s\n", __FUNCTION__);
928 if ((nfr = nFreeRegs (type)) == 0)
929 return nFreeRegs (REG_GPR);
932 return nFreeRegs (type);
935 static void writeSetUsedRegs(FILE *of, set *dRegs)
940 for (dReg = setFirstItem(dRegs) ; dReg ;
941 dReg = setNextItem(dRegs)) {
944 fprintf (of, "\t%s\n",dReg->name);
950 extern void pic16_groupRegistersInSection(set *regset);
952 extern void pic16_dump_equates(FILE *of, set *equs);
953 //extern void pic16_dump_map(void);
954 extern void pic16_dump_section(FILE *of, set *section, int fix);
955 extern void pic16_dump_int_registers(FILE *of, set *section);
956 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
958 static void packBits(set *bregs)
963 regs *relocbitfield=NULL;
969 for (regset = bregs ; regset ;
970 regset = regset->next) {
973 breg->isBitField = 1;
974 //fprintf(stderr,"bit reg: %s\n",breg->name);
977 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
979 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
980 breg->rIdx = breg->address & 7;
984 sprintf (buffer, "fbitfield%02x", breg->address);
985 //fprintf(stderr,"new bit field\n");
986 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
987 bitfield->isBitField = 1;
988 bitfield->isFixed = 1;
989 bitfield->address = breg->address;
990 addSet(&pic16_dynDirectRegs,bitfield);
991 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
993 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
996 breg->reg_alias = bitfield;
1000 if(!relocbitfield || bit_no >7) {
1003 sprintf (buffer, "bitfield%d", byte_no);
1004 //fprintf(stderr,"new relocatable bit field\n");
1005 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1006 relocbitfield->isBitField = 1;
1007 addSet(&pic16_dynDirectRegs,relocbitfield);
1008 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1012 breg->reg_alias = relocbitfield;
1013 breg->address = rDirectIdx; /* byte_no; */
1014 breg->rIdx = bit_no++;
1023 static void bitEQUs(FILE *of, set *bregs)
1025 regs *breg,*bytereg;
1028 //fprintf(stderr," %s\n",__FUNCTION__);
1029 for (breg = setFirstItem(bregs) ; breg ;
1030 breg = setNextItem(bregs)) {
1032 //fprintf(stderr,"bit reg: %s\n",breg->name);
1034 bytereg = breg->reg_alias;
1036 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1039 breg->rIdx & 0x0007);
1042 fprintf(stderr, "bit field is not assigned to a register\n");
1043 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1054 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1059 for (reg = setFirstItem(fregs) ; reg ;
1060 reg = setNextItem(fregs)) {
1062 if(!reg->isEmitted && reg->wasUsed) {
1064 if (reg->type != REG_SFR) {
1065 fprintf (of, "%s\tEQU\t0x%03x\n",
1071 fprintf (of, "%s\tEQU\t0x%03x\n",
1080 void pic16_writeUsedRegs(FILE *of)
1082 packBits(pic16_dynDirectBitRegs);
1084 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1085 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1086 pic16_groupRegistersInSection(pic16_dynStackRegs);
1087 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1088 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1089 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1093 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1094 pic16_assignFixedRegisters(pic16_dynStackRegs);
1095 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1096 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1098 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1099 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1100 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1101 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1102 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1105 // pic16_dump_map();
1106 // pic16_dump_cblock(of);
1109 pic16_dump_equates(of, pic16_equ_data);
1111 /* dump initialised data */
1112 pic16_dump_idata(of, idataSymSet);
1114 /* dump internal registers */
1115 pic16_dump_int_registers(of, pic16_int_regs);
1117 /* dump other variables */
1118 pic16_dump_section(of, pic16_rel_udata, 0);
1119 pic16_dump_section(of, pic16_fix_udata, 1);
1124 /*-----------------------------------------------------------------*/
1125 /* allDefsOutOfRange - all definitions are out of a range */
1126 /*-----------------------------------------------------------------*/
1128 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1132 debugLog ("%s\n", __FUNCTION__);
1136 for (i = 0; i < defs->size; i++)
1140 if (bitVectBitValue (defs, i) &&
1141 (ic = hTabItemWithKey (iCodehTab, i)) &&
1142 (ic->seq >= fseq && ic->seq <= toseq))
1152 /*-----------------------------------------------------------------*/
1153 /* computeSpillable - given a point find the spillable live ranges */
1154 /*-----------------------------------------------------------------*/
1156 computeSpillable (iCode * ic)
1160 debugLog ("%s\n", __FUNCTION__);
1161 /* spillable live ranges are those that are live at this
1162 point . the following categories need to be subtracted
1164 a) - those that are already spilt
1165 b) - if being used by this one
1166 c) - defined by this one */
1168 spillable = bitVectCopy (ic->rlive);
1170 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1172 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1173 bitVectUnSetBit (spillable, ic->defKey);
1174 spillable = bitVectIntersect (spillable, _G.regAssigned);
1179 /*-----------------------------------------------------------------*/
1180 /* noSpilLoc - return true if a variable has no spil location */
1181 /*-----------------------------------------------------------------*/
1183 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1185 debugLog ("%s\n", __FUNCTION__);
1186 return (sym->usl.spillLoc ? 0 : 1);
1189 /*-----------------------------------------------------------------*/
1190 /* hasSpilLoc - will return 1 if the symbol has spil location */
1191 /*-----------------------------------------------------------------*/
1193 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1195 debugLog ("%s\n", __FUNCTION__);
1196 return (sym->usl.spillLoc ? 1 : 0);
1199 /*-----------------------------------------------------------------*/
1200 /* directSpilLoc - will return 1 if the splilocation is in direct */
1201 /*-----------------------------------------------------------------*/
1203 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1205 debugLog ("%s\n", __FUNCTION__);
1206 if (sym->usl.spillLoc &&
1207 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1213 /*-----------------------------------------------------------------*/
1214 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1215 /* but is not used as a pointer */
1216 /*-----------------------------------------------------------------*/
1218 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1220 debugLog ("%s\n", __FUNCTION__);
1221 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1224 /*-----------------------------------------------------------------*/
1225 /* rematable - will return 1 if the remat flag is set */
1226 /*-----------------------------------------------------------------*/
1228 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1230 debugLog ("%s\n", __FUNCTION__);
1234 /*-----------------------------------------------------------------*/
1235 /* notUsedInRemaining - not used or defined in remain of the block */
1236 /*-----------------------------------------------------------------*/
1238 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1240 debugLog ("%s\n", __FUNCTION__);
1241 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1242 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1245 /*-----------------------------------------------------------------*/
1246 /* allLRs - return true for all */
1247 /*-----------------------------------------------------------------*/
1249 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1251 debugLog ("%s\n", __FUNCTION__);
1255 /*-----------------------------------------------------------------*/
1256 /* liveRangesWith - applies function to a given set of live range */
1257 /*-----------------------------------------------------------------*/
1259 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1260 eBBlock * ebp, iCode * ic)
1265 debugLog ("%s\n", __FUNCTION__);
1266 if (!lrs || !lrs->size)
1269 for (i = 1; i < lrs->size; i++)
1272 if (!bitVectBitValue (lrs, i))
1275 /* if we don't find it in the live range
1276 hash table we are in serious trouble */
1277 if (!(sym = hTabItemWithKey (liveRanges, i)))
1279 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1280 "liveRangesWith could not find liveRange");
1284 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1285 addSetHead (&rset, sym);
1292 /*-----------------------------------------------------------------*/
1293 /* leastUsedLR - given a set determines which is the least used */
1294 /*-----------------------------------------------------------------*/
1296 leastUsedLR (set * sset)
1298 symbol *sym = NULL, *lsym = NULL;
1300 debugLog ("%s\n", __FUNCTION__);
1301 sym = lsym = setFirstItem (sset);
1306 for (; lsym; lsym = setNextItem (sset))
1309 /* if usage is the same then prefer
1310 the spill the smaller of the two */
1311 if (lsym->used == sym->used)
1312 if (getSize (lsym->type) < getSize (sym->type))
1316 if (lsym->used < sym->used)
1321 setToNull ((void *) &sset);
1326 /*-----------------------------------------------------------------*/
1327 /* noOverLap - will iterate through the list looking for over lap */
1328 /*-----------------------------------------------------------------*/
1330 noOverLap (set * itmpStack, symbol * fsym)
1333 debugLog ("%s\n", __FUNCTION__);
1336 for (sym = setFirstItem (itmpStack); sym;
1337 sym = setNextItem (itmpStack))
1339 if (sym->liveTo > fsym->liveFrom)
1347 /*-----------------------------------------------------------------*/
1348 /* isFree - will return 1 if the a free spil location is found */
1349 /*-----------------------------------------------------------------*/
1354 V_ARG (symbol **, sloc);
1355 V_ARG (symbol *, fsym);
1357 debugLog ("%s\n", __FUNCTION__);
1358 /* if already found */
1362 /* if it is free && and the itmp assigned to
1363 this does not have any overlapping live ranges
1364 with the one currently being assigned and
1365 the size can be accomodated */
1367 noOverLap (sym->usl.itmpStack, fsym) &&
1368 getSize (sym->type) >= getSize (fsym->type))
1377 /*-----------------------------------------------------------------*/
1378 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1379 /*-----------------------------------------------------------------*/
1381 spillLRWithPtrReg (symbol * forSym)
1387 debugLog ("%s\n", __FUNCTION__);
1388 if (!_G.regAssigned ||
1389 bitVectIsZero (_G.regAssigned))
1392 r0 = pic16_regWithIdx (R0_IDX);
1393 r1 = pic16_regWithIdx (R1_IDX);
1395 /* for all live ranges */
1396 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1397 lrsym = hTabNextItem (liveRanges, &k))
1401 /* if no registers assigned to it or
1403 /* if it does not overlap with this then
1404 not need to spill it */
1406 if (lrsym->isspilt || !lrsym->nRegs ||
1407 (lrsym->liveTo < forSym->liveFrom))
1410 /* go thru the registers : if it is either
1411 r0 or r1 then spil it */
1412 for (j = 0; j < lrsym->nRegs; j++)
1413 if (lrsym->regs[j] == r0 ||
1414 lrsym->regs[j] == r1)
1423 /*-----------------------------------------------------------------*/
1424 /* createStackSpil - create a location on the stack to spil */
1425 /*-----------------------------------------------------------------*/
1427 createStackSpil (symbol * sym)
1429 symbol *sloc = NULL;
1430 int useXstack, model, noOverlay;
1432 char slocBuffer[30];
1433 debugLog ("%s\n", __FUNCTION__);
1435 /* first go try and find a free one that is already
1436 existing on the stack */
1437 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1439 /* found a free one : just update & return */
1440 sym->usl.spillLoc = sloc;
1443 addSetHead (&sloc->usl.itmpStack, sym);
1447 /* could not then have to create one , this is the hard part
1448 we need to allocate this on the stack : this is really a
1449 hack!! but cannot think of anything better at this time */
1451 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1453 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1454 __FILE__, __LINE__);
1458 sloc = newiTemp (slocBuffer);
1460 /* set the type to the spilling symbol */
1461 sloc->type = copyLinkChain (sym->type);
1462 sloc->etype = getSpec (sloc->type);
1463 SPEC_SCLS (sloc->etype) = S_DATA;
1464 SPEC_EXTR (sloc->etype) = 0;
1465 SPEC_STAT (sloc->etype) = 0;
1467 /* we don't allow it to be allocated`
1468 onto the external stack since : so we
1469 temporarily turn it off ; we also
1470 turn off memory model to prevent
1471 the spil from going to the external storage
1472 and turn off overlaying
1475 useXstack = options.useXstack;
1476 model = options.model;
1477 noOverlay = options.noOverlay;
1478 options.noOverlay = 1;
1479 options.model = options.useXstack = 0;
1483 options.useXstack = useXstack;
1484 options.model = model;
1485 options.noOverlay = noOverlay;
1486 sloc->isref = 1; /* to prevent compiler warning */
1488 /* if it is on the stack then update the stack */
1489 if (IN_STACK (sloc->etype))
1491 currFunc->stack += getSize (sloc->type);
1492 _G.stackExtend += getSize (sloc->type);
1495 _G.dataExtend += getSize (sloc->type);
1497 /* add it to the _G.stackSpil set */
1498 addSetHead (&_G.stackSpil, sloc);
1499 sym->usl.spillLoc = sloc;
1502 /* add it to the set of itempStack set
1503 of the spill location */
1504 addSetHead (&sloc->usl.itmpStack, sym);
1508 /*-----------------------------------------------------------------*/
1509 /* isSpiltOnStack - returns true if the spil location is on stack */
1510 /*-----------------------------------------------------------------*/
1512 isSpiltOnStack (symbol * sym)
1516 debugLog ("%s\n", __FUNCTION__);
1523 /* if (sym->_G.stackSpil) */
1526 if (!sym->usl.spillLoc)
1529 etype = getSpec (sym->usl.spillLoc->type);
1530 if (IN_STACK (etype))
1536 /*-----------------------------------------------------------------*/
1537 /* spillThis - spils a specific operand */
1538 /*-----------------------------------------------------------------*/
1540 spillThis (symbol * sym)
1543 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1545 /* if this is rematerializable or has a spillLocation
1546 we are okay, else we need to create a spillLocation
1548 if (!(sym->remat || sym->usl.spillLoc))
1549 createStackSpil (sym);
1552 /* mark it has spilt & put it in the spilt set */
1554 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1556 bitVectUnSetBit (_G.regAssigned, sym->key);
1558 for (i = 0; i < sym->nRegs; i++)
1562 freeReg (sym->regs[i]);
1563 sym->regs[i] = NULL;
1566 /* if spilt on stack then free up r0 & r1
1567 if they could have been assigned to some
1569 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1572 spillLRWithPtrReg (sym);
1575 if (sym->usl.spillLoc && !sym->remat)
1576 sym->usl.spillLoc->allocreq = 1;
1580 /*-----------------------------------------------------------------*/
1581 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1582 /*-----------------------------------------------------------------*/
1584 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1586 bitVect *lrcs = NULL;
1590 debugLog ("%s\n", __FUNCTION__);
1591 /* get the spillable live ranges */
1592 lrcs = computeSpillable (ic);
1594 /* get all live ranges that are rematerizable */
1595 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1598 /* return the least used of these */
1599 return leastUsedLR (selectS);
1602 /* get live ranges with spillLocations in direct space */
1603 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1605 sym = leastUsedLR (selectS);
1606 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1607 sym->usl.spillLoc->rname :
1608 sym->usl.spillLoc->name));
1610 /* mark it as allocation required */
1611 sym->usl.spillLoc->allocreq = 1;
1615 /* if the symbol is local to the block then */
1616 if (forSym->liveTo < ebp->lSeq)
1619 /* check if there are any live ranges allocated
1620 to registers that are not used in this block */
1621 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1623 sym = leastUsedLR (selectS);
1624 /* if this is not rematerializable */
1633 /* check if there are any live ranges that not
1634 used in the remainder of the block */
1635 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1637 sym = leastUsedLR (selectS);
1640 sym->remainSpil = 1;
1647 /* find live ranges with spillocation && not used as pointers */
1648 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1651 sym = leastUsedLR (selectS);
1652 /* mark this as allocation required */
1653 sym->usl.spillLoc->allocreq = 1;
1657 /* find live ranges with spillocation */
1658 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1661 sym = leastUsedLR (selectS);
1662 sym->usl.spillLoc->allocreq = 1;
1666 /* couldn't find then we need to create a spil
1667 location on the stack , for which one? the least
1669 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1672 /* return a created spil location */
1673 sym = createStackSpil (leastUsedLR (selectS));
1674 sym->usl.spillLoc->allocreq = 1;
1678 /* this is an extreme situation we will spill
1679 this one : happens very rarely but it does happen */
1685 /*-----------------------------------------------------------------*/
1686 /* spilSomething - spil some variable & mark registers as free */
1687 /*-----------------------------------------------------------------*/
1689 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1694 debugLog ("%s\n", __FUNCTION__);
1695 /* get something we can spil */
1696 ssym = selectSpil (ic, ebp, forSym);
1698 /* mark it as spilt */
1700 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1702 /* mark it as not register assigned &
1703 take it away from the set */
1704 bitVectUnSetBit (_G.regAssigned, ssym->key);
1706 /* mark the registers as free */
1707 for (i = 0; i < ssym->nRegs; i++)
1709 freeReg (ssym->regs[i]);
1711 /* if spilt on stack then free up r0 & r1
1712 if they could have been assigned to as gprs */
1713 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1716 spillLRWithPtrReg (ssym);
1719 /* if this was a block level spil then insert push & pop
1720 at the start & end of block respectively */
1721 if (ssym->blockSpil)
1723 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1724 /* add push to the start of the block */
1725 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1726 ebp->sch->next : ebp->sch));
1727 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1728 /* add pop to the end of the block */
1729 addiCodeToeBBlock (ebp, nic, NULL);
1732 /* if spilt because not used in the remainder of the
1733 block then add a push before this instruction and
1734 a pop at the end of the block */
1735 if (ssym->remainSpil)
1738 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1739 /* add push just before this instruction */
1740 addiCodeToeBBlock (ebp, nic, ic);
1742 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1743 /* add pop to the end of the block */
1744 addiCodeToeBBlock (ebp, nic, NULL);
1753 /*-----------------------------------------------------------------*/
1754 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1755 /*-----------------------------------------------------------------*/
1757 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1762 debugLog ("%s\n", __FUNCTION__);
1764 /* try for a ptr type */
1765 if ((reg = allocReg (REG_PTR)))
1768 /* try for gpr type */
1769 if ((reg = allocReg (REG_GPR)))
1772 /* we have to spil */
1773 if (!spilSomething (ic, ebp, sym))
1776 /* make sure partially assigned registers aren't reused */
1777 for (j=0; j<=sym->nRegs; j++)
1779 sym->regs[j]->isFree = 0;
1781 /* this looks like an infinite loop but
1782 in really selectSpil will abort */
1786 /*-----------------------------------------------------------------*/
1787 /* getRegGpr - will try for GPR if not spil */
1788 /*-----------------------------------------------------------------*/
1790 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1795 debugLog ("%s\n", __FUNCTION__);
1797 /* try for gpr type */
1798 if ((reg = allocReg (REG_GPR)))
1801 if (!pic16_ptrRegReq)
1802 if ((reg = allocReg (REG_PTR)))
1805 /* we have to spil */
1806 if (!spilSomething (ic, ebp, sym))
1809 /* make sure partially assigned registers aren't reused */
1810 for (j=0; j<=sym->nRegs; j++)
1812 sym->regs[j]->isFree = 0;
1814 /* this looks like an infinite loop but
1815 in really selectSpil will abort */
1819 /*-----------------------------------------------------------------*/
1820 /* symHasReg - symbol has a given register */
1821 /*-----------------------------------------------------------------*/
1823 symHasReg (symbol * sym, regs * reg)
1827 debugLog ("%s\n", __FUNCTION__);
1828 for (i = 0; i < sym->nRegs; i++)
1829 if (sym->regs[i] == reg)
1835 /*-----------------------------------------------------------------*/
1836 /* deassignLRs - check the live to and if they have registers & are */
1837 /* not spilt then free up the registers */
1838 /*-----------------------------------------------------------------*/
1840 deassignLRs (iCode * ic, eBBlock * ebp)
1846 debugLog ("%s\n", __FUNCTION__);
1847 for (sym = hTabFirstItem (liveRanges, &k); sym;
1848 sym = hTabNextItem (liveRanges, &k))
1851 symbol *psym = NULL;
1852 /* if it does not end here */
1853 if (sym->liveTo > ic->seq)
1856 /* if it was spilt on stack then we can
1857 mark the stack spil location as free */
1862 sym->usl.spillLoc->isFree = 1;
1868 if (!bitVectBitValue (_G.regAssigned, sym->key))
1871 /* special case check if this is an IFX &
1872 the privious one was a pop and the
1873 previous one was not spilt then keep track
1875 if (ic->op == IFX && ic->prev &&
1876 ic->prev->op == IPOP &&
1877 !ic->prev->parmPush &&
1878 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1879 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1885 bitVectUnSetBit (_G.regAssigned, sym->key);
1887 /* if the result of this one needs registers
1888 and does not have it then assign it right
1890 if (IC_RESULT (ic) &&
1891 !(SKIP_IC2 (ic) || /* not a special icode */
1892 ic->op == JUMPTABLE ||
1897 POINTER_SET (ic)) &&
1898 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1899 result->liveTo > ic->seq && /* and will live beyond this */
1900 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1901 result->regType == sym->regType && /* same register types */
1902 result->nRegs && /* which needs registers */
1903 !result->isspilt && /* and does not already have them */
1905 !bitVectBitValue (_G.regAssigned, result->key) &&
1906 /* the number of free regs + number of regs in this LR
1907 can accomodate the what result Needs */
1908 ((nfreeRegsType (result->regType) +
1909 sym->nRegs) >= result->nRegs)
1913 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1915 result->regs[i] = sym->regs[i];
1917 result->regs[i] = getRegGpr (ic, ebp, result);
1919 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1923 /* free the remaining */
1924 for (; i < sym->nRegs; i++)
1928 if (!symHasReg (psym, sym->regs[i]))
1929 freeReg (sym->regs[i]);
1932 freeReg (sym->regs[i]);
1939 /*-----------------------------------------------------------------*/
1940 /* reassignLR - reassign this to registers */
1941 /*-----------------------------------------------------------------*/
1943 reassignLR (operand * op)
1945 symbol *sym = OP_SYMBOL (op);
1948 debugLog ("%s\n", __FUNCTION__);
1949 /* not spilt any more */
1950 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1951 bitVectUnSetBit (_G.spiltSet, sym->key);
1953 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1957 for (i = 0; i < sym->nRegs; i++)
1958 sym->regs[i]->isFree = 0;
1961 /*-----------------------------------------------------------------*/
1962 /* willCauseSpill - determines if allocating will cause a spill */
1963 /*-----------------------------------------------------------------*/
1965 willCauseSpill (int nr, int rt)
1967 debugLog ("%s\n", __FUNCTION__);
1968 /* first check if there are any avlb registers
1969 of te type required */
1972 /* special case for pointer type
1973 if pointer type not avlb then
1974 check for type gpr */
1975 if (nFreeRegs (rt) >= nr)
1977 if (nFreeRegs (REG_GPR) >= nr)
1982 if (pic16_ptrRegReq)
1984 if (nFreeRegs (rt) >= nr)
1989 if (nFreeRegs (REG_PTR) +
1990 nFreeRegs (REG_GPR) >= nr)
1995 debugLog (" ... yep it will (cause a spill)\n");
1996 /* it will cause a spil */
2000 /*-----------------------------------------------------------------*/
2001 /* positionRegs - the allocator can allocate same registers to res- */
2002 /* ult and operand, if this happens make sure they are in the same */
2003 /* position as the operand otherwise chaos results */
2004 /*-----------------------------------------------------------------*/
2006 positionRegs (symbol * result, symbol * opsym, int lineno)
2008 int count = min (result->nRegs, opsym->nRegs);
2009 int i, j = 0, shared = 0;
2011 debugLog ("%s\n", __FUNCTION__);
2012 /* if the result has been spilt then cannot share */
2017 /* first make sure that they actually share */
2018 for (i = 0; i < count; i++)
2020 for (j = 0; j < count; j++)
2022 if (result->regs[i] == opsym->regs[j] && i != j)
2032 regs *tmp = result->regs[i];
2033 result->regs[i] = result->regs[j];
2034 result->regs[j] = tmp;
2039 /*------------------------------------------------------------------*/
2040 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2041 /* it should either have registers or have beed spilled. Otherwise, */
2042 /* there was an uninitialized variable, so just spill this to get */
2043 /* the operand in a valid state. */
2044 /*------------------------------------------------------------------*/
2046 verifyRegsAssigned (operand *op, iCode * ic)
2051 if (!IS_ITEMP (op)) return;
2053 sym = OP_SYMBOL (op);
2054 if (sym->isspilt) return;
2055 if (!sym->nRegs) return;
2056 if (sym->regs[0]) return;
2058 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2059 sym->prereqv ? sym->prereqv->name : sym->name);
2064 /*-----------------------------------------------------------------*/
2065 /* serialRegAssign - serially allocate registers to the variables */
2066 /*-----------------------------------------------------------------*/
2068 serialRegAssign (eBBlock ** ebbs, int count)
2072 debugLog ("%s\n", __FUNCTION__);
2073 /* for all blocks */
2074 for (i = 0; i < count; i++)
2079 if (ebbs[i]->noPath &&
2080 (ebbs[i]->entryLabel != entryLabel &&
2081 ebbs[i]->entryLabel != returnLabel))
2084 /* of all instructions do */
2085 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2088 debugLog (" op: %s\n", decodeOp (ic->op));
2090 /* if this is an ipop that means some live
2091 range will have to be assigned again */
2093 reassignLR (IC_LEFT (ic));
2095 /* if result is present && is a true symbol */
2096 if (IC_RESULT (ic) && ic->op != IFX &&
2097 IS_TRUE_SYMOP (IC_RESULT (ic)))
2098 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2100 /* take away registers from live
2101 ranges that end at this instruction */
2102 deassignLRs (ic, ebbs[i]);
2104 /* some don't need registers */
2105 if (SKIP_IC2 (ic) ||
2106 ic->op == JUMPTABLE ||
2110 (IC_RESULT (ic) && POINTER_SET (ic)))
2113 /* now we need to allocate registers
2114 only for the result */
2117 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2123 /* if it does not need or is spilt
2124 or is already assigned to registers
2125 or will not live beyond this instructions */
2128 bitVectBitValue (_G.regAssigned, sym->key) ||
2129 sym->liveTo <= ic->seq)
2132 /* if some liverange has been spilt at the block level
2133 and this one live beyond this block then spil this
2135 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2140 /* if trying to allocate this will cause
2141 a spill and there is nothing to spill
2142 or this one is rematerializable then
2144 willCS = willCauseSpill (sym->nRegs, sym->regType);
2145 spillable = computeSpillable (ic);
2147 (willCS && bitVectIsZero (spillable)))
2155 /* if it has a spillocation & is used less than
2156 all other live ranges then spill this */
2158 if (sym->usl.spillLoc) {
2159 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2160 allLRs, ebbs[i], ic));
2161 if (leastUsed && leastUsed->used > sym->used) {
2166 /* if none of the liveRanges have a spillLocation then better
2167 to spill this one than anything else already assigned to registers */
2168 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2169 /* if this is local to this block then we might find a block spil */
2170 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2178 if (ic->op == RECEIVE)
2179 debugLog ("When I get clever, I'll optimize the receive logic\n");
2181 /* if we need ptr regs for the right side
2183 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2184 <= (unsigned) PTRSIZE)
2189 /* else we assign registers to it */
2190 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2192 debugLog (" %d - \n", __LINE__);
2194 bitVectDebugOn(_G.regAssigned, debugF);
2196 for (j = 0; j < sym->nRegs; j++)
2198 if (sym->regType == REG_PTR)
2199 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2201 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2203 /* if the allocation falied which means
2204 this was spilt then break */
2208 debugLog (" %d - \n", __LINE__);
2210 /* if it shares registers with operands make sure
2211 that they are in the same position */
2212 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2213 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2214 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2215 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2216 /* do the same for the right operand */
2217 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2218 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2219 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2220 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2222 debugLog (" %d - \n", __LINE__);
2225 debugLog (" %d - \n", __LINE__);
2234 /* Check for and fix any problems with uninitialized operands */
2235 for (i = 0; i < count; i++)
2239 if (ebbs[i]->noPath &&
2240 (ebbs[i]->entryLabel != entryLabel &&
2241 ebbs[i]->entryLabel != returnLabel))
2244 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2251 verifyRegsAssigned (IC_COND (ic), ic);
2255 if (ic->op == JUMPTABLE)
2257 verifyRegsAssigned (IC_JTCOND (ic), ic);
2261 verifyRegsAssigned (IC_RESULT (ic), ic);
2262 verifyRegsAssigned (IC_LEFT (ic), ic);
2263 verifyRegsAssigned (IC_RIGHT (ic), ic);
2269 /*-----------------------------------------------------------------*/
2270 /* rUmaskForOp :- returns register mask for an operand */
2271 /*-----------------------------------------------------------------*/
2273 rUmaskForOp (operand * op)
2279 debugLog ("%s\n", __FUNCTION__);
2280 /* only temporaries are assigned registers */
2284 sym = OP_SYMBOL (op);
2286 /* if spilt or no registers assigned to it
2288 if (sym->isspilt || !sym->nRegs)
2291 rumask = newBitVect (pic16_nRegs);
2293 for (j = 0; j < sym->nRegs; j++)
2295 rumask = bitVectSetBit (rumask,
2296 sym->regs[j]->rIdx);
2302 /*-----------------------------------------------------------------*/
2303 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2304 /*-----------------------------------------------------------------*/
2306 regsUsedIniCode (iCode * ic)
2308 bitVect *rmask = newBitVect (pic16_nRegs);
2310 debugLog ("%s\n", __FUNCTION__);
2311 /* do the special cases first */
2314 rmask = bitVectUnion (rmask,
2315 rUmaskForOp (IC_COND (ic)));
2319 /* for the jumptable */
2320 if (ic->op == JUMPTABLE)
2322 rmask = bitVectUnion (rmask,
2323 rUmaskForOp (IC_JTCOND (ic)));
2328 /* of all other cases */
2330 rmask = bitVectUnion (rmask,
2331 rUmaskForOp (IC_LEFT (ic)));
2335 rmask = bitVectUnion (rmask,
2336 rUmaskForOp (IC_RIGHT (ic)));
2339 rmask = bitVectUnion (rmask,
2340 rUmaskForOp (IC_RESULT (ic)));
2346 /*-----------------------------------------------------------------*/
2347 /* createRegMask - for each instruction will determine the regsUsed */
2348 /*-----------------------------------------------------------------*/
2350 createRegMask (eBBlock ** ebbs, int count)
2354 debugLog ("%s\n", __FUNCTION__);
2355 /* for all blocks */
2356 for (i = 0; i < count; i++)
2360 if (ebbs[i]->noPath &&
2361 (ebbs[i]->entryLabel != entryLabel &&
2362 ebbs[i]->entryLabel != returnLabel))
2365 /* for all instructions */
2366 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2371 if (SKIP_IC2 (ic) || !ic->rlive)
2374 /* first mark the registers used in this
2376 ic->rUsed = regsUsedIniCode (ic);
2377 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2379 /* now create the register mask for those
2380 registers that are in use : this is a
2381 super set of ic->rUsed */
2382 ic->rMask = newBitVect (pic16_nRegs + 1);
2384 /* for all live Ranges alive at this point */
2385 for (j = 1; j < ic->rlive->size; j++)
2390 /* if not alive then continue */
2391 if (!bitVectBitValue (ic->rlive, j))
2394 /* find the live range we are interested in */
2395 if (!(sym = hTabItemWithKey (liveRanges, j)))
2397 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2398 "createRegMask cannot find live range");
2402 /* if no register assigned to it */
2403 if (!sym->nRegs || sym->isspilt)
2406 /* for all the registers allocated to it */
2407 for (k = 0; k < sym->nRegs; k++)
2410 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2416 /*-----------------------------------------------------------------*/
2417 /* rematStr - returns the rematerialized string for a remat var */
2418 /*-----------------------------------------------------------------*/
2420 rematStr (symbol * sym)
2423 iCode *ic = sym->rematiCode;
2424 symbol *psym = NULL;
2426 debugLog ("%s\n", __FUNCTION__);
2428 //printf ("%s\n", s);
2430 /* if plus or minus print the right hand side */
2432 if (ic->op == '+' || ic->op == '-') {
2434 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2436 sprintf (s, "(%s %c 0x%04x)",
2437 OP_SYMBOL (IC_LEFT (ric))->rname,
2439 (int) operandLitValue (IC_RIGHT (ic)));
2442 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2444 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2445 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2450 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2451 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2453 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2458 /*-----------------------------------------------------------------*/
2459 /* rematStr - returns the rematerialized string for a remat var */
2460 /*-----------------------------------------------------------------*/
2462 rematStr (symbol * sym)
2465 iCode *ic = sym->rematiCode;
2467 debugLog ("%s\n", __FUNCTION__);
2472 /* if plus or minus print the right hand side */
2474 if (ic->op == '+' || ic->op == '-') {
2475 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2478 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2482 if (ic->op == '+' || ic->op == '-')
2484 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2485 sprintf (s, "(%s %c 0x%04x)",
2486 OP_SYMBOL (IC_LEFT (ric))->rname,
2488 (int) operandLitValue (IC_RIGHT (ic)));
2491 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2493 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2497 /* we reached the end */
2498 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2502 printf ("%s\n", buffer);
2507 /*-----------------------------------------------------------------*/
2508 /* regTypeNum - computes the type & number of registers required */
2509 /*-----------------------------------------------------------------*/
2517 debugLog ("%s\n", __FUNCTION__);
2518 /* for each live range do */
2519 for (sym = hTabFirstItem (liveRanges, &k); sym;
2520 sym = hTabNextItem (liveRanges, &k)) {
2522 debugLog (" %d - %s\n", __LINE__, sym->rname);
2523 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2525 /* if used zero times then no registers needed */
2526 if ((sym->liveTo - sym->liveFrom) == 0)
2530 /* if the live range is a temporary */
2533 debugLog (" %d - itemp register\n", __LINE__);
2535 /* if the type is marked as a conditional */
2536 if (sym->regType == REG_CND)
2539 /* if used in return only then we don't
2541 if (sym->ruonly || sym->accuse) {
2542 if (IS_AGGREGATE (sym->type) || sym->isptr)
2543 sym->type = aggrToPtr (sym->type, FALSE);
2544 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2549 /* if the symbol has only one definition &
2550 that definition is a get_pointer and the
2551 pointer we are getting is rematerializable and
2554 if (bitVectnBitsOn (sym->defs) == 1 &&
2555 (ic = hTabItemWithKey (iCodehTab,
2556 bitVectFirstBit (sym->defs))) &&
2559 !IS_BITVAR (sym->etype)) {
2562 debugLog (" %d - \n", __LINE__);
2564 /* if remat in data space */
2565 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2566 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2568 /* create a psuedo symbol & force a spil */
2569 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2570 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2571 psym->type = sym->type;
2572 psym->etype = sym->etype;
2573 strcpy (psym->rname, psym->name);
2575 sym->usl.spillLoc = psym;
2579 /* if in data space or idata space then try to
2580 allocate pointer register */
2584 /* if not then we require registers */
2585 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2586 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2587 getSize (sym->type));
2591 if(IS_PTR_CONST (sym->type)) {
2593 if(IS_CODEPTR (sym->type)) {
2595 // what IS this ???? (HJD)
2596 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2597 sym->nRegs = 3; // patch 14
2600 if (sym->nRegs > 4) {
2601 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2602 printTypeChain (sym->type, stderr);
2603 fprintf (stderr, "\n");
2606 /* determine the type of register required */
2607 if (sym->nRegs == 1 &&
2608 IS_PTR (sym->type) &&
2610 sym->regType = REG_PTR;
2612 sym->regType = REG_GPR;
2615 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2619 /* for the first run we don't provide */
2620 /* registers for true symbols we will */
2621 /* see how things go */
2626 static DEFSETFUNC (markRegFree)
2628 ((regs *)item)->isFree = 1;
2633 DEFSETFUNC (pic16_deallocReg)
2635 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2636 ((regs *)item)->isFree = 1;
2637 ((regs *)item)->wasUsed = 0;
2641 /*-----------------------------------------------------------------*/
2642 /* freeAllRegs - mark all registers as free */
2643 /*-----------------------------------------------------------------*/
2645 pic16_freeAllRegs ()
2647 debugLog ("%s\n", __FUNCTION__);
2649 applyToSet(pic16_dynAllocRegs,markRegFree);
2650 applyToSet(pic16_dynStackRegs,markRegFree);
2653 /*-----------------------------------------------------------------*/
2654 /*-----------------------------------------------------------------*/
2656 pic16_deallocateAllRegs ()
2658 debugLog ("%s\n", __FUNCTION__);
2660 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2664 /*-----------------------------------------------------------------*/
2665 /* deallocStackSpil - this will set the stack pointer back */
2666 /*-----------------------------------------------------------------*/
2668 DEFSETFUNC (deallocStackSpil)
2672 debugLog ("%s\n", __FUNCTION__);
2677 /*-----------------------------------------------------------------*/
2678 /* farSpacePackable - returns the packable icode for far variables */
2679 /*-----------------------------------------------------------------*/
2681 farSpacePackable (iCode * ic)
2685 debugLog ("%s\n", __FUNCTION__);
2686 /* go thru till we find a definition for the
2687 symbol on the right */
2688 for (dic = ic->prev; dic; dic = dic->prev)
2691 /* if the definition is a call then no */
2692 if ((dic->op == CALL || dic->op == PCALL) &&
2693 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2698 /* if shift by unknown amount then not */
2699 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2700 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2703 /* if pointer get and size > 1 */
2704 if (POINTER_GET (dic) &&
2705 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2708 if (POINTER_SET (dic) &&
2709 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2712 /* if any three is a true symbol in far space */
2713 if (IC_RESULT (dic) &&
2714 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2715 isOperandInFarSpace (IC_RESULT (dic)))
2718 if (IC_RIGHT (dic) &&
2719 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2720 isOperandInFarSpace (IC_RIGHT (dic)) &&
2721 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2724 if (IC_LEFT (dic) &&
2725 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2726 isOperandInFarSpace (IC_LEFT (dic)) &&
2727 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2730 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2732 if ((dic->op == LEFT_OP ||
2733 dic->op == RIGHT_OP ||
2735 IS_OP_LITERAL (IC_RIGHT (dic)))
2745 /*-----------------------------------------------------------------*/
2746 /* packRegsForAssign - register reduction for assignment */
2747 /*-----------------------------------------------------------------*/
2749 packRegsForAssign (iCode * ic, eBBlock * ebp)
2754 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2755 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2756 debugAopGet (" result:", IC_RESULT (ic));
2757 debugAopGet (" left:", IC_LEFT (ic));
2758 debugAopGet (" right:", IC_RIGHT (ic));
2760 /* if this is at an absolute address, then get the address. */
2761 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2762 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2763 debugLog (" %d - found config word declaration\n", __LINE__);
2764 if(IS_VALOP(IC_RIGHT(ic))) {
2765 debugLog (" setting config word to %x\n",
2766 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2767 fprintf(stderr, " setting config word to %x\n",
2768 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2769 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2770 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2774 debugLog(" %d\n", __LINE__);
2776 /* remove the assignment from the iCode chain. */
2778 remiCodeFromeBBlock (ebp, ic);
2779 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2780 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2786 debugLog(" %d - actuall processing\n", __LINE__ );
2788 if (!IS_ITEMP (IC_RESULT (ic))) {
2789 pic16_allocDirReg(IC_RESULT (ic));
2790 debugLog (" %d - result is not temp\n", __LINE__);
2794 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2795 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2796 pic16_allocDirReg(IC_LEFT (ic));
2800 /* See BUGLOG0001 - VR */
2802 if (!IS_ITEMP (IC_RIGHT (ic))) {
2803 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2804 pic16_allocDirReg(IC_RIGHT (ic));
2809 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2810 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2812 debugLog (" %d - not packing - right side fails \n", __LINE__);
2816 /* if the true symbol is defined in far space or on stack
2817 then we should not since this will increase register pressure */
2818 if (isOperandInFarSpace (IC_RESULT (ic)))
2820 if ((dic = farSpacePackable (ic)))
2827 /* find the definition of iTempNN scanning backwards if we find a
2828 a use of the true symbol before we find the definition then
2830 for (dic = ic->prev; dic; dic = dic->prev)
2833 /* if there is a function call and this is
2834 a parameter & not my parameter then don't pack it */
2835 if ((dic->op == CALL || dic->op == PCALL) &&
2836 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2837 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2839 debugLog (" %d - \n", __LINE__);
2848 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2851 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2852 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2853 debugAopGet(" result is ", IC_RESULT(dic));
2855 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2856 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2857 debugAopGet(" left is ", IC_LEFT(dic));
2859 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2860 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2861 debugAopGet(" right is ", IC_RIGHT(dic));
2865 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2866 IS_OP_VOLATILE (IC_RESULT (dic)))
2868 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2874 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2875 IS_OP_VOLATILE (IC_RIGHT(dic)))
2877 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2884 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2885 IS_OP_VOLATILE (IC_LEFT(dic)))
2887 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2895 if( IS_SYMOP( IC_RESULT(dic)) &&
2896 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2898 debugLog (" %d - result is bitfield\n", __LINE__);
2904 if (IS_SYMOP (IC_RESULT (dic)) &&
2905 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2907 /* A previous result was assigned to the same register - we'll our definition */
2908 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2909 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2910 if (POINTER_SET (dic))
2916 if (IS_SYMOP (IC_RIGHT (dic)) &&
2917 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2918 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2920 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2925 if (IS_SYMOP (IC_LEFT (dic)) &&
2926 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2927 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2929 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2934 if (POINTER_SET (dic) &&
2935 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2937 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2945 return 0; /* did not find */
2948 /* This code is taken from the hc08 port. Do not know
2949 * if it fits for pic16, but I leave it here just in case */
2951 /* if assignment then check that right is not a bit */
2952 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2953 sym_link *etype = operandType (IC_RIGHT (dic));
2955 if (IS_BITFIELD (etype)) {
2956 /* if result is a bit too then it's ok */
2957 etype = operandType (IC_RESULT (dic));
2958 if (!IS_BITFIELD (etype)) {
2959 debugLog(" %d bitfields\n");
2966 /* if the result is on stack or iaccess then it must be
2967 the same atleast one of the operands */
2968 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2969 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2972 /* the operation has only one symbol
2973 operator then we can pack */
2974 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2975 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2978 if (!((IC_LEFT (dic) &&
2979 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2981 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2985 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2986 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2987 /* found the definition */
2988 /* replace the result with the result of */
2989 /* this assignment and remove this assignment */
2990 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2991 IC_RESULT (dic) = IC_RESULT (ic);
2993 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2995 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2997 /* delete from liverange table also
2998 delete from all the points inbetween and the new
3000 for (sic = dic; sic != ic; sic = sic->next)
3002 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3003 if (IS_ITEMP (IC_RESULT (dic)))
3004 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3007 remiCodeFromeBBlock (ebp, ic);
3008 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3010 debugLog(" %d\n", __LINE__ );
3011 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3012 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3018 #define NO_packRegsForAccUse
3019 #define NO_packRegsForSupport
3020 #define NO_packRegsForOneuse
3021 #define NO_cast_peep
3024 #ifndef NO_packRegsForSupport
3025 /*-----------------------------------------------------------------*/
3026 /* findAssignToSym : scanning backwards looks for first assig found */
3027 /*-----------------------------------------------------------------*/
3029 findAssignToSym (operand * op, iCode * ic)
3033 debugLog ("%s\n", __FUNCTION__);
3034 for (dic = ic->prev; dic; dic = dic->prev)
3037 /* if definition by assignment */
3038 if (dic->op == '=' &&
3039 !POINTER_SET (dic) &&
3040 IC_RESULT (dic)->key == op->key
3041 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3045 /* we are interested only if defined in far space */
3046 /* or in stack space in case of + & - */
3048 /* if assigned to a non-symbol then return
3050 if (!IS_SYMOP (IC_RIGHT (dic)))
3053 /* if the symbol is in far space then
3055 if (isOperandInFarSpace (IC_RIGHT (dic)))
3058 /* for + & - operations make sure that
3059 if it is on the stack it is the same
3060 as one of the three operands */
3061 if ((ic->op == '+' || ic->op == '-') &&
3062 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3065 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3066 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3067 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3075 /* if we find an usage then we cannot delete it */
3076 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3079 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3082 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3086 /* now make sure that the right side of dic
3087 is not defined between ic & dic */
3090 iCode *sic = dic->next;
3092 for (; sic != ic; sic = sic->next)
3093 if (IC_RESULT (sic) &&
3094 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3105 #ifndef NO_packRegsForSupport
3106 /*-----------------------------------------------------------------*/
3107 /* packRegsForSupport :- reduce some registers for support calls */
3108 /*-----------------------------------------------------------------*/
3110 packRegsForSupport (iCode * ic, eBBlock * ebp)
3114 debugLog ("%s\n", __FUNCTION__);
3115 /* for the left & right operand :- look to see if the
3116 left was assigned a true symbol in far space in that
3117 case replace them */
3118 if (IS_ITEMP (IC_LEFT (ic)) &&
3119 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3121 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3127 debugAopGet ("removing left:", IC_LEFT (ic));
3129 /* found it we need to remove it from the
3131 for (sic = dic; sic != ic; sic = sic->next)
3132 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3134 IC_LEFT (ic)->operand.symOperand =
3135 IC_RIGHT (dic)->operand.symOperand;
3136 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3137 remiCodeFromeBBlock (ebp, dic);
3138 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3139 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3143 /* do the same for the right operand */
3146 IS_ITEMP (IC_RIGHT (ic)) &&
3147 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3149 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3155 /* if this is a subtraction & the result
3156 is a true symbol in far space then don't pack */
3157 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3159 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3160 if (IN_FARSPACE (SPEC_OCLS (etype)))
3164 debugAopGet ("removing right:", IC_RIGHT (ic));
3166 /* found it we need to remove it from the
3168 for (sic = dic; sic != ic; sic = sic->next)
3169 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3171 IC_RIGHT (ic)->operand.symOperand =
3172 IC_RIGHT (dic)->operand.symOperand;
3173 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3175 remiCodeFromeBBlock (ebp, dic);
3176 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3177 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3186 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3188 #ifndef NO_packRegsForOneuse
3189 /*-----------------------------------------------------------------*/
3190 /* packRegsForOneuse : - will reduce some registers for single Use */
3191 /*-----------------------------------------------------------------*/
3193 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3198 debugLog ("%s\n", __FUNCTION__);
3199 /* if returning a literal then do nothing */
3203 /* only upto 2 bytes since we cannot predict
3204 the usage of b, & acc */
3205 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3210 /* this routine will mark the a symbol as used in one
3211 instruction use only && if the definition is local
3212 (ie. within the basic block) && has only one definition &&
3213 that definition is either a return value from a
3214 function or does not contain any variables in
3216 uses = bitVectCopy (OP_USES (op));
3217 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3218 if (!bitVectIsZero (uses)) /* has other uses */
3221 /* if it has only one defintion */
3222 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3223 return NULL; /* has more than one definition */
3225 /* get that definition */
3227 hTabItemWithKey (iCodehTab,
3228 bitVectFirstBit (OP_DEFS (op)))))
3231 /* found the definition now check if it is local */
3232 if (dic->seq < ebp->fSeq ||
3233 dic->seq > ebp->lSeq)
3234 return NULL; /* non-local */
3236 /* now check if it is the return from
3238 if (dic->op == CALL || dic->op == PCALL)
3240 if (ic->op != SEND && ic->op != RETURN &&
3241 !POINTER_SET(ic) && !POINTER_GET(ic))
3243 OP_SYMBOL (op)->ruonly = 1;
3250 /* otherwise check that the definition does
3251 not contain any symbols in far space */
3252 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3253 isOperandInFarSpace (IC_RIGHT (dic)) ||
3254 IS_OP_RUONLY (IC_LEFT (ic)) ||
3255 IS_OP_RUONLY (IC_RIGHT (ic)))
3260 /* if pointer set then make sure the pointer
3262 if (POINTER_SET (dic) &&
3263 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3266 if (POINTER_GET (dic) &&
3267 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3272 /* also make sure the intervenening instructions
3273 don't have any thing in far space */
3274 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3277 /* if there is an intervening function call then no */
3278 if (dic->op == CALL || dic->op == PCALL)
3280 /* if pointer set then make sure the pointer
3282 if (POINTER_SET (dic) &&
3283 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3286 if (POINTER_GET (dic) &&
3287 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3290 /* if address of & the result is remat then okay */
3291 if (dic->op == ADDRESS_OF &&
3292 OP_SYMBOL (IC_RESULT (dic))->remat)
3295 /* if operand has size of three or more & this
3296 operation is a '*','/' or '%' then 'b' may
3298 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3299 getSize (operandType (op)) >= 3)
3302 /* if left or right or result is in far space */
3303 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3304 isOperandInFarSpace (IC_RIGHT (dic)) ||
3305 isOperandInFarSpace (IC_RESULT (dic)) ||
3306 IS_OP_RUONLY (IC_LEFT (dic)) ||
3307 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3308 IS_OP_RUONLY (IC_RESULT (dic)))
3314 OP_SYMBOL (op)->ruonly = 1;
3321 /*-----------------------------------------------------------------*/
3322 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3323 /*-----------------------------------------------------------------*/
3325 isBitwiseOptimizable (iCode * ic)
3327 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3328 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3330 debugLog ("%s\n", __FUNCTION__);
3331 /* bitwise operations are considered optimizable
3332 under the following conditions (Jean-Louis VERN)
3344 if (IS_LITERAL (rtype) ||
3345 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3352 #ifndef NO_packRegsForAccUse
3354 /*-----------------------------------------------------------------*/
3355 /* packRegsForAccUse - pack registers for acc use */
3356 /*-----------------------------------------------------------------*/
3358 packRegsForAccUse (iCode * ic)
3362 debugLog ("%s\n", __FUNCTION__);
3364 /* if this is an aggregate, e.g. a one byte char array */
3365 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3368 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3370 /* if + or - then it has to be one byte result */
3371 if ((ic->op == '+' || ic->op == '-')
3372 && getSize (operandType (IC_RESULT (ic))) > 1)
3375 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3376 /* if shift operation make sure right side is not a literal */
3377 if (ic->op == RIGHT_OP &&
3378 (isOperandLiteral (IC_RIGHT (ic)) ||
3379 getSize (operandType (IC_RESULT (ic))) > 1))
3382 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3383 if (ic->op == LEFT_OP &&
3384 (isOperandLiteral (IC_RIGHT (ic)) ||
3385 getSize (operandType (IC_RESULT (ic))) > 1))
3388 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3389 if (IS_BITWISE_OP (ic) &&
3390 getSize (operandType (IC_RESULT (ic))) > 1)
3394 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3395 /* has only one definition */
3396 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3399 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3400 /* has only one use */
3401 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3404 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3405 /* and the usage immediately follows this iCode */
3406 if (!(uic = hTabItemWithKey (iCodehTab,
3407 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3410 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3411 if (ic->next != uic)
3414 /* if it is a conditional branch then we definitely can */
3418 if (uic->op == JUMPTABLE)
3421 /* if the usage is not is an assignment
3422 or an arithmetic / bitwise / shift operation then not */
3423 if (POINTER_SET (uic) &&
3424 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3427 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3428 if (uic->op != '=' &&
3429 !IS_ARITHMETIC_OP (uic) &&
3430 !IS_BITWISE_OP (uic) &&
3431 uic->op != LEFT_OP &&
3432 uic->op != RIGHT_OP)
3435 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3436 /* if used in ^ operation then make sure right is not a
3438 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3441 /* if shift operation make sure right side is not a literal */
3442 if (uic->op == RIGHT_OP &&
3443 (isOperandLiteral (IC_RIGHT (uic)) ||
3444 getSize (operandType (IC_RESULT (uic))) > 1))
3447 if (uic->op == LEFT_OP &&
3448 (isOperandLiteral (IC_RIGHT (uic)) ||
3449 getSize (operandType (IC_RESULT (uic))) > 1))
3452 /* make sure that the result of this icode is not on the
3453 stack, since acc is used to compute stack offset */
3454 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3455 OP_SYMBOL (IC_RESULT (uic))->onStack)
3458 /* if either one of them in far space then we cannot */
3459 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3460 isOperandInFarSpace (IC_LEFT (uic))) ||
3461 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3462 isOperandInFarSpace (IC_RIGHT (uic))))
3465 /* if the usage has only one operand then we can */
3466 if (IC_LEFT (uic) == NULL ||
3467 IC_RIGHT (uic) == NULL)
3470 /* make sure this is on the left side if not
3471 a '+' since '+' is commutative */
3472 if (ic->op != '+' &&
3473 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3477 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3478 /* if one of them is a literal then we can */
3479 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3480 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3481 (getSize (operandType (IC_RESULT (uic))) <= 1))
3483 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3488 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3489 /* if the other one is not on stack then we can */
3490 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3491 (IS_ITEMP (IC_RIGHT (uic)) ||
3492 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3493 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3496 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3497 (IS_ITEMP (IC_LEFT (uic)) ||
3498 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3499 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3505 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3506 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3513 /*-----------------------------------------------------------------*/
3514 /* packForPush - hueristics to reduce iCode for pushing */
3515 /*-----------------------------------------------------------------*/
3517 packForReceive (iCode * ic, eBBlock * ebp)
3521 debugLog ("%s\n", __FUNCTION__);
3522 debugAopGet (" result:", IC_RESULT (ic));
3523 debugAopGet (" left:", IC_LEFT (ic));
3524 debugAopGet (" right:", IC_RIGHT (ic));
3529 for (dic = ic->next; dic; dic = dic->next)
3534 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3535 debugLog (" used on left\n");
3536 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3537 debugLog (" used on right\n");
3538 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3539 debugLog (" used on result\n");
3541 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3542 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3547 debugLog (" hey we can remove this unnecessary assign\n");
3549 /*-----------------------------------------------------------------*/
3550 /* packForPush - hueristics to reduce iCode for pushing */
3551 /*-----------------------------------------------------------------*/
3553 packForPush (iCode * ic, eBBlock * ebp)
3557 debugLog ("%s\n", __FUNCTION__);
3558 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3561 /* must have only definition & one usage */
3562 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3563 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3566 /* find the definition */
3567 if (!(dic = hTabItemWithKey (iCodehTab,
3568 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3571 if (dic->op != '=' || POINTER_SET (dic))
3574 /* we now we know that it has one & only one def & use
3575 and the that the definition is an assignment */
3576 IC_LEFT (ic) = IC_RIGHT (dic);
3578 remiCodeFromeBBlock (ebp, dic);
3579 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3580 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3583 static void printSymType(char * str, sym_link *sl)
3585 if(!pic16_ralloc_debug)return;
3587 debugLog (" %s Symbol type: ",str);
3588 printTypeChain( sl, debugF);
3592 /*-----------------------------------------------------------------*/
3593 /* some debug code to print the symbol S_TYPE. Note that
3594 * the function checkSClass in src/SDCCsymt.c dinks with
3595 * the S_TYPE in ways the PIC port doesn't fully like...*/
3596 /*-----------------------------------------------------------------*/
3597 static void isData(sym_link *sl)
3601 if(!pic16_ralloc_debug)return;
3608 for ( ; sl; sl=sl->next) {
3610 switch (SPEC_SCLS(sl)) {
3611 case S_DATA: fprintf (of, "data "); break;
3612 case S_XDATA: fprintf (of, "xdata "); break;
3613 case S_SFR: fprintf (of, "sfr "); break;
3614 case S_SBIT: fprintf (of, "sbit "); break;
3615 case S_CODE: fprintf (of, "code "); break;
3616 case S_IDATA: fprintf (of, "idata "); break;
3617 case S_PDATA: fprintf (of, "pdata "); break;
3618 case S_LITERAL: fprintf (of, "literal "); break;
3619 case S_STACK: fprintf (of, "stack "); break;
3620 case S_XSTACK: fprintf (of, "xstack "); break;
3621 case S_BIT: fprintf (of, "bit "); break;
3622 case S_EEPROM: fprintf (of, "eeprom "); break;
3631 /*--------------------------------------------------------------------*/
3632 /* pic16_packRegisters - does some transformations to reduce */
3633 /* register pressure */
3635 /*--------------------------------------------------------------------*/
3637 pic16_packRegisters (eBBlock * ebp)
3642 debugLog ("%s\n", __FUNCTION__);
3648 /* look for assignments of the form */
3649 /* iTempNN = TRueSym (someoperation) SomeOperand */
3651 /* TrueSym := iTempNN:1 */
3652 for (ic = ebp->sch; ic; ic = ic->next)
3654 // debugLog("%d\n", __LINE__);
3655 /* find assignment of the form TrueSym := iTempNN:1 */
3656 /* see BUGLOG0001 for workaround with the CAST - VR */
3657 if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3658 // if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3659 change += packRegsForAssign (ic, ebp);
3663 if (POINTER_SET (ic))
3664 debugLog ("pointer is set\n");
3665 debugAopGet (" result:", IC_RESULT (ic));
3666 debugAopGet (" left:", IC_LEFT (ic));
3667 debugAopGet (" right:", IC_RIGHT (ic));
3676 for (ic = ebp->sch; ic; ic = ic->next) {
3678 if(IS_SYMOP ( IC_LEFT(ic))) {
3679 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3681 debugAopGet ("x left:", IC_LEFT (ic));
3683 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3685 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3687 debugLog (" is a pointer\n");
3689 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3690 debugLog (" is a ptr\n");
3692 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3693 debugLog (" is volatile\n");
3697 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3698 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3699 pic16_allocDirReg(IC_LEFT (ic));
3702 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3705 if(IS_SYMOP ( IC_RIGHT(ic))) {
3706 debugAopGet (" right:", IC_RIGHT (ic));
3707 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3710 if(IS_SYMOP ( IC_RESULT(ic))) {
3711 debugAopGet (" result:", IC_RESULT (ic));
3712 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3715 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3716 debugAopGet (" right:", IC_RIGHT (ic));
3717 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3718 // pic16_allocDirReg(IC_RIGHT(ic));
3721 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3722 debugAopGet (" result:", IC_RESULT (ic));
3723 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3724 // pic16_allocDirReg(IC_RESULT(ic));
3728 if (POINTER_SET (ic))
3729 debugLog (" %d - Pointer set\n", __LINE__);
3732 /* if this is an itemp & result of a address of a true sym
3733 then mark this as rematerialisable */
3734 if (ic->op == ADDRESS_OF &&
3735 IS_ITEMP (IC_RESULT (ic)) &&
3736 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3737 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3738 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3741 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3743 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3744 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3745 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3749 /* if straight assignment then carry remat flag if
3750 this is the only definition */
3751 if (ic->op == '=' &&
3752 !POINTER_SET (ic) &&
3753 IS_SYMOP (IC_RIGHT (ic)) &&
3754 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3755 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3757 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3759 OP_SYMBOL (IC_RESULT (ic))->remat =
3760 OP_SYMBOL (IC_RIGHT (ic))->remat;
3761 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3762 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3765 /* if this is a +/- operation with a rematerizable
3766 then mark this as rematerializable as well */
3767 if ((ic->op == '+' || ic->op == '-') &&
3768 (IS_SYMOP (IC_LEFT (ic)) &&
3769 IS_ITEMP (IC_RESULT (ic)) &&
3770 OP_SYMBOL (IC_LEFT (ic))->remat &&
3771 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3772 IS_OP_LITERAL (IC_RIGHT (ic))))
3774 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3776 operandLitValue (IC_RIGHT (ic));
3777 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3778 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3779 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3782 /* mark the pointer usages */
3783 if (POINTER_SET (ic))
3785 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3786 debugLog (" marking as a pointer (set) =>");
3787 debugAopGet (" result:", IC_RESULT (ic));
3789 if (POINTER_GET (ic))
3791 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3792 debugLog (" marking as a pointer (get) =>");
3793 debugAopGet (" left:", IC_LEFT (ic));
3796 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3800 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3801 /* if we are using a symbol on the stack
3802 then we should say pic16_ptrRegReq */
3803 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3804 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3805 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3806 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3807 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3808 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3812 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3813 if (IS_SYMOP (IC_LEFT (ic)))
3814 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3815 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3816 if (IS_SYMOP (IC_RIGHT (ic)))
3817 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3818 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3819 if (IS_SYMOP (IC_RESULT (ic)))
3820 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3821 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3824 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3828 /* if the condition of an if instruction
3829 is defined in the previous instruction then
3830 mark the itemp as a conditional */
3831 if ((IS_CONDITIONAL (ic) ||
3832 ((ic->op == BITWISEAND ||
3835 isBitwiseOptimizable (ic))) &&
3836 ic->next && ic->next->op == IFX &&
3837 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3838 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3841 debugLog (" %d\n", __LINE__);
3842 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3846 debugLog(" %d\n", __LINE__);
3848 #ifndef NO_packRegsForSupport
3849 /* reduce for support function calls */
3850 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3851 packRegsForSupport (ic, ebp);
3854 /* if a parameter is passed, it's in W, so we may not
3855 need to place a copy in a register */
3856 if (ic->op == RECEIVE)
3857 packForReceive (ic, ebp);
3859 #ifndef NO_packRegsForOneuse
3860 /* some cases the redundant moves can
3861 can be eliminated for return statements */
3862 if ((ic->op == RETURN || ic->op == SEND) &&
3863 !isOperandInFarSpace (IC_LEFT (ic)) &&
3865 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3868 #ifndef NO_packRegsForOneuse
3869 /* if pointer set & left has a size more than
3870 one and right is not in far space */
3871 if (POINTER_SET (ic) &&
3872 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3873 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3874 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3875 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3877 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3880 #ifndef NO_packRegsForOneuse
3881 /* if pointer get */
3882 if (POINTER_GET (ic) &&
3883 !isOperandInFarSpace (IC_RESULT (ic)) &&
3884 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3885 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3886 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3888 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3889 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3892 #ifndef NO_cast_peep
3893 /* if this is cast for intergral promotion then
3894 check if only use of the definition of the
3895 operand being casted/ if yes then replace
3896 the result of that arithmetic operation with
3897 this result and get rid of the cast */
3898 if (ic->op == CAST) {
3900 sym_link *fromType = operandType (IC_RIGHT (ic));
3901 sym_link *toType = operandType (IC_LEFT (ic));
3903 debugLog (" %d - casting\n", __LINE__);
3905 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3906 getSize (fromType) != getSize (toType)) {
3909 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3912 if (IS_ARITHMETIC_OP (dic)) {
3913 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3915 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3916 IC_RESULT (dic) = IC_RESULT (ic);
3917 remiCodeFromeBBlock (ebp, ic);
3918 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3919 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3920 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3924 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3928 /* if the type from and type to are the same
3929 then if this is the only use then packit */
3930 if (compareType (operandType (IC_RIGHT (ic)),
3931 operandType (IC_LEFT (ic))) == 1) {
3933 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3936 debugLog(" %d\n", __LINE__);
3938 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3939 IC_RESULT (dic) = IC_RESULT (ic);
3940 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3941 remiCodeFromeBBlock (ebp, ic);
3942 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3943 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3951 iTempNN := (some variable in farspace) V1
3956 if (ic->op == IPUSH)
3958 packForPush (ic, ebp);
3962 #ifndef NO_packRegsForAccUse
3963 /* pack registers for accumulator use, when the
3964 result of an arithmetic or bit wise operation
3965 has only one use, that use is immediately following
3966 the defintion and the using iCode has only one
3967 operand or has two operands but one is literal &
3968 the result of that operation is not on stack then
3969 we can leave the result of this operation in acc:b
3971 if ((IS_ARITHMETIC_OP (ic)
3973 || IS_BITWISE_OP (ic)
3975 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3978 IS_ITEMP (IC_RESULT (ic)) &&
3979 getSize (operandType (IC_RESULT (ic))) <= 1)
3981 packRegsForAccUse (ic);
3988 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3992 if (!pic16_ralloc_debug || !debugF)
3995 for (i = 0; i < count; i++)
3997 fprintf (debugF, "\n----------------------------------------------------------------\n");
3998 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3999 ebbs[i]->entryLabel->name,
4002 ebbs[i]->isLastInLoop);
4003 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4008 fprintf (debugF, "visited %d : hasFcall = %d\n",
4012 fprintf (debugF, "\ndefines bitVector :");
4013 bitVectDebugOn (ebbs[i]->defSet, debugF);
4014 fprintf (debugF, "\nlocal defines bitVector :");
4015 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4016 fprintf (debugF, "\npointers Set bitvector :");
4017 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4018 fprintf (debugF, "\nin pointers Set bitvector :");
4019 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4020 fprintf (debugF, "\ninDefs Set bitvector :");
4021 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4022 fprintf (debugF, "\noutDefs Set bitvector :");
4023 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4024 fprintf (debugF, "\nusesDefs Set bitvector :");
4025 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4026 fprintf (debugF, "\n----------------------------------------------------------------\n");
4027 printiCChain (ebbs[i]->sch, debugF);
4030 /*-----------------------------------------------------------------*/
4031 /* pic16_assignRegisters - assigns registers to each live range as need */
4032 /*-----------------------------------------------------------------*/
4034 pic16_assignRegisters (eBBlock ** ebbs, int count)
4039 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4040 debugLog ("\nebbs before optimizing:\n");
4041 dumpEbbsToDebug (ebbs, count);
4043 setToNull ((void *) &_G.funcrUsed);
4044 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4047 /* change assignments this will remove some
4048 live ranges reducing some register pressure */
4049 for (i = 0; i < count; i++)
4050 pic16_packRegisters (ebbs[i]);
4057 debugLog("dir registers allocated so far:\n");
4058 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4061 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4062 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4063 reg = hTabNextItem(dynDirectRegNames, &hkey);
4068 /* liveranges probably changed by register packing
4069 so we compute them again */
4070 recomputeLiveRanges (ebbs, count);
4072 if (options.dump_pack)
4073 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4075 /* first determine for each live range the number of
4076 registers & the type of registers required for each */
4079 /* and serially allocate registers */
4080 serialRegAssign (ebbs, count);
4082 // debugLog ("ebbs after serialRegAssign:\n");
4083 // dumpEbbsToDebug (ebbs, count);
4086 //pic16_freeAllRegs();
4088 /* if stack was extended then tell the user */
4091 /* werror(W_TOOMANY_SPILS,"stack", */
4092 /* _G.stackExtend,currFunc->name,""); */
4098 /* werror(W_TOOMANY_SPILS,"data space", */
4099 /* _G.dataExtend,currFunc->name,""); */
4103 /* after that create the register mask
4104 for each of the instruction */
4105 createRegMask (ebbs, count);
4107 /* redo that offsets for stacked automatic variables */
4108 redoStackOffsets ();
4110 if (options.dump_rassgn)
4111 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4113 /* now get back the chain */
4114 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4116 debugLog ("ebbs after optimizing:\n");
4117 dumpEbbsToDebug (ebbs, count);
4122 /* free up any _G.stackSpil locations allocated */
4123 applyToSet (_G.stackSpil, deallocStackSpil);
4125 setToNull ((void *) &_G.stackSpil);
4126 setToNull ((void *) &_G.spiltSet);
4127 /* mark all registers as free */
4128 pic16_freeAllRegs ();
4130 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");