1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
35 #define FENTRY2 1 ? (void)0 : printf
37 #define STRCASECMP strcasecmp
38 //#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0)
39 #define FENTRY2 1 ? (void)0 : printf
42 /* this should go in SDCCicode.h, but it doesn't. */
43 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
45 /*-----------------------------------------------------------------*/
46 /* At this point we start getting processor specific although */
47 /* some routines are non-processor specific & can be reused when */
48 /* targetting other processors. The decision for this will have */
49 /* to be made on a routine by routine basis */
50 /* routines used to pack registers are most definitely not reusable */
51 /* since the pack the registers depending strictly on the MCU */
52 /*-----------------------------------------------------------------*/
54 extern void genpic14Code (iCode *);
55 extern void pic14_assignConfigWordValue(int address, int value);
65 bitVect *funcrUsed; /* registers used in a function */
71 /* Shared with gen.c */
72 int pic14_ptrRegReq; /* one byte pointer register required */
75 set *dynAllocRegs=NULL;
76 set *dynStackRegs=NULL;
77 set *dynProcessorRegs=NULL;
78 set *dynDirectRegs=NULL;
79 set *dynDirectBitRegs=NULL;
80 set *dynInternalRegs=NULL;
82 static hTab *dynDirectRegNames= NULL;
83 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 static int dynrIdx = 0x1000;
87 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
89 int Gstack_base_addr=0; /* The starting address of registers that
90 * are used to pass and return parameters */
96 static void spillThis (symbol *);
98 static FILE *debugF = NULL;
99 /*-----------------------------------------------------------------*/
100 /* debugLog - open a file for debugging information */
101 /*-----------------------------------------------------------------*/
102 //static void debugLog(char *inst,char *fmt, ...)
104 debugLog (char *fmt,...)
106 static int append = 0; // First time through, open the file without append.
109 //char *bufferP=buffer;
112 if (!debug || !dstFileName)
118 /* create the file name */
119 strcpy (buffer, dstFileName);
120 strcat (buffer, ".d");
122 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
124 werror (E_FILE_OPEN_ERR, buffer);
127 append = 1; // Next time debubLog is called, we'll append the debug info
133 vsprintf (buffer, fmt, ap);
135 fprintf (debugF, "%s", buffer);
136 //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
138 while (isspace((unsigned char)*bufferP)) bufferP++;
140 if (bufferP && *bufferP)
141 lineCurr = (lineCurr ?
142 connectLine(lineCurr,newLineNode(lb)) :
143 (lineHead = newLineNode(lb)));
144 lineCurr->isInline = _G.inLine;
145 lineCurr->isDebug = _G.debugLine;
155 fputc ('\n', debugF);
157 /*-----------------------------------------------------------------*/
158 /* debugLogClose - closes the debug log file (if opened) */
159 /*-----------------------------------------------------------------*/
169 #define AOP(op) op->aop
172 debugAopGet (char *str, operand * op)
177 printOperand (op, debugF);
185 decodeOp (unsigned int op)
188 if (op < 128 && op > ' ')
190 buffer[0] = (op & 0xff);
197 case IDENTIFIER: return "IDENTIFIER";
198 case TYPE_NAME: return "TYPE_NAME";
199 case CONSTANT: return "CONSTANT";
200 case STRING_LITERAL: return "STRING_LITERAL";
201 case SIZEOF: return "SIZEOF";
202 case PTR_OP: return "PTR_OP";
203 case INC_OP: return "INC_OP";
204 case DEC_OP: return "DEC_OP";
205 case LEFT_OP: return "LEFT_OP";
206 case RIGHT_OP: return "RIGHT_OP";
207 case LE_OP: return "LE_OP";
208 case GE_OP: return "GE_OP";
209 case EQ_OP: return "EQ_OP";
210 case NE_OP: return "NE_OP";
211 case AND_OP: return "AND_OP";
212 case OR_OP: return "OR_OP";
213 case MUL_ASSIGN: return "MUL_ASSIGN";
214 case DIV_ASSIGN: return "DIV_ASSIGN";
215 case MOD_ASSIGN: return "MOD_ASSIGN";
216 case ADD_ASSIGN: return "ADD_ASSIGN";
217 case SUB_ASSIGN: return "SUB_ASSIGN";
218 case LEFT_ASSIGN: return "LEFT_ASSIGN";
219 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
220 case AND_ASSIGN: return "AND_ASSIGN";
221 case XOR_ASSIGN: return "XOR_ASSIGN";
222 case OR_ASSIGN: return "OR_ASSIGN";
223 case TYPEDEF: return "TYPEDEF";
224 case EXTERN: return "EXTERN";
225 case STATIC: return "STATIC";
226 case AUTO: return "AUTO";
227 case REGISTER: return "REGISTER";
228 case CODE: return "CODE";
229 case EEPROM: return "EEPROM";
230 case INTERRUPT: return "INTERRUPT";
231 case SFR: return "SFR";
232 case AT: return "AT";
233 case SBIT: return "SBIT";
234 case REENTRANT: return "REENTRANT";
235 case USING: return "USING";
236 case XDATA: return "XDATA";
237 case DATA: return "DATA";
238 case IDATA: return "IDATA";
239 case PDATA: return "PDATA";
240 case VAR_ARGS: return "VAR_ARGS";
241 case CRITICAL: return "CRITICAL";
242 case NONBANKED: return "NONBANKED";
243 case BANKED: return "BANKED";
244 case CHAR: return "CHAR";
245 case SHORT: return "SHORT";
246 case INT: return "INT";
247 case LONG: return "LONG";
248 case SIGNED: return "SIGNED";
249 case UNSIGNED: return "UNSIGNED";
250 case FLOAT: return "FLOAT";
251 case DOUBLE: return "DOUBLE";
252 case CONST: return "CONST";
253 case VOLATILE: return "VOLATILE";
254 case VOID: return "VOID";
255 case BIT: return "BIT";
256 case STRUCT: return "STRUCT";
257 case UNION: return "UNION";
258 case ENUM: return "ENUM";
259 case ELIPSIS: return "ELIPSIS";
260 case RANGE: return "RANGE";
261 case FAR: return "FAR";
262 case CASE: return "CASE";
263 case DEFAULT: return "DEFAULT";
264 case IF: return "IF";
265 case ELSE: return "ELSE";
266 case SWITCH: return "SWITCH";
267 case WHILE: return "WHILE";
268 case DO: return "DO";
269 case FOR: return "FOR";
270 case GOTO: return "GOTO";
271 case CONTINUE: return "CONTINUE";
272 case BREAK: return "BREAK";
273 case RETURN: return "RETURN";
274 case INLINEASM: return "INLINEASM";
275 case IFX: return "IFX";
276 case ADDRESS_OF: return "ADDRESS_OF";
277 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
278 case SPIL: return "SPIL";
279 case UNSPIL: return "UNSPIL";
280 case GETHBIT: return "GETHBIT";
281 case BITWISEAND: return "BITWISEAND";
282 case UNARYMINUS: return "UNARYMINUS";
283 case IPUSH: return "IPUSH";
284 case IPOP: return "IPOP";
285 case PCALL: return "PCALL";
286 case ENDFUNCTION: return "ENDFUNCTION";
287 case JUMPTABLE: return "JUMPTABLE";
288 case RRC: return "RRC";
289 case RLC: return "RLC";
290 case CAST: return "CAST";
291 case CALL: return "CALL";
292 case PARAM: return "PARAM ";
293 case NULLOP: return "NULLOP";
294 case BLOCK: return "BLOCK";
295 case LABEL: return "LABEL";
296 case RECEIVE: return "RECEIVE";
297 case SEND: return "SEND";
299 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
302 /*-----------------------------------------------------------------*/
303 /*-----------------------------------------------------------------*/
305 debugLogRegType (short type)
310 case REG_GPR: return "REG_GPR";
311 case REG_PTR: return "REG_PTR";
312 case REG_CND: return "REG_CND";
315 sprintf (buffer, "unknown reg type %d", type);
319 /*-----------------------------------------------------------------*/
320 /*-----------------------------------------------------------------*/
321 static int regname2key(char const *name)
330 key += (*name++) + 1;
334 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
338 static regs *regWithIdx (set *dRegs, int idx, int fixed);
339 /*-----------------------------------------------------------------*/
340 /* newReg - allocate and init memory for a new register */
341 /*-----------------------------------------------------------------*/
342 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
345 regs *dReg, *reg_alias;
347 /* check whether a matching register already exists */
348 dReg = dirregWithName( name );
350 //printf( "%s: already present: %s\n", __FUNCTION__, name );
354 // check whether a register at that location exists
355 reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
356 if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
358 // create a new register
359 dReg = Safe_calloc(1,sizeof(regs));
361 dReg->pc_type = pc_type;
364 dReg->name = Safe_strdup(name);
366 sprintf(buffer,"r0x%02X", dReg->rIdx);
367 dReg->name = Safe_strdup(buffer);
383 dReg->reg_alias = reg_alias;
384 dReg->reglives.usedpFlows = newSet();
385 dReg->reglives.assignedpFlows = newSet();
386 if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
387 debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
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 == (int)dReg->isFixed)) {
404 while (dReg->reg_alias) dReg = dReg->reg_alias;
412 /*-----------------------------------------------------------------*/
413 /* regWithName - Search through a set of registers that matches name */
414 /*-----------------------------------------------------------------*/
416 regWithName (set *dRegs, const char *name)
420 for (dReg = setFirstItem(dRegs) ; dReg ;
421 dReg = setNextItem(dRegs)) {
423 if((strcmp(name,dReg->name)==0)) {
431 /*-----------------------------------------------------------------*/
432 /* regWithName - Search for a registers that matches name */
433 /*-----------------------------------------------------------------*/
435 regFindWithName (const char *name)
439 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
440 debugLog ("Found a Direct Register!\n");
443 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
444 debugLog ("Found a Direct Bit Register!\n");
448 if (*name=='_') name++; // Step passed '_'
450 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
451 debugLog ("Found a Dynamic Register!\n");
454 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
455 debugLog ("Found a Processor Register!\n");
458 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
459 debugLog ("Found an Internal Register!\n");
462 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
463 debugLog ("Found an Stack Register!\n");
470 /*-----------------------------------------------------------------*/
471 /* regFindFree - Search for a free register in a set of registers */
472 /*-----------------------------------------------------------------*/
474 regFindFree (set *dRegs)
478 for (dReg = setFirstItem(dRegs) ; dReg ;
479 dReg = setNextItem(dRegs)) {
487 /*-----------------------------------------------------------------*/
488 /* initStack - allocate registers for a pseudo stack */
489 /*-----------------------------------------------------------------*/
490 void initStack(int base_address, int size)
495 Gstack_base_addr = base_address;
497 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
499 for(i = 0; i<size; i++) {
502 SNPRINTF(&buffer[0], 16, "STK%02d", i);
503 // Trying to use shared memory for pseudo stack
504 r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, 0x180);
505 r->isFixed = 0; // fixed location no longer required
509 addSet(&dynStackRegs,r);
513 /*-----------------------------------------------------------------*
514 *-----------------------------------------------------------------*/
516 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
519 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
520 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
523 /*-----------------------------------------------------------------*
524 *-----------------------------------------------------------------*/
527 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
529 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
531 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
534 return addSet(&dynInternalRegs,reg);
539 /*-----------------------------------------------------------------*/
540 /* allocReg - allocates register of given type */
541 /*-----------------------------------------------------------------*/
543 allocReg (short type)
547 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
548 //fprintf(stderr,"allocReg\n");
550 reg = pic14_findFreeReg (type);
558 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
563 /*-----------------------------------------------------------------*/
564 /* dirregWithName - search for register by name */
565 /*-----------------------------------------------------------------*/
567 dirregWithName (char *name)
575 /* hash the name to get a key */
577 hkey = regname2key(name);
579 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
583 if(STRCASECMP(reg->name, name) == 0) {
584 // handle registers with multiple names
585 while (reg->reg_alias) reg = reg->reg_alias;
589 reg = hTabNextItemWK (dynDirectRegNames);
593 return NULL; // name wasn't found in the hash table
596 int IS_CONFIG_ADDRESS(int address)
599 return ((address == 0x2007) || (address == 0x2008));
602 /*-----------------------------------------------------------------*/
603 /* allocNewDirReg - allocates a new register of given type */
604 /*-----------------------------------------------------------------*/
606 allocNewDirReg (sym_link *symlnk,const char *name)
610 sym_link *spec = getSpec (symlnk);
612 /* if this is at an absolute address, then get the address. */
613 if (SPEC_ABSA (spec) ) {
614 address = SPEC_ADDR (spec);
615 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
618 /* Register wasn't found in hash, so let's create
619 * a new one and put it in the hash table AND in the
620 * dynDirectRegNames set */
621 if (IS_CONFIG_ADDRESS(address)) {
622 debugLog (" -- %s is declared at address 0x2007\n",name);
627 if (IS_BITVAR (spec))
634 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
635 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
637 if (SPEC_ABSA (spec) ) {
641 if (IS_BITVAR (spec)) {
642 addSet(&dynDirectBitRegs, reg);
645 addSet(&dynDirectRegs, reg);
647 if (!IS_STATIC (spec)) {
650 if (IS_EXTERN (spec)) {
656 if (address && reg) {
658 reg->address = address;
659 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
665 /*-----------------------------------------------------------------*/
666 /* allocDirReg - allocates register of given type */
667 /*-----------------------------------------------------------------*/
669 allocDirReg (operand *op )
676 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
680 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
682 /* If the symbol is at a fixed address, then remove the leading underscore
683 * from the name. This is hack to allow the .asm include file named registers
684 * to match the .c declared register names */
686 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
689 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
691 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
692 debugLog(" %d const char\n",__LINE__);
693 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
696 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
697 if (IS_CODE ( OP_SYM_ETYPE(op)) )
698 debugLog(" %d code space\n",__LINE__);
700 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
701 debugLog(" %d integral\n",__LINE__);
702 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
703 debugLog(" %d literal\n",__LINE__);
704 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
705 debugLog(" %d specifier\n",__LINE__);
706 debugAopGet(NULL, op);
709 if (IS_CODE ( OP_SYM_ETYPE(op)) )
712 /* First, search the hash table to see if there is a register with this name */
713 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
714 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
717 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
718 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
720 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
721 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
724 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
726 reg = dirregWithName(name);
733 /* if this is at an absolute address, then get the address. */
734 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
735 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
736 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
739 /* Register wasn't found in hash, so let's create
740 * a new one and put it in the hash table AND in the
741 * dynDirectRegNames set */
742 if(!IS_CONFIG_ADDRESS(address)) {
743 //fprintf(stderr,"allocating new reg %s\n",name);
745 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
746 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
748 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
750 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
752 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
756 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
757 addSet(&dynDirectBitRegs, reg);
760 addSet(&dynDirectRegs, reg);
762 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
765 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
771 debugLog (" -- %s is declared at address 0x2007\n",name);
776 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
778 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
779 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
784 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
786 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
787 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
790 allocNewDirReg (OP_SYM_TYPE(op),name);
797 /*-----------------------------------------------------------------*/
798 /* allocRegByName - allocates register with given name */
799 /*-----------------------------------------------------------------*/
801 allocRegByName (char *name, int size)
807 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
811 /* First, search the hash table to see if there is a register with this name */
812 reg = dirregWithName(name);
818 /* Register wasn't found in hash, so let's create
819 * a new one and put it in the hash table AND in the
820 * dynDirectRegNames set */
821 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
822 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
823 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
824 if (strcmp(reg->name+1,sym->name)==0) {
825 unsigned a = SPEC_ADDR(sym->etype);
829 if (!IS_STATIC (sym->etype)) {
832 if (IS_EXTERN (sym->etype)) {
835 if (IS_BITVAR (sym->etype))
842 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
843 if (strcmp(reg->name+1,sym->name)==0) {
844 unsigned a = SPEC_ADDR(sym->etype);
846 if (!IS_STATIC (sym->etype)) {
849 if (IS_EXTERN (sym->etype)) {
852 if (IS_BITVAR (sym->etype))
860 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
862 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
863 if (reg->isBitField) {
864 addSet(&dynDirectBitRegs, reg);
866 addSet(&dynDirectRegs, reg);
872 /*-----------------------------------------------------------------*/
873 /* RegWithIdx - returns pointer to register with index number */
874 /*-----------------------------------------------------------------*/
876 typeRegWithIdx (int idx, int type, int fixed)
881 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
886 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
888 debugLog ("Found a Dynamic Register!\n");
891 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
892 debugLog ("Found a Direct Register!\n");
898 if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
899 debugLog ("Found a Stack Register!\n");
903 werror (E_STACK_OUT, "Register");
904 /* return an existing register just to avoid the SDCC crash */
905 return regWithIdx ( dynStackRegs, 0x7f, 0);
909 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
910 debugLog ("Found a Processor Register!\n");
924 /*-----------------------------------------------------------------*/
925 /* pic14_regWithIdx - returns pointer to register with index number*/
926 /*-----------------------------------------------------------------*/
928 pic14_regWithIdx (int idx)
932 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
935 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
941 /*-----------------------------------------------------------------*/
942 /* pic14_regWithIdx - returns pointer to register with index number */
943 /*-----------------------------------------------------------------*/
945 pic14_allocWithIdx (int idx)
950 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
952 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
954 debugLog ("Found a Dynamic Register!\n");
955 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
956 debugLog ("Found a Stack Register!\n");
957 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
958 debugLog ("Found a Processor Register!\n");
959 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
960 debugLog ("Found an Internal Register!\n");
961 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
962 debugLog ("Found an Internal Register!\n");
965 debugLog ("Dynamic Register not found\n");
968 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
969 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
970 "regWithIdx not found");
980 /*-----------------------------------------------------------------*/
981 /*-----------------------------------------------------------------*/
983 pic14_findFreeReg(short type)
990 if((dReg = regFindFree(dynAllocRegs)) != NULL)
992 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
996 if((dReg = regFindFree(dynStackRegs)) != NULL)
1008 /*-----------------------------------------------------------------*/
1009 /* freeReg - frees a register */
1010 /*-----------------------------------------------------------------*/
1012 freeReg (regs * reg)
1014 debugLog ("%s\n", __FUNCTION__);
1019 /*-----------------------------------------------------------------*/
1020 /* nFreeRegs - returns number of free registers */
1021 /*-----------------------------------------------------------------*/
1023 nFreeRegs (int type)
1025 /* dynamically allocate as many as we need and worry about
1026 * fitting them into a PIC later */
1033 debugLog ("%s\n", __FUNCTION__);
1034 for (i = 0; i < pic14_nRegs; i++)
1035 if (regspic14[i].isFree && regspic14[i].type == type)
1041 /*-----------------------------------------------------------------*/
1042 /* nfreeRegsType - free registers with type */
1043 /*-----------------------------------------------------------------*/
1045 nfreeRegsType (int type)
1048 debugLog ("%s\n", __FUNCTION__);
1049 if (type == REG_PTR)
1051 if ((nfr = nFreeRegs (type)) == 0)
1052 return nFreeRegs (REG_GPR);
1055 return nFreeRegs (type);
1058 void writeSetUsedRegs(FILE *of, set *dRegs)
1063 for (dReg = setFirstItem(dRegs) ; dReg ;
1064 dReg = setNextItem(dRegs)) {
1067 fprintf (of, "\t%s\n",dReg->name);
1071 extern void assignFixedRegisters(set *regset);
1072 extern void assignRelocatableRegisters(set *regset,int used);
1073 extern void dump_map(void);
1074 extern void dump_sfr(FILE *of);
1076 void packBits(set *bregs)
1080 regs *bitfield=NULL;
1081 regs *relocbitfield=NULL;
1087 for (regset = bregs ; regset ;
1088 regset = regset->next) {
1090 breg = regset->item;
1091 breg->isBitField = 1;
1092 //fprintf(stderr,"bit reg: %s\n",breg->name);
1095 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1097 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1098 breg->rIdx = breg->address & 7;
1099 breg->address >>= 3;
1102 //sprintf (buffer, "fbitfield%02x", breg->address);
1103 sprintf (buffer, "0x%02x", breg->address);
1104 //fprintf(stderr,"new bit field\n");
1105 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1106 bitfield->isBitField = 1;
1107 bitfield->isFixed = 1;
1108 bitfield->address = breg->address;
1109 //addSet(&dynDirectRegs,bitfield);
1110 addSet(&dynInternalRegs,bitfield);
1111 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1113 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1116 breg->reg_alias = bitfield;
1120 if(!relocbitfield || bit_no >7) {
1123 sprintf (buffer, "bitfield%d", byte_no);
1124 //fprintf(stderr,"new relocatable bit field\n");
1125 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
1126 relocbitfield->isBitField = 1;
1127 //addSet(&dynDirectRegs,relocbitfield);
1128 addSet(&dynInternalRegs,relocbitfield);
1129 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1133 breg->reg_alias = relocbitfield;
1134 breg->address = dynrIdx; /* byte_no; */
1135 breg->rIdx = bit_no++;
1143 void bitEQUs(FILE *of, set *bregs)
1145 regs *breg,*bytereg;
1148 //fprintf(stderr," %s\n",__FUNCTION__);
1149 for (breg = setFirstItem(bregs) ; breg ;
1150 breg = setNextItem(bregs)) {
1152 //fprintf(stderr,"bit reg: %s\n",breg->name);
1154 bytereg = breg->reg_alias;
1156 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1159 breg->rIdx & 0x0007);
1162 //fprintf(stderr, "bit field is not assigned to a register\n");
1163 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1173 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1178 for (reg = setFirstItem(fregs) ; reg ;
1179 reg = setNextItem(fregs)) {
1181 //if(!reg->isEmitted && reg->wasUsed) {
1184 fprintf (of, "%s\tEQU\t0x%03x\n",
1188 fprintf (of, "%s\tEQU\t0x%03x\n",
1196 void writeUsedRegs(FILE *of)
1198 packBits(dynDirectBitRegs);
1200 assignFixedRegisters(dynInternalRegs);
1201 assignFixedRegisters(dynAllocRegs);
1202 assignFixedRegisters(dynStackRegs);
1203 assignFixedRegisters(dynDirectRegs);
1205 assignRelocatableRegisters(dynInternalRegs,0);
1206 assignRelocatableRegisters(dynAllocRegs,0);
1207 assignRelocatableRegisters(dynStackRegs,0);
1209 assignRelocatableRegisters(dynDirectRegs,0);
1211 assignRelocatableRegisters(dynDirectRegs,0);
1212 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1217 bitEQUs(of,dynDirectBitRegs);
1219 aliasEQUs(of,dynAllocRegs,0);
1220 aliasEQUs(of,dynDirectRegs,0);
1221 aliasEQUs(of,dynStackRegs,0);
1222 aliasEQUs(of,dynProcessorRegs,1);
1227 /*-----------------------------------------------------------------*/
1228 /* allDefsOutOfRange - all definitions are out of a range */
1229 /*-----------------------------------------------------------------*/
1231 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1235 debugLog ("%s\n", __FUNCTION__);
1239 for (i = 0; i < defs->size; i++)
1243 if (bitVectBitValue (defs, i) &&
1244 (ic = hTabItemWithKey (iCodehTab, i)) &&
1245 (ic->seq >= fseq && ic->seq <= toseq))
1255 /*-----------------------------------------------------------------*/
1256 /* computeSpillable - given a point find the spillable live ranges */
1257 /*-----------------------------------------------------------------*/
1259 computeSpillable (iCode * ic)
1263 debugLog ("%s\n", __FUNCTION__);
1264 /* spillable live ranges are those that are live at this
1265 point . the following categories need to be subtracted
1267 a) - those that are already spilt
1268 b) - if being used by this one
1269 c) - defined by this one */
1271 spillable = bitVectCopy (ic->rlive);
1273 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1275 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1276 bitVectUnSetBit (spillable, ic->defKey);
1277 spillable = bitVectIntersect (spillable, _G.regAssigned);
1282 /*-----------------------------------------------------------------*/
1283 /* noSpilLoc - return true if a variable has no spil location */
1284 /*-----------------------------------------------------------------*/
1286 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1288 debugLog ("%s\n", __FUNCTION__);
1289 return (sym->usl.spillLoc ? 0 : 1);
1292 /*-----------------------------------------------------------------*/
1293 /* hasSpilLoc - will return 1 if the symbol has spil location */
1294 /*-----------------------------------------------------------------*/
1296 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1298 debugLog ("%s\n", __FUNCTION__);
1299 return (sym->usl.spillLoc ? 1 : 0);
1302 /*-----------------------------------------------------------------*/
1303 /* directSpilLoc - will return 1 if the splilocation is in direct */
1304 /*-----------------------------------------------------------------*/
1306 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1308 debugLog ("%s\n", __FUNCTION__);
1309 if (sym->usl.spillLoc &&
1310 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1316 /*-----------------------------------------------------------------*/
1317 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1318 /* but is not used as a pointer */
1319 /*-----------------------------------------------------------------*/
1321 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1323 debugLog ("%s\n", __FUNCTION__);
1324 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1327 /*-----------------------------------------------------------------*/
1328 /* rematable - will return 1 if the remat flag is set */
1329 /*-----------------------------------------------------------------*/
1331 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1333 debugLog ("%s\n", __FUNCTION__);
1337 /*-----------------------------------------------------------------*/
1338 /* notUsedInRemaining - not used or defined in remain of the block */
1339 /*-----------------------------------------------------------------*/
1341 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1343 debugLog ("%s\n", __FUNCTION__);
1344 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1345 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1348 /*-----------------------------------------------------------------*/
1349 /* allLRs - return true for all */
1350 /*-----------------------------------------------------------------*/
1352 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1354 debugLog ("%s\n", __FUNCTION__);
1358 /*-----------------------------------------------------------------*/
1359 /* liveRangesWith - applies function to a given set of live range */
1360 /*-----------------------------------------------------------------*/
1362 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1363 eBBlock * ebp, iCode * ic)
1368 debugLog ("%s\n", __FUNCTION__);
1369 if (!lrs || !lrs->size)
1372 for (i = 1; i < lrs->size; i++)
1375 if (!bitVectBitValue (lrs, i))
1378 /* if we don't find it in the live range
1379 hash table we are in serious trouble */
1380 if (!(sym = hTabItemWithKey (liveRanges, i)))
1382 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1383 "liveRangesWith could not find liveRange");
1387 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1388 addSetHead (&rset, sym);
1395 /*-----------------------------------------------------------------*/
1396 /* leastUsedLR - given a set determines which is the least used */
1397 /*-----------------------------------------------------------------*/
1399 leastUsedLR (set * sset)
1401 symbol *sym = NULL, *lsym = NULL;
1403 debugLog ("%s\n", __FUNCTION__);
1404 sym = lsym = setFirstItem (sset);
1409 for (; lsym; lsym = setNextItem (sset))
1412 /* if usage is the same then prefer
1413 the spill the smaller of the two */
1414 if (lsym->used == sym->used)
1415 if (getSize (lsym->type) < getSize (sym->type))
1419 if (lsym->used < sym->used)
1424 setToNull ((void *) &sset);
1429 /*-----------------------------------------------------------------*/
1430 /* noOverLap - will iterate through the list looking for over lap */
1431 /*-----------------------------------------------------------------*/
1433 noOverLap (set * itmpStack, symbol * fsym)
1436 debugLog ("%s\n", __FUNCTION__);
1439 for (sym = setFirstItem (itmpStack); sym;
1440 sym = setNextItem (itmpStack))
1442 if (sym->liveTo > fsym->liveFrom)
1450 /*-----------------------------------------------------------------*/
1451 /* isFree - will return 1 if the a free spil location is found */
1452 /*-----------------------------------------------------------------*/
1457 V_ARG (symbol **, sloc);
1458 V_ARG (symbol *, fsym);
1460 debugLog ("%s\n", __FUNCTION__);
1461 /* if already found */
1465 /* if it is free && and the itmp assigned to
1466 this does not have any overlapping live ranges
1467 with the one currently being assigned and
1468 the size can be accomodated */
1470 noOverLap (sym->usl.itmpStack, fsym) &&
1471 getSize (sym->type) >= getSize (fsym->type))
1480 /*-----------------------------------------------------------------*/
1481 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1482 /*-----------------------------------------------------------------*/
1484 spillLRWithPtrReg (symbol * forSym)
1490 debugLog ("%s\n", __FUNCTION__);
1491 if (!_G.regAssigned ||
1492 bitVectIsZero (_G.regAssigned))
1495 r0 = pic14_regWithIdx (R0_IDX);
1496 r1 = pic14_regWithIdx (R1_IDX);
1498 /* for all live ranges */
1499 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1500 lrsym = hTabNextItem (liveRanges, &k))
1504 /* if no registers assigned to it or
1506 /* if it does not overlap with this then
1507 not need to spill it */
1509 if (lrsym->isspilt || !lrsym->nRegs ||
1510 (lrsym->liveTo < forSym->liveFrom))
1513 /* go thru the registers : if it is either
1514 r0 or r1 then spil it */
1515 for (j = 0; j < lrsym->nRegs; j++)
1516 if (lrsym->regs[j] == r0 ||
1517 lrsym->regs[j] == r1)
1526 /*-----------------------------------------------------------------*/
1527 /* createStackSpil - create a location on the stack to spil */
1528 /*-----------------------------------------------------------------*/
1530 createStackSpil (symbol * sym)
1532 symbol *sloc = NULL;
1533 int useXstack, model, noOverlay;
1535 char slocBuffer[30];
1536 debugLog ("%s\n", __FUNCTION__);
1540 /* first go try and find a free one that is already
1541 existing on the stack */
1542 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1544 /* found a free one : just update & return */
1545 sym->usl.spillLoc = sloc;
1548 addSetHead (&sloc->usl.itmpStack, sym);
1552 /* could not then have to create one , this is the hard part
1553 we need to allocate this on the stack : this is really a
1554 hack!! but cannot think of anything better at this time */
1556 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1558 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1559 __FILE__, __LINE__);
1563 sloc = newiTemp (slocBuffer);
1565 /* set the type to the spilling symbol */
1566 sloc->type = copyLinkChain (sym->type);
1567 sloc->etype = getSpec (sloc->type);
1568 SPEC_SCLS (sloc->etype) = S_DATA;
1569 SPEC_EXTR (sloc->etype) = 0;
1570 SPEC_STAT (sloc->etype) = 0;
1572 /* we don't allow it to be allocated`
1573 onto the external stack since : so we
1574 temporarily turn it off ; we also
1575 turn off memory model to prevent
1576 the spil from going to the external storage
1577 and turn off overlaying
1580 useXstack = options.useXstack;
1581 model = options.model;
1582 noOverlay = options.noOverlay;
1583 options.noOverlay = 1;
1584 options.model = options.useXstack = 0;
1588 options.useXstack = useXstack;
1589 options.model = model;
1590 options.noOverlay = noOverlay;
1591 sloc->isref = 1; /* to prevent compiler warning */
1593 /* if it is on the stack then update the stack */
1594 if (IN_STACK (sloc->etype))
1596 currFunc->stack += getSize (sloc->type);
1597 _G.stackExtend += getSize (sloc->type);
1600 _G.dataExtend += getSize (sloc->type);
1602 /* add it to the _G.stackSpil set */
1603 addSetHead (&_G.stackSpil, sloc);
1604 sym->usl.spillLoc = sloc;
1607 /* add it to the set of itempStack set
1608 of the spill location */
1609 addSetHead (&sloc->usl.itmpStack, sym);
1613 /*-----------------------------------------------------------------*/
1614 /* isSpiltOnStack - returns true if the spil location is on stack */
1615 /*-----------------------------------------------------------------*/
1617 isSpiltOnStack (symbol * sym)
1621 debugLog ("%s\n", __FUNCTION__);
1630 /* if (sym->_G.stackSpil) */
1633 if (!sym->usl.spillLoc)
1636 etype = getSpec (sym->usl.spillLoc->type);
1637 if (IN_STACK (etype))
1643 /*-----------------------------------------------------------------*/
1644 /* spillThis - spils a specific operand */
1645 /*-----------------------------------------------------------------*/
1647 spillThis (symbol * sym)
1650 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1651 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1653 /* if this is rematerializable or has a spillLocation
1654 we are okay, else we need to create a spillLocation
1656 if (!(sym->remat || sym->usl.spillLoc))
1657 createStackSpil (sym);
1660 /* mark it has spilt & put it in the spilt set */
1662 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1664 bitVectUnSetBit (_G.regAssigned, sym->key);
1666 for (i = 0; i < sym->nRegs; i++)
1670 freeReg (sym->regs[i]);
1671 sym->regs[i] = NULL;
1675 /* if spilt on stack then free up r0 & r1
1676 if they could have been assigned to some
1678 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1681 spillLRWithPtrReg (sym);
1684 if (sym->usl.spillLoc && !sym->remat)
1685 sym->usl.spillLoc->allocreq = 1;
1690 /*-----------------------------------------------------------------*/
1691 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1692 /*-----------------------------------------------------------------*/
1694 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1696 bitVect *lrcs = NULL;
1700 debugLog ("%s\n", __FUNCTION__);
1702 /* get the spillable live ranges */
1703 lrcs = computeSpillable (ic);
1706 /* get all live ranges that are rematerizable */
1707 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1709 /* return the least used of these */
1710 return leastUsedLR (selectS);
1713 /* get live ranges with spillLocations in direct space */
1714 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1716 sym = leastUsedLR (selectS);
1717 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1718 sym->usl.spillLoc->rname :
1719 sym->usl.spillLoc->name));
1721 /* mark it as allocation required */
1722 sym->usl.spillLoc->allocreq = 1;
1726 /* if the symbol is local to the block then */
1727 if (forSym->liveTo < ebp->lSeq)
1730 /* check if there are any live ranges allocated
1731 to registers that are not used in this block */
1732 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1734 sym = leastUsedLR (selectS);
1735 /* if this is not rematerializable */
1744 /* check if there are any live ranges that not
1745 used in the remainder of the block */
1746 if (!_G.blockSpil &&
1747 !isiCodeInFunctionCall (ic) &&
1748 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1750 sym = leastUsedLR (selectS);
1753 sym->remainSpil = 1;
1760 /* find live ranges with spillocation && not used as pointers */
1761 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1764 sym = leastUsedLR (selectS);
1765 /* mark this as allocation required */
1766 sym->usl.spillLoc->allocreq = 1;
1770 /* find live ranges with spillocation */
1771 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1774 sym = leastUsedLR (selectS);
1775 sym->usl.spillLoc->allocreq = 1;
1779 /* couldn't find then we need to create a spil
1780 location on the stack , for which one? the least
1782 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1785 /* return a created spil location */
1786 sym = createStackSpil (leastUsedLR (selectS));
1787 sym->usl.spillLoc->allocreq = 1;
1791 /* this is an extreme situation we will spill
1792 this one : happens very rarely but it does happen */
1798 /*-----------------------------------------------------------------*/
1799 /* spilSomething - spil some variable & mark registers as free */
1800 /*-----------------------------------------------------------------*/
1802 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1807 debugLog ("%s\n", __FUNCTION__);
1808 /* get something we can spil */
1809 ssym = selectSpil (ic, ebp, forSym);
1811 /* mark it as spilt */
1813 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1815 /* mark it as not register assigned &
1816 take it away from the set */
1817 bitVectUnSetBit (_G.regAssigned, ssym->key);
1819 /* mark the registers as free */
1820 for (i = 0; i < ssym->nRegs; i++)
1822 freeReg (ssym->regs[i]);
1824 /* if spilt on stack then free up r0 & r1
1825 if they could have been assigned to as gprs */
1826 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1829 spillLRWithPtrReg (ssym);
1832 /* if this was a block level spil then insert push & pop
1833 at the start & end of block respectively */
1834 if (ssym->blockSpil)
1836 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1837 /* add push to the start of the block */
1838 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1839 ebp->sch->next : ebp->sch));
1840 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1841 /* add pop to the end of the block */
1842 addiCodeToeBBlock (ebp, nic, NULL);
1845 /* if spilt because not used in the remainder of the
1846 block then add a push before this instruction and
1847 a pop at the end of the block */
1848 if (ssym->remainSpil)
1851 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1852 /* add push just before this instruction */
1853 addiCodeToeBBlock (ebp, nic, ic);
1855 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1856 /* add pop to the end of the block */
1857 addiCodeToeBBlock (ebp, nic, NULL);
1866 /*-----------------------------------------------------------------*/
1867 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1868 /*-----------------------------------------------------------------*/
1870 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1875 debugLog ("%s\n", __FUNCTION__);
1877 /* try for a ptr type */
1878 if ((reg = allocReg (REG_PTR)))
1881 /* try for gpr type */
1882 if ((reg = allocReg (REG_GPR)))
1885 /* we have to spil */
1886 if (!spilSomething (ic, ebp, sym))
1889 /* make sure partially assigned registers aren't reused */
1890 for (j=0; j<=sym->nRegs; j++)
1892 sym->regs[j]->isFree = 0;
1894 /* this looks like an infinite loop but
1895 in really selectSpil will abort */
1899 /*-----------------------------------------------------------------*/
1900 /* getRegGpr - will try for GPR if not spil */
1901 /*-----------------------------------------------------------------*/
1903 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1908 debugLog ("%s\n", __FUNCTION__);
1910 /* try for gpr type */
1911 if ((reg = allocReg (REG_GPR)))
1914 if (!pic14_ptrRegReq)
1915 if ((reg = allocReg (REG_PTR)))
1918 /* we have to spil */
1919 if (!spilSomething (ic, ebp, sym))
1922 /* make sure partially assigned registers aren't reused */
1923 for (j=0; j<=sym->nRegs; j++)
1925 sym->regs[j]->isFree = 0;
1927 /* this looks like an infinite loop but
1928 in really selectSpil will abort */
1932 /*-----------------------------------------------------------------*/
1933 /* symHasReg - symbol has a given register */
1934 /*-----------------------------------------------------------------*/
1936 symHasReg (symbol * sym, regs * reg)
1940 debugLog ("%s\n", __FUNCTION__);
1941 for (i = 0; i < sym->nRegs; i++)
1942 if (sym->regs[i] == reg)
1948 /*-----------------------------------------------------------------*/
1949 /* deassignLRs - check the live to and if they have registers & are */
1950 /* not spilt then free up the registers */
1951 /*-----------------------------------------------------------------*/
1953 deassignLRs (iCode * ic, eBBlock * ebp)
1959 debugLog ("%s\n", __FUNCTION__);
1960 for (sym = hTabFirstItem (liveRanges, &k); sym;
1961 sym = hTabNextItem (liveRanges, &k))
1964 symbol *psym = NULL;
1965 /* if it does not end here */
1966 if (sym->liveTo > ic->seq)
1969 /* Prevent the result from being assigned the same registers as (one)
1970 * operand as many genXXX-functions fail otherwise.
1971 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1972 * are known to fail. */
1973 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1977 case '=': /* assignment */
1978 case BITWISEAND: /* bitwise AND */
1979 case '|': /* bitwise OR */
1980 case '^': /* bitwise XOR */
1981 case '~': /* bitwise negate */
1982 case RLC: /* rotate through carry */
1985 case '+': /* addition */
1986 case '-': /* subtraction */
1987 /* go ahead, these are safe to use with
1988 * non-disjoint register sets */
1992 /* do not release operand registers */
1993 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1998 /* if it was spilt on stack then we can
1999 mark the stack spil location as free */
2004 sym->usl.spillLoc->isFree = 1;
2010 if (!bitVectBitValue (_G.regAssigned, sym->key))
2012 /* special case check if this is an IFX &
2013 the privious one was a pop and the
2014 previous one was not spilt then keep track
2016 if (ic->op == IFX && ic->prev &&
2017 ic->prev->op == IPOP &&
2018 !ic->prev->parmPush &&
2019 IS_SYMOP(IC_LEFT (ic->prev)) &&
2020 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2021 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2027 bitVectUnSetBit (_G.regAssigned, sym->key);
2029 /* if the result of this one needs registers
2030 and does not have it then assign it right
2032 if (IC_RESULT (ic) &&
2033 !(SKIP_IC2 (ic) || /* not a special icode */
2034 ic->op == JUMPTABLE ||
2039 POINTER_SET (ic)) &&
2040 IS_SYMOP (IC_RESULT (ic)) &&
2041 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2042 result->liveTo > ic->seq && /* and will live beyond this */
2043 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2044 result->liveFrom == ic->seq && /* does not start before here */
2045 result->regType == sym->regType && /* same register types */
2046 result->regType == sym->regType && /* same register types */
2047 result->nRegs && /* which needs registers */
2048 !result->isspilt && /* and does not already have them */
2050 !bitVectBitValue (_G.regAssigned, result->key) &&
2051 /* the number of free regs + number of regs in this LR
2052 can accomodate the what result Needs */
2053 ((nfreeRegsType (result->regType) +
2054 sym->nRegs) >= result->nRegs)
2058 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2060 result->regs[i] = sym->regs[i];
2062 result->regs[i] = getRegGpr (ic, ebp, result);
2064 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2068 /* free the remaining */
2069 for (; i < sym->nRegs; i++)
2073 if (!symHasReg (psym, sym->regs[i]))
2074 freeReg (sym->regs[i]);
2077 freeReg (sym->regs[i]);
2084 /*-----------------------------------------------------------------*/
2085 /* reassignLR - reassign this to registers */
2086 /*-----------------------------------------------------------------*/
2088 reassignLR (operand * op)
2090 symbol *sym = OP_SYMBOL (op);
2093 debugLog ("%s\n", __FUNCTION__);
2094 /* not spilt any more */
2095 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2096 bitVectUnSetBit (_G.spiltSet, sym->key);
2098 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2102 for (i = 0; i < sym->nRegs; i++)
2103 sym->regs[i]->isFree = 0;
2106 /*-----------------------------------------------------------------*/
2107 /* willCauseSpill - determines if allocating will cause a spill */
2108 /*-----------------------------------------------------------------*/
2110 willCauseSpill (int nr, int rt)
2112 debugLog ("%s\n", __FUNCTION__);
2113 /* first check if there are any avlb registers
2114 of te type required */
2117 /* special case for pointer type
2118 if pointer type not avlb then
2119 check for type gpr */
2120 if (nFreeRegs (rt) >= nr)
2122 if (nFreeRegs (REG_GPR) >= nr)
2127 if (pic14_ptrRegReq)
2129 if (nFreeRegs (rt) >= nr)
2134 if (nFreeRegs (REG_PTR) +
2135 nFreeRegs (REG_GPR) >= nr)
2140 debugLog (" ... yep it will (cause a spill)\n");
2141 /* it will cause a spil */
2145 /*-----------------------------------------------------------------*/
2146 /* positionRegs - the allocator can allocate same registers to res- */
2147 /* ult and operand, if this happens make sure they are in the same */
2148 /* position as the operand otherwise chaos results */
2149 /*-----------------------------------------------------------------*/
2151 positionRegs (symbol * result, symbol * opsym, int lineno)
2153 int count = min (result->nRegs, opsym->nRegs);
2154 int i, j = 0, shared = 0;
2156 debugLog ("%s\n", __FUNCTION__);
2157 /* if the result has been spilt then cannot share */
2162 /* first make sure that they actually share */
2163 for (i = 0; i < count; i++)
2165 for (j = 0; j < count; j++)
2167 if (result->regs[i] == opsym->regs[j] && i != j)
2177 regs *tmp = result->regs[i];
2178 result->regs[i] = result->regs[j];
2179 result->regs[j] = tmp;
2184 /*------------------------------------------------------------------*/
2185 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2186 /* it should either have registers or have beed spilled. Otherwise, */
2187 /* there was an uninitialized variable, so just spill this to get */
2188 /* the operand in a valid state. */
2189 /*------------------------------------------------------------------*/
2191 verifyRegsAssigned (operand *op, iCode * ic)
2196 if (!IS_ITEMP (op)) return;
2198 sym = OP_SYMBOL (op);
2199 if (sym->isspilt) return;
2200 if (!sym->nRegs) return;
2201 if (sym->regs[0]) return;
2203 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2204 sym->prereqv ? sym->prereqv->name : sym->name);
2209 /*-----------------------------------------------------------------*/
2210 /* serialRegAssign - serially allocate registers to the variables */
2211 /*-----------------------------------------------------------------*/
2213 serialRegAssign (eBBlock ** ebbs, int count)
2217 debugLog ("%s\n", __FUNCTION__);
2218 /* for all blocks */
2219 for (i = 0; i < count; i++)
2224 if (ebbs[i]->noPath &&
2225 (ebbs[i]->entryLabel != entryLabel &&
2226 ebbs[i]->entryLabel != returnLabel))
2229 /* of all instructions do */
2230 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2232 debugLog (" op: %s\n", decodeOp (ic->op));
2234 /* if this is an ipop that means some live
2235 range will have to be assigned again */
2237 reassignLR (IC_LEFT (ic));
2239 /* if result is present && is a true symbol */
2240 if (IC_RESULT (ic) && ic->op != IFX &&
2241 IS_TRUE_SYMOP (IC_RESULT (ic)))
2242 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2244 /* take away registers from live
2245 ranges that end at this instruction */
2246 deassignLRs (ic, ebbs[i]);
2248 /* some don't need registers */
2249 if (SKIP_IC2 (ic) ||
2250 ic->op == JUMPTABLE ||
2254 (IC_RESULT (ic) && POINTER_SET (ic)))
2257 /* now we need to allocate registers
2258 only for the result */
2259 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2261 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2267 /* Make sure any spill location is definately allocated */
2268 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2269 !sym->usl.spillLoc->allocreq)
2271 sym->usl.spillLoc->allocreq++;
2274 /* if it does not need or is spilt
2275 or is already assigned to registers
2276 or will not live beyond this instructions */
2279 bitVectBitValue (_G.regAssigned, sym->key) ||
2280 sym->liveTo <= ic->seq)
2283 /* if some liverange has been spilt at the block level
2284 and this one live beyond this block then spil this
2286 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2291 /* if trying to allocate this will cause
2292 a spill and there is nothing to spill
2293 or this one is rematerializable then
2295 willCS = willCauseSpill (sym->nRegs, sym->regType);
2296 spillable = computeSpillable (ic);
2298 (willCS && bitVectIsZero (spillable)))
2306 /* If the live range preceeds the point of definition
2307 then ideally we must take into account registers that
2308 have been allocated after sym->liveFrom but freed
2309 before ic->seq. This is complicated, so spill this
2310 symbol instead and let fillGaps handle the allocation. */
2311 if (sym->liveFrom < ic->seq)
2317 /* if it has a spillocation & is used less than
2318 all other live ranges then spill this */
2320 if (sym->usl.spillLoc) {
2321 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2322 allLRs, ebbs[i], ic));
2323 if (leastUsed && leastUsed->used > sym->used) {
2328 /* if none of the liveRanges have a spillLocation then better
2329 to spill this one than anything else already assigned to registers */
2330 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2331 /* if this is local to this block then we might find a block spil */
2332 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2340 if (ic->op == RECEIVE)
2341 debugLog ("When I get clever, I'll optimize the receive logic\n");
2343 /* if we need ptr regs for the right side
2345 if (POINTER_GET (ic)
2346 && IS_SYMOP(IC_LEFT(ic))
2347 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2348 <= (unsigned) PTRSIZE)
2353 /* else we assign registers to it */
2354 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2356 debugLog (" %d - \n", __LINE__);
2358 bitVectDebugOn(_G.regAssigned, debugF);
2359 for (j = 0; j < sym->nRegs; j++)
2361 if (sym->regType == REG_PTR)
2362 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2364 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2366 /* if the allocation failed which means
2367 this was spilt then break */
2371 debugLog (" %d - \n", __LINE__);
2373 /* if it shares registers with operands make sure
2374 that they are in the same position */
2375 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2376 IS_SYMOP(IC_RESULT(ic)) &&
2377 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2378 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2379 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2380 /* do the same for the right operand */
2381 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2382 IS_SYMOP(IC_RESULT(ic)) &&
2383 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2384 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2385 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2387 debugLog (" %d - \n", __LINE__);
2390 debugLog (" %d - \n", __LINE__);
2399 /* Check for and fix any problems with uninitialized operands */
2400 for (i = 0; i < count; i++)
2404 if (ebbs[i]->noPath &&
2405 (ebbs[i]->entryLabel != entryLabel &&
2406 ebbs[i]->entryLabel != returnLabel))
2409 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2416 verifyRegsAssigned (IC_COND (ic), ic);
2420 if (ic->op == JUMPTABLE)
2422 verifyRegsAssigned (IC_JTCOND (ic), ic);
2426 verifyRegsAssigned (IC_RESULT (ic), ic);
2427 verifyRegsAssigned (IC_LEFT (ic), ic);
2428 verifyRegsAssigned (IC_RIGHT (ic), ic);
2434 /*-----------------------------------------------------------------*/
2435 /* rUmaskForOp :- returns register mask for an operand */
2436 /*-----------------------------------------------------------------*/
2438 rUmaskForOp (operand * op)
2444 debugLog ("%s\n", __FUNCTION__);
2445 /* only temporaries are assigned registers */
2449 sym = OP_SYMBOL (op);
2451 /* if spilt or no registers assigned to it
2453 if (sym->isspilt || !sym->nRegs)
2456 rumask = newBitVect (pic14_nRegs);
2458 for (j = 0; j < sym->nRegs; j++)
2460 rumask = bitVectSetBit (rumask,
2461 sym->regs[j]->rIdx);
2467 /*-----------------------------------------------------------------*/
2468 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2469 /*-----------------------------------------------------------------*/
2471 regsUsedIniCode (iCode * ic)
2473 bitVect *rmask = newBitVect (pic14_nRegs);
2475 debugLog ("%s\n", __FUNCTION__);
2476 /* do the special cases first */
2479 rmask = bitVectUnion (rmask,
2480 rUmaskForOp (IC_COND (ic)));
2484 /* for the jumptable */
2485 if (ic->op == JUMPTABLE)
2487 rmask = bitVectUnion (rmask,
2488 rUmaskForOp (IC_JTCOND (ic)));
2493 /* of all other cases */
2495 rmask = bitVectUnion (rmask,
2496 rUmaskForOp (IC_LEFT (ic)));
2500 rmask = bitVectUnion (rmask,
2501 rUmaskForOp (IC_RIGHT (ic)));
2504 rmask = bitVectUnion (rmask,
2505 rUmaskForOp (IC_RESULT (ic)));
2511 /*-----------------------------------------------------------------*/
2512 /* createRegMask - for each instruction will determine the regsUsed */
2513 /*-----------------------------------------------------------------*/
2515 createRegMask (eBBlock ** ebbs, int count)
2519 debugLog ("%s\n", __FUNCTION__);
2520 /* for all blocks */
2521 for (i = 0; i < count; i++)
2525 if (ebbs[i]->noPath &&
2526 (ebbs[i]->entryLabel != entryLabel &&
2527 ebbs[i]->entryLabel != returnLabel))
2530 /* for all instructions */
2531 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2536 if (SKIP_IC2 (ic) || !ic->rlive)
2539 /* first mark the registers used in this
2541 ic->rUsed = regsUsedIniCode (ic);
2542 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2544 /* now create the register mask for those
2545 registers that are in use : this is a
2546 super set of ic->rUsed */
2547 ic->rMask = newBitVect (pic14_nRegs + 1);
2549 /* for all live Ranges alive at this point */
2550 for (j = 1; j < ic->rlive->size; j++)
2555 /* if not alive then continue */
2556 if (!bitVectBitValue (ic->rlive, j))
2559 /* find the live range we are interested in */
2560 if (!(sym = hTabItemWithKey (liveRanges, j)))
2562 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2563 "createRegMask cannot find live range");
2567 /* if no register assigned to it */
2568 if (!sym->nRegs || sym->isspilt)
2571 /* for all the registers allocated to it */
2572 for (k = 0; k < sym->nRegs; k++)
2575 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2581 /* This was the active version */
2582 /*-----------------------------------------------------------------*/
2583 /* rematStr - returns the rematerialized string for a remat var */
2584 /*-----------------------------------------------------------------*/
2586 rematStr (symbol * sym)
2589 iCode *ic = sym->rematiCode;
2590 symbol *psym = NULL;
2592 debugLog ("%s\n", __FUNCTION__);
2594 //printf ("%s\n", s);
2596 /* if plus or minus print the right hand side */
2598 if (ic->op == '+' || ic->op == '-') {
2600 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2602 sprintf (s, "(%s %c 0x%04x)",
2603 OP_SYMBOL (IC_LEFT (ric))->rname,
2605 (int) operandLitValue (IC_RIGHT (ic)));
2608 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2610 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2611 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2616 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2617 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2619 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2625 /* deprecated version */
2626 /*-----------------------------------------------------------------*/
2627 /* rematStr - returns the rematerialized string for a remat var */
2628 /*-----------------------------------------------------------------*/
2630 rematStr (symbol * sym)
2633 iCode *ic = sym->rematiCode;
2635 debugLog ("%s\n", __FUNCTION__);
2640 /* if plus or minus print the right hand side */
2642 if (ic->op == '+' || ic->op == '-') {
2643 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2646 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2650 if (ic->op == '+' || ic->op == '-')
2652 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2653 sprintf (s, "(%s %c 0x%04x)",
2654 OP_SYMBOL (IC_LEFT (ric))->rname,
2656 (int) operandLitValue (IC_RIGHT (ic)));
2659 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2661 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2665 /* we reached the end */
2666 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2670 printf ("%s\n", buffer);
2675 /*-----------------------------------------------------------------*/
2676 /* regTypeNum - computes the type & number of registers required */
2677 /*-----------------------------------------------------------------*/
2685 debugLog ("%s\n", __FUNCTION__);
2686 /* for each live range do */
2687 for (sym = hTabFirstItem (liveRanges, &k); sym;
2688 sym = hTabNextItem (liveRanges, &k)) {
2690 debugLog (" %d - %s\n", __LINE__, sym->rname);
2692 /* if used zero times then no registers needed */
2693 if ((sym->liveTo - sym->liveFrom) == 0)
2697 /* if the live range is a temporary */
2700 debugLog (" %d - itemp register\n", __LINE__);
2702 /* if the type is marked as a conditional */
2703 if (sym->regType == REG_CND)
2706 /* if used in return only then we don't
2709 if (IS_AGGREGATE (sym->type) || sym->isptr)
2710 sym->type = aggrToPtr (sym->type, FALSE);
2711 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2717 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2718 // sym->type = aggrToPtr (sym->type, FALSE);
2719 debugLog (" %d - used as a return\n", __LINE__);
2724 /* if the symbol has only one definition &
2725 that definition is a get_pointer and the
2726 pointer we are getting is rematerializable and
2730 if (bitVectnBitsOn (sym->defs) == 1 &&
2731 (ic = hTabItemWithKey (iCodehTab,
2732 bitVectFirstBit (sym->defs))) &&
2734 !IS_BITVAR (sym->etype) &&
2735 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2737 if (ptrPseudoSymSafe (sym, ic)) {
2741 debugLog (" %d - \n", __LINE__);
2743 /* create a pseudo symbol & force a spil */
2744 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2745 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2746 psym->type = sym->type;
2747 psym->etype = sym->etype;
2748 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2749 strcpy (psym->rname, psym->name);
2751 sym->usl.spillLoc = psym;
2755 /* if in data space or idata space then try to
2756 allocate pointer register */
2761 /* if not then we require registers */
2762 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2763 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2764 getSize (sym->type));
2767 if(IS_PTR_CONST (sym->type)) {
2768 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2772 if (sym->nRegs > 4) {
2773 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2774 printTypeChain (sym->type, stderr);
2775 fprintf (stderr, "\n");
2778 /* determine the type of register required */
2779 if (sym->nRegs == 1 &&
2780 IS_PTR (sym->type) &&
2782 sym->regType = REG_PTR;
2784 sym->regType = REG_GPR;
2787 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2791 /* for the first run we don't provide */
2792 /* registers for true symbols we will */
2793 /* see how things go */
2798 DEFSETFUNC (markRegFree)
2800 ((regs *)item)->isFree = 1;
2805 DEFSETFUNC (deallocReg)
2807 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2808 ((regs *)item)->isFree = 1;
2809 ((regs *)item)->wasUsed = 0;
2813 /*-----------------------------------------------------------------*/
2814 /* freeAllRegs - mark all registers as free */
2815 /*-----------------------------------------------------------------*/
2817 pic14_freeAllRegs ()
2821 debugLog ("%s\n", __FUNCTION__);
2823 applyToSet(dynAllocRegs,markRegFree);
2824 applyToSet(dynStackRegs,markRegFree);
2827 for (i = 0; i < pic14_nRegs; i++)
2828 regspic14[i].isFree = 1;
2832 /*-----------------------------------------------------------------*/
2833 /*-----------------------------------------------------------------*/
2835 pic14_deallocateAllRegs ()
2839 debugLog ("%s\n", __FUNCTION__);
2841 applyToSet(dynAllocRegs,deallocReg);
2844 for (i = 0; i < pic14_nRegs; i++) {
2845 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2846 regspic14[i].isFree = 1;
2847 regspic14[i].wasUsed = 0;
2854 /*-----------------------------------------------------------------*/
2855 /* deallocStackSpil - this will set the stack pointer back */
2856 /*-----------------------------------------------------------------*/
2858 DEFSETFUNC (deallocStackSpil)
2862 debugLog ("%s\n", __FUNCTION__);
2867 /*-----------------------------------------------------------------*/
2868 /* farSpacePackable - returns the packable icode for far variables */
2869 /*-----------------------------------------------------------------*/
2871 farSpacePackable (iCode * ic)
2875 debugLog ("%s\n", __FUNCTION__);
2876 /* go thru till we find a definition for the
2877 symbol on the right */
2878 for (dic = ic->prev; dic; dic = dic->prev)
2881 /* if the definition is a call then no */
2882 if ((dic->op == CALL || dic->op == PCALL) &&
2883 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2888 /* if shift by unknown amount then not */
2889 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2890 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2893 /* if pointer get and size > 1 */
2894 if (POINTER_GET (dic) &&
2895 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2898 if (POINTER_SET (dic) &&
2899 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2902 /* if any three is a true symbol in far space */
2903 if (IC_RESULT (dic) &&
2904 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2905 isOperandInFarSpace (IC_RESULT (dic)))
2908 if (IC_RIGHT (dic) &&
2909 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2910 isOperandInFarSpace (IC_RIGHT (dic)) &&
2911 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2914 if (IC_LEFT (dic) &&
2915 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2916 isOperandInFarSpace (IC_LEFT (dic)) &&
2917 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2920 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2922 if ((dic->op == LEFT_OP ||
2923 dic->op == RIGHT_OP ||
2925 IS_OP_LITERAL (IC_RIGHT (dic)))
2935 /*-----------------------------------------------------------------*/
2936 /* packRegsForAssign - register reduction for assignment */
2937 /*-----------------------------------------------------------------*/
2939 packRegsForAssign (iCode * ic, eBBlock * ebp)
2944 debugLog ("%s\n", __FUNCTION__);
2946 debugAopGet (" result:", IC_RESULT (ic));
2947 debugAopGet (" left:", IC_LEFT (ic));
2948 debugAopGet (" right:", IC_RIGHT (ic));
2950 /* if this is at an absolute address, then get the address. */
2951 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2952 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2953 debugLog (" %d - found config word declaration\n", __LINE__);
2954 if(IS_VALOP(IC_RIGHT(ic))) {
2955 debugLog (" setting config word to %x\n",
2956 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2957 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2958 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2961 /* remove the assignment from the iCode chain. */
2963 remiCodeFromeBBlock (ebp, ic);
2964 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2965 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2972 if (!IS_ITEMP (IC_RESULT (ic))) {
2973 allocDirReg(IC_RESULT (ic));
2974 debugLog (" %d - result is not temp\n", __LINE__);
2977 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2978 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2979 allocDirReg(IC_LEFT (ic));
2983 if (!IS_ITEMP (IC_RIGHT (ic))) {
2984 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2986 /* only pack if this is not a function pointer */
2987 if (!IS_REF (IC_RIGHT (ic)))
2988 allocDirReg(IC_RIGHT (ic));
2992 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2993 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2995 debugLog (" %d - not packing - right side fails \n", __LINE__);
2999 /* if the true symbol is defined in far space or on stack
3000 then we should not since this will increase register pressure */
3001 if (isOperandInFarSpace (IC_RESULT (ic)))
3003 if ((dic = farSpacePackable (ic)))
3009 /* find the definition of iTempNN scanning backwards if we find a
3010 a use of the true symbol before we find the definition then
3012 for (dic = ic->prev; dic; dic = dic->prev)
3015 /* if there is a function call and this is
3016 a parameter & not my parameter then don't pack it */
3017 if ((dic->op == CALL || dic->op == PCALL) &&
3018 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3019 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3021 debugLog (" %d - \n", __LINE__);
3029 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3030 IS_OP_VOLATILE (IC_RESULT (dic)))
3032 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3037 if (IS_SYMOP (IC_RESULT (dic)) &&
3038 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3040 /* A previous result was assigned to the same register - we'll our definition */
3041 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3042 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3043 if (POINTER_SET (dic))
3049 if (IS_SYMOP (IC_RIGHT (dic)) &&
3050 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3051 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3053 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3058 if (IS_SYMOP (IC_LEFT (dic)) &&
3059 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3060 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3062 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3067 if (POINTER_SET (dic) &&
3068 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3070 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3078 return 0; /* did not find */
3080 /* if assignment then check that right is not a bit */
3081 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
3083 sym_link *etype = operandType (IC_RESULT (dic));
3084 if (IS_BITFIELD (etype))
3086 /* if result is a bit too then it's ok */
3087 etype = operandType (IC_RESULT (ic));
3088 if (!IS_BITFIELD (etype))
3093 /* if the result is on stack or iaccess then it must be
3094 the same at least one of the operands */
3095 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3096 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3099 /* the operation has only one symbol
3100 operator then we can pack */
3101 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3102 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3105 if (!((IC_LEFT (dic) &&
3106 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3108 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3112 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3113 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3114 /* found the definition */
3115 /* replace the result with the result of */
3116 /* this assignment and remove this assignment */
3117 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3118 IC_RESULT (dic) = IC_RESULT (ic);
3120 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3122 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3124 /* delete from liverange table also
3125 delete from all the points inbetween and the new
3127 for (sic = dic; sic != ic; sic = sic->next)
3129 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3130 if (IS_ITEMP (IC_RESULT (dic)))
3131 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3134 remiCodeFromeBBlock (ebp, ic);
3135 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3136 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3137 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3143 /*-----------------------------------------------------------------*/
3144 /* findAssignToSym : scanning backwards looks for first assig found */
3145 /*-----------------------------------------------------------------*/
3147 findAssignToSym (operand * op, iCode * ic)
3151 debugLog ("%s\n", __FUNCTION__);
3152 for (dic = ic->prev; dic; dic = dic->prev)
3155 /* if definition by assignment */
3156 if (dic->op == '=' &&
3157 !POINTER_SET (dic) &&
3158 IC_RESULT (dic)->key == op->key
3159 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3163 /* we are interested only if defined in far space */
3164 /* or in stack space in case of + & - */
3166 /* if assigned to a non-symbol then return
3168 if (!IS_SYMOP (IC_RIGHT (dic)))
3171 /* if the symbol is in far space then
3173 if (isOperandInFarSpace (IC_RIGHT (dic)))
3176 /* for + & - operations make sure that
3177 if it is on the stack it is the same
3178 as one of the three operands */
3179 if ((ic->op == '+' || ic->op == '-') &&
3180 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3183 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3184 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3185 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3193 /* if we find an usage then we cannot delete it */
3194 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3197 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3200 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3204 /* now make sure that the right side of dic
3205 is not defined between ic & dic */
3208 iCode *sic = dic->next;
3210 for (; sic != ic; sic = sic->next)
3211 if (IC_RESULT (sic) &&
3212 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3221 /*-----------------------------------------------------------------*/
3222 /* packRegsForSupport :- reduce some registers for support calls */
3223 /*-----------------------------------------------------------------*/
3225 packRegsForSupport (iCode * ic, eBBlock * ebp)
3229 debugLog ("%s\n", __FUNCTION__);
3230 /* for the left & right operand :- look to see if the
3231 left was assigned a true symbol in far space in that
3232 case replace them */
3233 if (IS_ITEMP (IC_LEFT (ic)) &&
3234 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3236 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3242 debugAopGet ("removing left:", IC_LEFT (ic));
3244 /* found it we need to remove it from the
3246 for (sic = dic; sic != ic; sic = sic->next)
3247 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3249 IC_LEFT (ic)->operand.symOperand =
3250 IC_RIGHT (dic)->operand.symOperand;
3251 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3252 remiCodeFromeBBlock (ebp, dic);
3253 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3254 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3258 /* do the same for the right operand */
3261 IS_ITEMP (IC_RIGHT (ic)) &&
3262 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3264 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3270 /* if this is a subtraction & the result
3271 is a true symbol in far space then don't pack */
3272 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3274 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3275 if (IN_FARSPACE (SPEC_OCLS (etype)))
3279 debugAopGet ("removing right:", IC_RIGHT (ic));
3281 /* found it we need to remove it from the
3283 for (sic = dic; sic != ic; sic = sic->next)
3284 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3286 IC_RIGHT (ic)->operand.symOperand =
3287 IC_RIGHT (dic)->operand.symOperand;
3288 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3290 remiCodeFromeBBlock (ebp, dic);
3291 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3292 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3299 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3302 /*-----------------------------------------------------------------*/
3303 /* packRegsForOneuse : - will reduce some registers for single Use */
3304 /*-----------------------------------------------------------------*/
3306 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3311 debugLog ("%s\n", __FUNCTION__);
3312 /* if returning a literal then do nothing */
3316 /* only upto 2 bytes since we cannot predict
3317 the usage of b, & acc */
3318 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3323 /* this routine will mark the a symbol as used in one
3324 instruction use only && if the definition is local
3325 (ie. within the basic block) && has only one definition &&
3326 that definition is either a return value from a
3327 function or does not contain any variables in
3329 uses = bitVectCopy (OP_USES (op));
3330 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3331 if (!bitVectIsZero (uses)) /* has other uses */
3334 /* if it has only one defintion */
3335 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3336 return NULL; /* has more than one definition */
3338 /* get that definition */
3340 hTabItemWithKey (iCodehTab,
3341 bitVectFirstBit (OP_DEFS (op)))))
3344 /* found the definition now check if it is local */
3345 if (dic->seq < ebp->fSeq ||
3346 dic->seq > ebp->lSeq)
3347 return NULL; /* non-local */
3349 /* now check if it is the return from
3351 if (dic->op == CALL || dic->op == PCALL)
3353 if (ic->op != SEND && ic->op != RETURN &&
3354 !POINTER_SET(ic) && !POINTER_GET(ic))
3356 OP_SYMBOL (op)->ruonly = 1;
3363 /* otherwise check that the definition does
3364 not contain any symbols in far space */
3365 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3366 isOperandInFarSpace (IC_RIGHT (dic)) ||
3367 IS_OP_RUONLY (IC_LEFT (ic)) ||
3368 IS_OP_RUONLY (IC_RIGHT (ic)))
3373 /* if pointer set then make sure the pointer
3375 if (POINTER_SET (dic) &&
3376 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3379 if (POINTER_GET (dic) &&
3380 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3385 /* also make sure the intervenening instructions
3386 don't have any thing in far space */
3387 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3390 /* if there is an intervening function call then no */
3391 if (dic->op == CALL || dic->op == PCALL)
3393 /* if pointer set then make sure the pointer
3395 if (POINTER_SET (dic) &&
3396 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3399 if (POINTER_GET (dic) &&
3400 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3403 /* if address of & the result is remat then okay */
3404 if (dic->op == ADDRESS_OF &&
3405 OP_SYMBOL (IC_RESULT (dic))->remat)
3408 /* if operand has size of three or more & this
3409 operation is a '*','/' or '%' then 'b' may
3411 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3412 getSize (operandType (op)) >= 3)
3415 /* if left or right or result is in far space */
3416 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3417 isOperandInFarSpace (IC_RIGHT (dic)) ||
3418 isOperandInFarSpace (IC_RESULT (dic)) ||
3419 IS_OP_RUONLY (IC_LEFT (dic)) ||
3420 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3421 IS_OP_RUONLY (IC_RESULT (dic)))
3427 OP_SYMBOL (op)->ruonly = 1;
3432 /*-----------------------------------------------------------------*/
3433 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3434 /*-----------------------------------------------------------------*/
3436 isBitwiseOptimizable (iCode * ic)
3438 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3439 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3441 debugLog ("%s\n", __FUNCTION__);
3442 /* bitwise operations are considered optimizable
3443 under the following conditions (Jean-Louis VERN)
3455 if (IS_LITERAL (rtype) ||
3456 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3462 /*-----------------------------------------------------------------*/
3463 /* packRegsForAccUse - pack registers for acc use */
3464 /*-----------------------------------------------------------------*/
3466 packRegsForAccUse (iCode * ic)
3470 debugLog ("%s\n", __FUNCTION__);
3472 /* result too large for WREG? */
3473 if (getSize (operandType (IC_RESULT (ic))) > 1)
3476 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3477 * is never used as an operand to an instruction that
3478 * cannot have WREG as an operand (e.g. BTFSx cannot
3479 * operate on WREG...
3480 * For now, store all results into proper registers. */
3484 /* if this is an aggregate, e.g. a one byte char array */
3485 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3488 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3490 /* if + or - then it has to be one byte result */
3491 if ((ic->op == '+' || ic->op == '-')
3492 && getSize (operandType (IC_RESULT (ic))) > 1)
3495 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3496 /* if shift operation make sure right side is not a literal */
3497 if (ic->op == RIGHT_OP &&
3498 (isOperandLiteral (IC_RIGHT (ic)) ||
3499 getSize (operandType (IC_RESULT (ic))) > 1))
3502 if (ic->op == LEFT_OP &&
3503 (isOperandLiteral (IC_RIGHT (ic)) ||
3504 getSize (operandType (IC_RESULT (ic))) > 1))
3507 if (IS_BITWISE_OP (ic) &&
3508 getSize (operandType (IC_RESULT (ic))) > 1)
3512 /* has only one definition */
3513 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3516 /* has only one use */
3517 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3520 /* and the usage immediately follows this iCode */
3521 if (!(uic = hTabItemWithKey (iCodehTab,
3522 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3525 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3526 if (ic->next != uic)
3529 /* if it is a conditional branch then we definitely can */
3533 if (uic->op == JUMPTABLE)
3536 /* if the usage is not is an assignment
3537 or an arithmetic / bitwise / shift operation then not */
3538 if (POINTER_SET (uic) &&
3539 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3542 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3543 if (uic->op != '=' &&
3544 !IS_ARITHMETIC_OP (uic) &&
3545 !IS_BITWISE_OP (uic) &&
3546 uic->op != LEFT_OP &&
3547 uic->op != RIGHT_OP)
3550 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3551 /* if used in ^ operation then make sure right is not a
3553 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3556 /* if shift operation make sure right side is not a literal */
3557 if (uic->op == RIGHT_OP &&
3558 (isOperandLiteral (IC_RIGHT (uic)) ||
3559 getSize (operandType (IC_RESULT (uic))) > 1))
3562 if (uic->op == LEFT_OP &&
3563 (isOperandLiteral (IC_RIGHT (uic)) ||
3564 getSize (operandType (IC_RESULT (uic))) > 1))
3567 /* make sure that the result of this icode is not on the
3568 stack, since acc is used to compute stack offset */
3569 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3570 OP_SYMBOL (IC_RESULT (uic))->onStack)
3573 /* if either one of them in far space then we cannot */
3574 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3575 isOperandInFarSpace (IC_LEFT (uic))) ||
3576 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3577 isOperandInFarSpace (IC_RIGHT (uic))))
3580 /* if the usage has only one operand then we can */
3581 if (IC_LEFT (uic) == NULL ||
3582 IC_RIGHT (uic) == NULL)
3585 /* make sure this is on the left side if not
3586 a '+' since '+' is commutative */
3587 if (ic->op != '+' &&
3588 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3591 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3592 /* if one of them is a literal then we can */
3593 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3594 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3595 (getSize (operandType (IC_RESULT (uic))) <= 1))
3597 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3601 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3602 /* if the other one is not on stack then we can */
3603 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3604 (IS_ITEMP (IC_RIGHT (uic)) ||
3605 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3606 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3609 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3610 (IS_ITEMP (IC_LEFT (uic)) ||
3611 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3612 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3618 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3619 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3623 /*-----------------------------------------------------------------*/
3624 /* packForPush - hueristics to reduce iCode for pushing */
3625 /*-----------------------------------------------------------------*/
3627 packForReceive (iCode * ic, eBBlock * ebp)
3631 debugLog ("%s\n", __FUNCTION__);
3632 debugAopGet (" result:", IC_RESULT (ic));
3633 debugAopGet (" left:", IC_LEFT (ic));
3634 debugAopGet (" right:", IC_RIGHT (ic));
3639 for (dic = ic->next; dic; dic = dic->next)
3644 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3645 debugLog (" used on left\n");
3646 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3647 debugLog (" used on right\n");
3648 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3649 debugLog (" used on result\n");
3651 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3652 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3657 debugLog (" hey we can remove this unnecessary assign\n");
3659 /*-----------------------------------------------------------------*/
3660 /* packForPush - hueristics to reduce iCode for pushing */
3661 /*-----------------------------------------------------------------*/
3663 packForPush (iCode * ic, eBBlock * ebp)
3667 debugLog ("%s\n", __FUNCTION__);
3668 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3671 /* must have only definition & one usage */
3672 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3673 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3676 /* find the definition */
3677 if (!(dic = hTabItemWithKey (iCodehTab,
3678 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3681 if (dic->op != '=' || POINTER_SET (dic))
3684 /* we now we know that it has one & only one def & use
3685 and the that the definition is an assignment */
3686 IC_LEFT (ic) = IC_RIGHT (dic);
3688 remiCodeFromeBBlock (ebp, dic);
3689 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3690 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3693 void printSymType(char * str, sym_link *sl)
3695 debugLog (" %s Symbol type: ",str);
3696 printTypeChain( sl, debugF);
3701 /*-----------------------------------------------------------------*/
3702 /* some debug code to print the symbol S_TYPE. Note that
3703 * the function checkSClass in src/SDCCsymt.c dinks with
3704 * the S_TYPE in ways the PIC port doesn't fully like...*/
3705 /*-----------------------------------------------------------------*/
3706 void isData(sym_link *sl)
3716 for ( ; sl; sl=sl->next) {
3718 switch (SPEC_SCLS(sl)) {
3720 case S_DATA: fprintf (of, "data "); break;
3721 case S_XDATA: fprintf (of, "xdata "); break;
3722 case S_SFR: fprintf (of, "sfr "); break;
3723 case S_SBIT: fprintf (of, "sbit "); break;
3724 case S_CODE: fprintf (of, "code "); break;
3725 case S_IDATA: fprintf (of, "idata "); break;
3726 case S_PDATA: fprintf (of, "pdata "); break;
3727 case S_LITERAL: fprintf (of, "literal "); break;
3728 case S_STACK: fprintf (of, "stack "); break;
3729 case S_XSTACK: fprintf (of, "xstack "); break;
3730 case S_BIT: fprintf (of, "bit "); break;
3731 case S_EEPROM: fprintf (of, "eeprom "); break;
3741 /*-----------------------------------------------------------------*/
3742 /* packRegisters - does some transformations to reduce register */
3744 /*-----------------------------------------------------------------*/
3746 packRegisters (eBBlock * ebp)
3751 debugLog ("%s\n", __FUNCTION__);
3757 /* look for assignments of the form */
3758 /* iTempNN = TRueSym (someoperation) SomeOperand */
3760 /* TrueSym := iTempNN:1 */
3761 for (ic = ebp->sch; ic; ic = ic->next)
3764 /* find assignment of the form TrueSym := iTempNN:1 */
3765 if (ic->op == '=' && !POINTER_SET (ic))
3766 change += packRegsForAssign (ic, ebp);
3770 if (POINTER_SET (ic))
3771 debugLog ("pointer is set\n");
3772 debugAopGet (" result:", IC_RESULT (ic));
3773 debugAopGet (" left:", IC_LEFT (ic));
3774 debugAopGet (" right:", IC_RIGHT (ic));
3783 for (ic = ebp->sch; ic; ic = ic->next) {
3785 if(IS_SYMOP ( IC_LEFT(ic))) {
3786 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3788 debugAopGet (" left:", IC_LEFT (ic));
3789 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3790 debugLog (" is a pointer\n");
3792 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3793 debugLog (" is volatile\n");
3797 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3800 if(IS_SYMOP ( IC_RIGHT(ic))) {
3801 debugAopGet (" right:", IC_RIGHT (ic));
3802 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3805 if(IS_SYMOP ( IC_RESULT(ic))) {
3806 debugAopGet (" result:", IC_RESULT (ic));
3807 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3810 if (POINTER_SET (ic))
3811 debugLog (" %d - Pointer set\n", __LINE__);
3814 /* Look for two subsequent iCodes with */
3816 /* _c = iTemp & op; */
3817 /* and replace them by */
3820 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3822 ic->prev->op == '=' &&
3823 IS_ITEMP (IC_LEFT (ic)) &&
3824 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3825 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3827 iCode* ic_prev = ic->prev;
3828 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3830 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3831 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3833 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3834 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3835 prev_result_sym->liveTo == ic->seq)
3837 prev_result_sym->liveTo = ic_prev->seq;
3840 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3842 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3844 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3846 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3847 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3848 remiCodeFromeBBlock (ebp, ic_prev);
3849 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3853 /* if this is an itemp & result of a address of a true sym
3854 then mark this as rematerialisable */
3855 if (ic->op == ADDRESS_OF &&
3856 IS_ITEMP (IC_RESULT (ic)) &&
3857 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3858 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3859 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3862 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3864 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3865 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3866 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3870 /* if straight assignment then carry remat flag if
3871 this is the only definition */
3872 if (ic->op == '=' &&
3873 !POINTER_SET (ic) &&
3874 IS_SYMOP (IC_RIGHT (ic)) &&
3875 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3876 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3878 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3880 OP_SYMBOL (IC_RESULT (ic))->remat =
3881 OP_SYMBOL (IC_RIGHT (ic))->remat;
3882 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3883 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3886 /* if this is a +/- operation with a rematerizable
3887 then mark this as rematerializable as well */
3888 if ((ic->op == '+' || ic->op == '-') &&
3889 (IS_SYMOP (IC_LEFT (ic)) &&
3890 IS_ITEMP (IC_RESULT (ic)) &&
3891 OP_SYMBOL (IC_LEFT (ic))->remat &&
3892 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3893 IS_OP_LITERAL (IC_RIGHT (ic))))
3895 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3897 operandLitValue (IC_RIGHT (ic));
3898 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3899 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3900 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3903 /* mark the pointer usages */
3904 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3906 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3907 debugLog (" marking as a pointer (set) =>");
3908 debugAopGet (" result:", IC_RESULT (ic));
3910 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3912 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3913 debugLog (" marking as a pointer (get) =>");
3914 debugAopGet (" left:", IC_LEFT (ic));
3919 /* if we are using a symbol on the stack
3920 then we should say pic14_ptrRegReq */
3921 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3922 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3923 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3924 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3925 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3926 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3929 if (IS_SYMOP (IC_LEFT (ic)))
3930 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3931 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3932 if (IS_SYMOP (IC_RIGHT (ic)))
3933 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3934 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3935 if (IS_SYMOP (IC_RESULT (ic)))
3936 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3937 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3940 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3944 /* if the condition of an if instruction
3945 is defined in the previous instruction then
3946 mark the itemp as a conditional */
3947 if ((IS_CONDITIONAL (ic) ||
3948 ((ic->op == BITWISEAND ||
3951 isBitwiseOptimizable (ic))) &&
3952 ic->next && ic->next->op == IFX &&
3953 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3954 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3957 debugLog (" %d\n", __LINE__);
3958 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3962 /* reduce for support function calls */
3963 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3964 packRegsForSupport (ic, ebp);
3966 /* if a parameter is passed, it's in W, so we may not
3967 need to place a copy in a register */
3968 if (ic->op == RECEIVE)
3969 packForReceive (ic, ebp);
3971 /* some cases the redundant moves can
3972 can be eliminated for return statements */
3973 if ((ic->op == RETURN || ic->op == SEND) &&
3974 !isOperandInFarSpace (IC_LEFT (ic)) &&
3976 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3978 /* if pointer set & left has a size more than
3979 one and right is not in far space */
3980 if (POINTER_SET (ic) &&
3981 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3982 IS_SYMOP(IC_RESULT(ic)) &&
3983 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3984 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3985 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3987 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3989 /* if pointer get */
3990 if (POINTER_GET (ic) &&
3991 !isOperandInFarSpace (IC_RESULT (ic)) &&
3992 IS_SYMOP(IC_LEFT(ic)) &&
3993 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3994 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3995 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3997 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4000 /* if this is cast for intergral promotion then
4001 check if only use of the definition of the
4002 operand being casted/ if yes then replace
4003 the result of that arithmetic operation with
4004 this result and get rid of the cast */
4005 if (ic->op == CAST) {
4007 sym_link *fromType = operandType (IC_RIGHT (ic));
4008 sym_link *toType = operandType (IC_LEFT (ic));
4010 debugLog (" %d - casting\n", __LINE__);
4012 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4013 getSize (fromType) != getSize (toType)) {
4016 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4019 if (IS_ARITHMETIC_OP (dic)) {
4021 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4022 IC_RESULT (dic) = IC_RESULT (ic);
4023 remiCodeFromeBBlock (ebp, ic);
4024 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4025 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4026 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4030 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4034 /* if the type from and type to are the same
4035 then if this is the only use then packit */
4036 if (compareType (operandType (IC_RIGHT (ic)),
4037 operandType (IC_LEFT (ic))) == 1) {
4039 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4042 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4043 IC_RESULT (dic) = IC_RESULT (ic);
4044 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4045 remiCodeFromeBBlock (ebp, ic);
4046 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4047 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4055 iTempNN := (some variable in farspace) V1
4060 if (ic->op == IPUSH)
4062 packForPush (ic, ebp);
4066 /* pack registers for accumulator use, when the
4067 result of an arithmetic or bit wise operation
4068 has only one use, that use is immediately following
4069 the defintion and the using iCode has only one
4070 operand or has two operands but one is literal &
4071 the result of that operation is not on stack then
4072 we can leave the result of this operation in acc:b
4074 if ((IS_ARITHMETIC_OP (ic)
4076 || IS_BITWISE_OP (ic)
4078 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4081 IS_ITEMP (IC_RESULT (ic)) &&
4082 getSize (operandType (IC_RESULT (ic))) <= 2)
4084 packRegsForAccUse (ic);
4090 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4094 if (!debug || !debugF)
4097 for (i = 0; i < count; i++)
4099 fprintf (debugF, "\n----------------------------------------------------------------\n");
4100 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4101 ebbs[i]->entryLabel->name,
4104 ebbs[i]->isLastInLoop);
4105 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4110 fprintf (debugF, "visited %d : hasFcall = %d\n",
4114 fprintf (debugF, "\ndefines bitVector :");
4115 bitVectDebugOn (ebbs[i]->defSet, debugF);
4116 fprintf (debugF, "\nlocal defines bitVector :");
4117 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4118 fprintf (debugF, "\npointers Set bitvector :");
4119 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4120 fprintf (debugF, "\nin pointers Set bitvector :");
4121 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4122 fprintf (debugF, "\ninDefs Set bitvector :");
4123 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4124 fprintf (debugF, "\noutDefs Set bitvector :");
4125 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4126 fprintf (debugF, "\nusesDefs Set bitvector :");
4127 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4128 fprintf (debugF, "\n----------------------------------------------------------------\n");
4129 printiCChain (ebbs[i]->sch, debugF);
4132 /*-----------------------------------------------------------------*/
4133 /* assignRegisters - assigns registers to each live range as need */
4134 /*-----------------------------------------------------------------*/
4136 pic14_assignRegisters (ebbIndex * ebbi)
4138 eBBlock ** ebbs = ebbi->bbOrder;
4139 int count = ebbi->count;
4143 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4144 debugLog ("ebbs before optimizing:\n");
4145 dumpEbbsToDebug (ebbs, count);
4147 setToNull ((void *) &_G.funcrUsed);
4148 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4151 /* change assignments this will remove some
4152 live ranges reducing some register pressure */
4153 for (i = 0; i < count; i++)
4154 packRegisters (ebbs[i]);
4161 debugLog("dir registers allocated so far:\n");
4162 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4165 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4166 reg = hTabNextItem(dynDirectRegNames, &hkey);
4171 if (options.dump_pack)
4172 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4174 /* first determine for each live range the number of
4175 registers & the type of registers required for each */
4178 /* and serially allocate registers */
4179 serialRegAssign (ebbs, count);
4181 /* if stack was extended then tell the user */
4184 /* werror(W_TOOMANY_SPILS,"stack", */
4185 /* _G.stackExtend,currFunc->name,""); */
4191 /* werror(W_TOOMANY_SPILS,"data space", */
4192 /* _G.dataExtend,currFunc->name,""); */
4196 /* after that create the register mask
4197 for each of the instruction */
4198 createRegMask (ebbs, count);
4200 /* redo that offsets for stacked automatic variables */
4201 redoStackOffsets ();
4203 if (options.dump_rassgn)
4204 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4206 /* now get back the chain */
4207 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4209 debugLog ("ebbs after optimizing:\n");
4210 dumpEbbsToDebug (ebbs, count);
4215 /* free up any _G.stackSpil locations allocated */
4216 applyToSet (_G.stackSpil, deallocStackSpil);
4218 setToNull ((void *) &_G.stackSpil);
4219 setToNull ((void *) &_G.spiltSet);
4220 /* mark all registers as free */
4221 //pic14_freeAllRegs ();
4223 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");