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 assignConfigWordValue(int address, int value);
65 bitVect *funcrUsed; /* registers used in a function */
71 /* Shared with gen.c */
72 int pic14_ptrRegReq; /* one byte pointer register required */
75 set *dynAllocRegs=NULL;
76 set *dynStackRegs=NULL;
77 set *dynProcessorRegs=NULL;
78 set *dynDirectRegs=NULL;
79 set *dynDirectBitRegs=NULL;
80 set *dynInternalRegs=NULL;
82 static hTab *dynDirectRegNames= NULL;
83 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 static int dynrIdx=0x20;
86 static int rDirectIdx=0;
88 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
90 int Gstack_base_addr=0; /* The starting address of registers that
91 * are used to pass and return parameters */
97 static void spillThis (symbol *);
99 static FILE *debugF = NULL;
100 /*-----------------------------------------------------------------*/
101 /* debugLog - open a file for debugging information */
102 /*-----------------------------------------------------------------*/
103 //static void debugLog(char *inst,char *fmt, ...)
105 debugLog (char *fmt,...)
107 static int append = 0; // First time through, open the file without append.
110 //char *bufferP=buffer;
113 if (!debug || !dstFileName)
119 /* create the file name */
120 strcpy (buffer, dstFileName);
121 strcat (buffer, ".d");
123 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
125 werror (E_FILE_OPEN_ERR, buffer);
128 append = 1; // Next time debubLog is called, we'll append the debug info
134 vsprintf (buffer, fmt, ap);
136 fprintf (debugF, "%s", buffer);
137 //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
139 while (isspace((unsigned char)*bufferP)) bufferP++;
141 if (bufferP && *bufferP)
142 lineCurr = (lineCurr ?
143 connectLine(lineCurr,newLineNode(lb)) :
144 (lineHead = newLineNode(lb)));
145 lineCurr->isInline = _G.inLine;
146 lineCurr->isDebug = _G.debugLine;
156 fputc ('\n', debugF);
158 /*-----------------------------------------------------------------*/
159 /* debugLogClose - closes the debug log file (if opened) */
160 /*-----------------------------------------------------------------*/
170 #define AOP(op) op->aop
173 debugAopGet (char *str, operand * op)
178 printOperand (op, debugF);
186 decodeOp (unsigned int op)
189 if (op < 128 && op > ' ')
191 buffer[0] = (op & 0xff);
198 case IDENTIFIER: return "IDENTIFIER";
199 case TYPE_NAME: return "TYPE_NAME";
200 case CONSTANT: return "CONSTANT";
201 case STRING_LITERAL: return "STRING_LITERAL";
202 case SIZEOF: return "SIZEOF";
203 case PTR_OP: return "PTR_OP";
204 case INC_OP: return "INC_OP";
205 case DEC_OP: return "DEC_OP";
206 case LEFT_OP: return "LEFT_OP";
207 case RIGHT_OP: return "RIGHT_OP";
208 case LE_OP: return "LE_OP";
209 case GE_OP: return "GE_OP";
210 case EQ_OP: return "EQ_OP";
211 case NE_OP: return "NE_OP";
212 case AND_OP: return "AND_OP";
213 case OR_OP: return "OR_OP";
214 case MUL_ASSIGN: return "MUL_ASSIGN";
215 case DIV_ASSIGN: return "DIV_ASSIGN";
216 case MOD_ASSIGN: return "MOD_ASSIGN";
217 case ADD_ASSIGN: return "ADD_ASSIGN";
218 case SUB_ASSIGN: return "SUB_ASSIGN";
219 case LEFT_ASSIGN: return "LEFT_ASSIGN";
220 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
221 case AND_ASSIGN: return "AND_ASSIGN";
222 case XOR_ASSIGN: return "XOR_ASSIGN";
223 case OR_ASSIGN: return "OR_ASSIGN";
224 case TYPEDEF: return "TYPEDEF";
225 case EXTERN: return "EXTERN";
226 case STATIC: return "STATIC";
227 case AUTO: return "AUTO";
228 case REGISTER: return "REGISTER";
229 case CODE: return "CODE";
230 case EEPROM: return "EEPROM";
231 case INTERRUPT: return "INTERRUPT";
232 case SFR: return "SFR";
233 case AT: return "AT";
234 case SBIT: return "SBIT";
235 case REENTRANT: return "REENTRANT";
236 case USING: return "USING";
237 case XDATA: return "XDATA";
238 case DATA: return "DATA";
239 case IDATA: return "IDATA";
240 case PDATA: return "PDATA";
241 case VAR_ARGS: return "VAR_ARGS";
242 case CRITICAL: return "CRITICAL";
243 case NONBANKED: return "NONBANKED";
244 case BANKED: return "BANKED";
245 case CHAR: return "CHAR";
246 case SHORT: return "SHORT";
247 case INT: return "INT";
248 case LONG: return "LONG";
249 case SIGNED: return "SIGNED";
250 case UNSIGNED: return "UNSIGNED";
251 case FLOAT: return "FLOAT";
252 case DOUBLE: return "DOUBLE";
253 case CONST: return "CONST";
254 case VOLATILE: return "VOLATILE";
255 case VOID: return "VOID";
256 case BIT: return "BIT";
257 case STRUCT: return "STRUCT";
258 case UNION: return "UNION";
259 case ENUM: return "ENUM";
260 case ELIPSIS: return "ELIPSIS";
261 case RANGE: return "RANGE";
262 case FAR: return "FAR";
263 case CASE: return "CASE";
264 case DEFAULT: return "DEFAULT";
265 case IF: return "IF";
266 case ELSE: return "ELSE";
267 case SWITCH: return "SWITCH";
268 case WHILE: return "WHILE";
269 case DO: return "DO";
270 case FOR: return "FOR";
271 case GOTO: return "GOTO";
272 case CONTINUE: return "CONTINUE";
273 case BREAK: return "BREAK";
274 case RETURN: return "RETURN";
275 case INLINEASM: return "INLINEASM";
276 case IFX: return "IFX";
277 case ADDRESS_OF: return "ADDRESS_OF";
278 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
279 case SPIL: return "SPIL";
280 case UNSPIL: return "UNSPIL";
281 case GETHBIT: return "GETHBIT";
282 case BITWISEAND: return "BITWISEAND";
283 case UNARYMINUS: return "UNARYMINUS";
284 case IPUSH: return "IPUSH";
285 case IPOP: return "IPOP";
286 case PCALL: return "PCALL";
287 case ENDFUNCTION: return "ENDFUNCTION";
288 case JUMPTABLE: return "JUMPTABLE";
289 case RRC: return "RRC";
290 case RLC: return "RLC";
291 case CAST: return "CAST";
292 case CALL: return "CALL";
293 case PARAM: return "PARAM ";
294 case NULLOP: return "NULLOP";
295 case BLOCK: return "BLOCK";
296 case LABEL: return "LABEL";
297 case RECEIVE: return "RECEIVE";
298 case SEND: return "SEND";
300 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
303 /*-----------------------------------------------------------------*/
304 /*-----------------------------------------------------------------*/
306 debugLogRegType (short type)
311 case REG_GPR: return "REG_GPR";
312 case REG_PTR: return "REG_PTR";
313 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
320 /*-----------------------------------------------------------------*/
321 /*-----------------------------------------------------------------*/
322 static int regname2key(char const *name)
331 key += (*name++) + 1;
335 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
339 static regs *regWithIdx (set *dRegs, int idx, int fixed);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
348 /* check whether a matching register already exists */
349 dReg = dirregWithName( name );
351 //printf( "%s: already present: %s\n", __FUNCTION__, name );
354 dReg = regWithIdx( dynDirectRegs, rIdx, 0 );
355 if (!dReg) dReg = regWithIdx( dynDirectRegs, rIdx, 1 );
358 //printf( "%s: already present %s (idx:%d/%x)", __FUNCTION__, name, rIdx, rIdx );
362 dReg = Safe_calloc(1,sizeof(regs));
364 dReg->pc_type = pc_type;
367 dReg->name = Safe_strdup(name);
369 sprintf(buffer,"r0x%02X", dReg->rIdx);
370 dReg->name = Safe_strdup(buffer);
386 dReg->reg_alias = NULL;
387 dReg->reglives.usedpFlows = newSet();
388 dReg->reglives.assignedpFlows = newSet();
390 hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
391 debugLog( "%s: Created register %s (%p).\n",
392 __FUNCTION__, dReg->name, __builtin_return_address(0) );
397 /*-----------------------------------------------------------------*/
398 /* regWithIdx - Search through a set of registers that matches idx */
399 /*-----------------------------------------------------------------*/
401 regWithIdx (set *dRegs, int idx, int fixed)
405 for (dReg = setFirstItem(dRegs) ; dReg ;
406 dReg = setNextItem(dRegs)) {
408 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
416 /*-----------------------------------------------------------------*/
417 /* regWithName - Search through a set of registers that matches name */
418 /*-----------------------------------------------------------------*/
420 regWithName (set *dRegs, const char *name)
424 for (dReg = setFirstItem(dRegs) ; dReg ;
425 dReg = setNextItem(dRegs)) {
427 if((strcmp(name,dReg->name)==0)) {
435 /*-----------------------------------------------------------------*/
436 /* regWithName - Search for a registers that matches name */
437 /*-----------------------------------------------------------------*/
439 regFindWithName (const char *name)
443 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
444 debugLog ("Found a Direct Register!\n");
447 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
448 debugLog ("Found a Direct Bit Register!\n");
452 if (*name=='_') name++; // Step passed '_'
454 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
455 debugLog ("Found a Dynamic Register!\n");
458 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
459 debugLog ("Found a Processor Register!\n");
462 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
463 debugLog ("Found an Internal Register!\n");
466 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
467 debugLog ("Found an Stack Register!\n");
474 /*-----------------------------------------------------------------*/
475 /* regFindFree - Search for a free register in a set of registers */
476 /*-----------------------------------------------------------------*/
478 regFindFree (set *dRegs)
482 for (dReg = setFirstItem(dRegs) ; dReg ;
483 dReg = setNextItem(dRegs)) {
491 /*-----------------------------------------------------------------*/
492 /* initStack - allocate registers for a pseudo stack */
493 /*-----------------------------------------------------------------*/
494 void initStack(int base_address, int size)
499 Gstack_base_addr = base_address;
501 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
503 for(i = 0; i<size; i++) {
506 SNPRINTF(&buffer[0], 16, "STK%02d", i);
507 r = newReg(REG_STK, PO_GPR_TEMP,base_address,buffer,1,0);
508 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
512 r->alias = 0x180; // Using shared memory for pseudo stack
513 addSet(&dynStackRegs,r);
518 /*-----------------------------------------------------------------*
519 *-----------------------------------------------------------------*/
521 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
524 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
525 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
528 /*-----------------------------------------------------------------*
529 *-----------------------------------------------------------------*/
532 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
534 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
536 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
539 return addSet(&dynInternalRegs,reg);
544 /*-----------------------------------------------------------------*/
545 /* allocReg - allocates register of given type */
546 /*-----------------------------------------------------------------*/
548 allocReg (short type)
552 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
553 //fprintf(stderr,"allocReg\n");
555 reg = pic14_findFreeReg (type);
563 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
568 /*-----------------------------------------------------------------*/
569 /* dirregWithName - search for register by name */
570 /*-----------------------------------------------------------------*/
572 dirregWithName (char *name)
580 /* hash the name to get a key */
582 hkey = regname2key(name);
584 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
588 if(STRCASECMP(reg->name, name) == 0) {
592 reg = hTabNextItemWK (dynDirectRegNames);
596 return NULL; // name wasn't found in the hash table
599 int IS_CONFIG_ADDRESS(int address)
602 return address == 0x2007 || address == 0x2008;
605 /*-----------------------------------------------------------------*/
606 /* allocNewDirReg - allocates a new register of given type */
607 /*-----------------------------------------------------------------*/
609 allocNewDirReg (sym_link *symlnk,const char *name)
613 sym_link *spec = getSpec (symlnk);
615 /* if this is at an absolute address, then get the address. */
616 if (SPEC_ABSA (spec) ) {
617 address = SPEC_ADDR (spec);
618 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
621 /* Register wasn't found in hash, so let's create
622 * a new one and put it in the hash table AND in the
623 * dynDirectRegNames set */
624 if (IS_CONFIG_ADDRESS(address)) {
625 debugLog (" -- %s is declared at address 0x2007\n",name);
630 if (IS_BITVAR (spec))
637 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
638 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
640 if (SPEC_ABSA (spec) ) {
644 if (IS_BITVAR (spec)) {
645 addSet(&dynDirectBitRegs, reg);
648 addSet(&dynDirectRegs, reg);
650 if (!IS_STATIC (spec)) {
653 if (IS_EXTERN (spec)) {
659 if (address && reg) {
661 reg->address = address;
662 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
668 /*-----------------------------------------------------------------*/
669 /* allocDirReg - allocates register of given type */
670 /*-----------------------------------------------------------------*/
672 allocDirReg (operand *op )
679 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
683 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
685 /* If the symbol is at a fixed address, then remove the leading underscore
686 * from the name. This is hack to allow the .asm include file named registers
687 * to match the .c declared register names */
689 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
692 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
694 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
695 debugLog(" %d const char\n",__LINE__);
696 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
699 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
700 if (IS_CODE ( OP_SYM_ETYPE(op)) )
701 debugLog(" %d code space\n",__LINE__);
703 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
704 debugLog(" %d integral\n",__LINE__);
705 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
706 debugLog(" %d literal\n",__LINE__);
707 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
708 debugLog(" %d specifier\n",__LINE__);
709 debugAopGet(NULL, op);
712 if (IS_CODE ( OP_SYM_ETYPE(op)) )
715 /* First, search the hash table to see if there is a register with this name */
716 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
717 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
720 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
721 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
723 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
724 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
727 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
729 reg = dirregWithName(name);
736 /* if this is at an absolute address, then get the address. */
737 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
738 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
739 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
742 /* Register wasn't found in hash, so let's create
743 * a new one and put it in the hash table AND in the
744 * dynDirectRegNames set */
745 if(!IS_CONFIG_ADDRESS(address)) {
746 //fprintf(stderr,"allocating new reg %s\n",name);
748 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
749 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
751 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
753 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
755 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
759 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
760 addSet(&dynDirectBitRegs, reg);
763 addSet(&dynDirectRegs, reg);
765 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
768 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
774 debugLog (" -- %s is declared at address 0x2007\n",name);
779 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
781 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
782 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
787 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
789 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
790 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
793 allocNewDirReg (OP_SYM_TYPE(op),name);
800 /*-----------------------------------------------------------------*/
801 /* allocRegByName - allocates register with given name */
802 /*-----------------------------------------------------------------*/
804 allocRegByName (char *name, int size)
810 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
814 /* First, search the hash table to see if there is a register with this name */
815 reg = dirregWithName(name);
821 /* Register wasn't found in hash, so let's create
822 * a new one and put it in the hash table AND in the
823 * dynDirectRegNames set */
824 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
825 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
826 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
827 if (strcmp(reg->name+1,sym->name)==0) {
828 unsigned a = SPEC_ADDR(sym->etype);
832 if (!IS_STATIC (sym->etype)) {
835 if (IS_EXTERN (sym->etype)) {
838 if (IS_BITVAR (sym->etype))
845 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
846 if (strcmp(reg->name+1,sym->name)==0) {
847 unsigned a = SPEC_ADDR(sym->etype);
849 if (!IS_STATIC (sym->etype)) {
852 if (IS_EXTERN (sym->etype)) {
855 if (IS_BITVAR (sym->etype))
863 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
865 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
866 if (reg->isBitField) {
867 addSet(&dynDirectBitRegs, reg);
869 addSet(&dynDirectRegs, reg);
875 /*-----------------------------------------------------------------*/
876 /* RegWithIdx - returns pointer to register with index number */
877 /*-----------------------------------------------------------------*/
879 typeRegWithIdx (int idx, int type, int fixed)
884 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
889 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
891 debugLog ("Found a Dynamic Register!\n");
894 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
895 debugLog ("Found a Direct Register!\n");
901 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
902 debugLog ("Found a Stack Register!\n");
906 werror (E_STACK_OUT, "Register");
907 /* return an existing register just to avoid the SDCC crash */
908 return regWithIdx ( dynStackRegs, 0x7f, fixed);
912 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
913 debugLog ("Found a Processor Register!\n");
927 /*-----------------------------------------------------------------*/
928 /* pic14_regWithIdx - returns pointer to register with index number*/
929 /*-----------------------------------------------------------------*/
931 pic14_regWithIdx (int idx)
935 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
938 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
944 /*-----------------------------------------------------------------*/
945 /* pic14_regWithIdx - returns pointer to register with index number */
946 /*-----------------------------------------------------------------*/
948 pic14_allocWithIdx (int idx)
953 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
955 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
957 debugLog ("Found a Dynamic Register!\n");
958 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
959 debugLog ("Found a Stack Register!\n");
960 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
961 debugLog ("Found a Processor Register!\n");
962 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
963 debugLog ("Found an Internal Register!\n");
964 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
965 debugLog ("Found an Internal Register!\n");
968 debugLog ("Dynamic Register not found\n");
971 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
972 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
973 "regWithIdx not found");
983 /*-----------------------------------------------------------------*/
984 /*-----------------------------------------------------------------*/
986 pic14_findFreeReg(short type)
993 if((dReg = regFindFree(dynAllocRegs)) != NULL)
995 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
999 if((dReg = regFindFree(dynStackRegs)) != NULL)
1011 /*-----------------------------------------------------------------*/
1012 /* freeReg - frees a register */
1013 /*-----------------------------------------------------------------*/
1015 freeReg (regs * reg)
1017 debugLog ("%s\n", __FUNCTION__);
1022 /*-----------------------------------------------------------------*/
1023 /* nFreeRegs - returns number of free registers */
1024 /*-----------------------------------------------------------------*/
1026 nFreeRegs (int type)
1028 /* dynamically allocate as many as we need and worry about
1029 * fitting them into a PIC later */
1036 debugLog ("%s\n", __FUNCTION__);
1037 for (i = 0; i < pic14_nRegs; i++)
1038 if (regspic14[i].isFree && regspic14[i].type == type)
1044 /*-----------------------------------------------------------------*/
1045 /* nfreeRegsType - free registers with type */
1046 /*-----------------------------------------------------------------*/
1048 nfreeRegsType (int type)
1051 debugLog ("%s\n", __FUNCTION__);
1052 if (type == REG_PTR)
1054 if ((nfr = nFreeRegs (type)) == 0)
1055 return nFreeRegs (REG_GPR);
1058 return nFreeRegs (type);
1061 void writeSetUsedRegs(FILE *of, set *dRegs)
1066 for (dReg = setFirstItem(dRegs) ; dReg ;
1067 dReg = setNextItem(dRegs)) {
1070 fprintf (of, "\t%s\n",dReg->name);
1074 extern void assignFixedRegisters(set *regset);
1075 extern void assignRelocatableRegisters(set *regset,int used);
1076 extern void dump_map(void);
1077 extern void dump_sfr(FILE *of);
1079 void packBits(set *bregs)
1083 regs *bitfield=NULL;
1084 regs *relocbitfield=NULL;
1090 for (regset = bregs ; regset ;
1091 regset = regset->next) {
1093 breg = regset->item;
1094 breg->isBitField = 1;
1095 //fprintf(stderr,"bit reg: %s\n",breg->name);
1098 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1100 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1101 breg->rIdx = breg->address & 7;
1102 breg->address >>= 3;
1105 //sprintf (buffer, "fbitfield%02x", breg->address);
1106 sprintf (buffer, "0x%02x", breg->address);
1107 //fprintf(stderr,"new bit field\n");
1108 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1109 bitfield->isBitField = 1;
1110 bitfield->isFixed = 1;
1111 bitfield->address = breg->address;
1112 //addSet(&dynDirectRegs,bitfield);
1113 addSet(&dynInternalRegs,bitfield);
1114 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1116 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1119 breg->reg_alias = bitfield;
1123 if(!relocbitfield || bit_no >7) {
1126 sprintf (buffer, "bitfield%d", byte_no);
1127 //fprintf(stderr,"new relocatable bit field\n");
1128 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1129 relocbitfield->isBitField = 1;
1130 //addSet(&dynDirectRegs,relocbitfield);
1131 addSet(&dynInternalRegs,relocbitfield);
1132 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1136 breg->reg_alias = relocbitfield;
1137 breg->address = rDirectIdx; /* byte_no; */
1138 breg->rIdx = bit_no++;
1146 void bitEQUs(FILE *of, set *bregs)
1148 regs *breg,*bytereg;
1151 //fprintf(stderr," %s\n",__FUNCTION__);
1152 for (breg = setFirstItem(bregs) ; breg ;
1153 breg = setNextItem(bregs)) {
1155 //fprintf(stderr,"bit reg: %s\n",breg->name);
1157 bytereg = breg->reg_alias;
1159 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1162 breg->rIdx & 0x0007);
1165 //fprintf(stderr, "bit field is not assigned to a register\n");
1166 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1176 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1181 for (reg = setFirstItem(fregs) ; reg ;
1182 reg = setNextItem(fregs)) {
1184 //if(!reg->isEmitted && reg->wasUsed) {
1187 fprintf (of, "%s\tEQU\t0x%03x\n",
1191 fprintf (of, "%s\tEQU\t0x%03x\n",
1199 void writeUsedRegs(FILE *of)
1201 packBits(dynDirectBitRegs);
1203 assignFixedRegisters(dynInternalRegs);
1204 assignFixedRegisters(dynAllocRegs);
1205 assignFixedRegisters(dynStackRegs);
1206 assignFixedRegisters(dynDirectRegs);
1208 assignRelocatableRegisters(dynInternalRegs,0);
1209 assignRelocatableRegisters(dynAllocRegs,0);
1210 assignRelocatableRegisters(dynStackRegs,0);
1212 assignRelocatableRegisters(dynDirectRegs,0);
1214 assignRelocatableRegisters(dynDirectRegs,0);
1215 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1220 bitEQUs(of,dynDirectBitRegs);
1222 aliasEQUs(of,dynAllocRegs,0);
1223 aliasEQUs(of,dynDirectRegs,0);
1224 aliasEQUs(of,dynStackRegs,0);
1225 aliasEQUs(of,dynProcessorRegs,1);
1230 /*-----------------------------------------------------------------*/
1231 /* allDefsOutOfRange - all definitions are out of a range */
1232 /*-----------------------------------------------------------------*/
1234 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1238 debugLog ("%s\n", __FUNCTION__);
1242 for (i = 0; i < defs->size; i++)
1246 if (bitVectBitValue (defs, i) &&
1247 (ic = hTabItemWithKey (iCodehTab, i)) &&
1248 (ic->seq >= fseq && ic->seq <= toseq))
1258 /*-----------------------------------------------------------------*/
1259 /* computeSpillable - given a point find the spillable live ranges */
1260 /*-----------------------------------------------------------------*/
1262 computeSpillable (iCode * ic)
1266 debugLog ("%s\n", __FUNCTION__);
1267 /* spillable live ranges are those that are live at this
1268 point . the following categories need to be subtracted
1270 a) - those that are already spilt
1271 b) - if being used by this one
1272 c) - defined by this one */
1274 spillable = bitVectCopy (ic->rlive);
1276 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1278 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1279 bitVectUnSetBit (spillable, ic->defKey);
1280 spillable = bitVectIntersect (spillable, _G.regAssigned);
1285 /*-----------------------------------------------------------------*/
1286 /* noSpilLoc - return true if a variable has no spil location */
1287 /*-----------------------------------------------------------------*/
1289 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1291 debugLog ("%s\n", __FUNCTION__);
1292 return (sym->usl.spillLoc ? 0 : 1);
1295 /*-----------------------------------------------------------------*/
1296 /* hasSpilLoc - will return 1 if the symbol has spil location */
1297 /*-----------------------------------------------------------------*/
1299 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1301 debugLog ("%s\n", __FUNCTION__);
1302 return (sym->usl.spillLoc ? 1 : 0);
1305 /*-----------------------------------------------------------------*/
1306 /* directSpilLoc - will return 1 if the splilocation is in direct */
1307 /*-----------------------------------------------------------------*/
1309 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1311 debugLog ("%s\n", __FUNCTION__);
1312 if (sym->usl.spillLoc &&
1313 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1319 /*-----------------------------------------------------------------*/
1320 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1321 /* but is not used as a pointer */
1322 /*-----------------------------------------------------------------*/
1324 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1326 debugLog ("%s\n", __FUNCTION__);
1327 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1330 /*-----------------------------------------------------------------*/
1331 /* rematable - will return 1 if the remat flag is set */
1332 /*-----------------------------------------------------------------*/
1334 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1336 debugLog ("%s\n", __FUNCTION__);
1340 /*-----------------------------------------------------------------*/
1341 /* notUsedInRemaining - not used or defined in remain of the block */
1342 /*-----------------------------------------------------------------*/
1344 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1346 debugLog ("%s\n", __FUNCTION__);
1347 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1348 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1351 /*-----------------------------------------------------------------*/
1352 /* allLRs - return true for all */
1353 /*-----------------------------------------------------------------*/
1355 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1357 debugLog ("%s\n", __FUNCTION__);
1361 /*-----------------------------------------------------------------*/
1362 /* liveRangesWith - applies function to a given set of live range */
1363 /*-----------------------------------------------------------------*/
1365 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1366 eBBlock * ebp, iCode * ic)
1371 debugLog ("%s\n", __FUNCTION__);
1372 if (!lrs || !lrs->size)
1375 for (i = 1; i < lrs->size; i++)
1378 if (!bitVectBitValue (lrs, i))
1381 /* if we don't find it in the live range
1382 hash table we are in serious trouble */
1383 if (!(sym = hTabItemWithKey (liveRanges, i)))
1385 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1386 "liveRangesWith could not find liveRange");
1390 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1391 addSetHead (&rset, sym);
1398 /*-----------------------------------------------------------------*/
1399 /* leastUsedLR - given a set determines which is the least used */
1400 /*-----------------------------------------------------------------*/
1402 leastUsedLR (set * sset)
1404 symbol *sym = NULL, *lsym = NULL;
1406 debugLog ("%s\n", __FUNCTION__);
1407 sym = lsym = setFirstItem (sset);
1412 for (; lsym; lsym = setNextItem (sset))
1415 /* if usage is the same then prefer
1416 the spill the smaller of the two */
1417 if (lsym->used == sym->used)
1418 if (getSize (lsym->type) < getSize (sym->type))
1422 if (lsym->used < sym->used)
1427 setToNull ((void *) &sset);
1432 /*-----------------------------------------------------------------*/
1433 /* noOverLap - will iterate through the list looking for over lap */
1434 /*-----------------------------------------------------------------*/
1436 noOverLap (set * itmpStack, symbol * fsym)
1439 debugLog ("%s\n", __FUNCTION__);
1442 for (sym = setFirstItem (itmpStack); sym;
1443 sym = setNextItem (itmpStack))
1445 if (sym->liveTo > fsym->liveFrom)
1453 /*-----------------------------------------------------------------*/
1454 /* isFree - will return 1 if the a free spil location is found */
1455 /*-----------------------------------------------------------------*/
1460 V_ARG (symbol **, sloc);
1461 V_ARG (symbol *, fsym);
1463 debugLog ("%s\n", __FUNCTION__);
1464 /* if already found */
1468 /* if it is free && and the itmp assigned to
1469 this does not have any overlapping live ranges
1470 with the one currently being assigned and
1471 the size can be accomodated */
1473 noOverLap (sym->usl.itmpStack, fsym) &&
1474 getSize (sym->type) >= getSize (fsym->type))
1483 /*-----------------------------------------------------------------*/
1484 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1485 /*-----------------------------------------------------------------*/
1487 spillLRWithPtrReg (symbol * forSym)
1493 debugLog ("%s\n", __FUNCTION__);
1494 if (!_G.regAssigned ||
1495 bitVectIsZero (_G.regAssigned))
1498 r0 = pic14_regWithIdx (R0_IDX);
1499 r1 = pic14_regWithIdx (R1_IDX);
1501 /* for all live ranges */
1502 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1503 lrsym = hTabNextItem (liveRanges, &k))
1507 /* if no registers assigned to it or
1509 /* if it does not overlap with this then
1510 not need to spill it */
1512 if (lrsym->isspilt || !lrsym->nRegs ||
1513 (lrsym->liveTo < forSym->liveFrom))
1516 /* go thru the registers : if it is either
1517 r0 or r1 then spil it */
1518 for (j = 0; j < lrsym->nRegs; j++)
1519 if (lrsym->regs[j] == r0 ||
1520 lrsym->regs[j] == r1)
1529 /*-----------------------------------------------------------------*/
1530 /* createStackSpil - create a location on the stack to spil */
1531 /*-----------------------------------------------------------------*/
1533 createStackSpil (symbol * sym)
1535 symbol *sloc = NULL;
1536 int useXstack, model, noOverlay;
1538 char slocBuffer[30];
1539 debugLog ("%s\n", __FUNCTION__);
1543 /* first go try and find a free one that is already
1544 existing on the stack */
1545 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1547 /* found a free one : just update & return */
1548 sym->usl.spillLoc = sloc;
1551 addSetHead (&sloc->usl.itmpStack, sym);
1555 /* could not then have to create one , this is the hard part
1556 we need to allocate this on the stack : this is really a
1557 hack!! but cannot think of anything better at this time */
1559 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1561 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1562 __FILE__, __LINE__);
1566 sloc = newiTemp (slocBuffer);
1568 /* set the type to the spilling symbol */
1569 sloc->type = copyLinkChain (sym->type);
1570 sloc->etype = getSpec (sloc->type);
1571 SPEC_SCLS (sloc->etype) = S_DATA;
1572 SPEC_EXTR (sloc->etype) = 0;
1573 SPEC_STAT (sloc->etype) = 0;
1575 /* we don't allow it to be allocated`
1576 onto the external stack since : so we
1577 temporarily turn it off ; we also
1578 turn off memory model to prevent
1579 the spil from going to the external storage
1580 and turn off overlaying
1583 useXstack = options.useXstack;
1584 model = options.model;
1585 noOverlay = options.noOverlay;
1586 options.noOverlay = 1;
1587 options.model = options.useXstack = 0;
1591 options.useXstack = useXstack;
1592 options.model = model;
1593 options.noOverlay = noOverlay;
1594 sloc->isref = 1; /* to prevent compiler warning */
1596 /* if it is on the stack then update the stack */
1597 if (IN_STACK (sloc->etype))
1599 currFunc->stack += getSize (sloc->type);
1600 _G.stackExtend += getSize (sloc->type);
1603 _G.dataExtend += getSize (sloc->type);
1605 /* add it to the _G.stackSpil set */
1606 addSetHead (&_G.stackSpil, sloc);
1607 sym->usl.spillLoc = sloc;
1610 /* add it to the set of itempStack set
1611 of the spill location */
1612 addSetHead (&sloc->usl.itmpStack, sym);
1616 /*-----------------------------------------------------------------*/
1617 /* isSpiltOnStack - returns true if the spil location is on stack */
1618 /*-----------------------------------------------------------------*/
1620 isSpiltOnStack (symbol * sym)
1624 debugLog ("%s\n", __FUNCTION__);
1633 /* if (sym->_G.stackSpil) */
1636 if (!sym->usl.spillLoc)
1639 etype = getSpec (sym->usl.spillLoc->type);
1640 if (IN_STACK (etype))
1646 /*-----------------------------------------------------------------*/
1647 /* spillThis - spils a specific operand */
1648 /*-----------------------------------------------------------------*/
1650 spillThis (symbol * sym)
1653 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1654 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1656 /* if this is rematerializable or has a spillLocation
1657 we are okay, else we need to create a spillLocation
1659 if (!(sym->remat || sym->usl.spillLoc))
1660 createStackSpil (sym);
1663 /* mark it has spilt & put it in the spilt set */
1665 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1667 bitVectUnSetBit (_G.regAssigned, sym->key);
1669 for (i = 0; i < sym->nRegs; i++)
1673 freeReg (sym->regs[i]);
1674 sym->regs[i] = NULL;
1678 /* if spilt on stack then free up r0 & r1
1679 if they could have been assigned to some
1681 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1684 spillLRWithPtrReg (sym);
1687 if (sym->usl.spillLoc && !sym->remat)
1688 sym->usl.spillLoc->allocreq = 1;
1693 /*-----------------------------------------------------------------*/
1694 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1695 /*-----------------------------------------------------------------*/
1697 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1699 bitVect *lrcs = NULL;
1703 debugLog ("%s\n", __FUNCTION__);
1705 /* get the spillable live ranges */
1706 lrcs = computeSpillable (ic);
1709 /* get all live ranges that are rematerizable */
1710 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1712 /* return the least used of these */
1713 return leastUsedLR (selectS);
1716 /* get live ranges with spillLocations in direct space */
1717 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1719 sym = leastUsedLR (selectS);
1720 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1721 sym->usl.spillLoc->rname :
1722 sym->usl.spillLoc->name));
1724 /* mark it as allocation required */
1725 sym->usl.spillLoc->allocreq = 1;
1729 /* if the symbol is local to the block then */
1730 if (forSym->liveTo < ebp->lSeq)
1733 /* check if there are any live ranges allocated
1734 to registers that are not used in this block */
1735 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1737 sym = leastUsedLR (selectS);
1738 /* if this is not rematerializable */
1747 /* check if there are any live ranges that not
1748 used in the remainder of the block */
1749 if (!_G.blockSpil &&
1750 !isiCodeInFunctionCall (ic) &&
1751 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1753 sym = leastUsedLR (selectS);
1756 sym->remainSpil = 1;
1763 /* find live ranges with spillocation && not used as pointers */
1764 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1767 sym = leastUsedLR (selectS);
1768 /* mark this as allocation required */
1769 sym->usl.spillLoc->allocreq = 1;
1773 /* find live ranges with spillocation */
1774 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1777 sym = leastUsedLR (selectS);
1778 sym->usl.spillLoc->allocreq = 1;
1782 /* couldn't find then we need to create a spil
1783 location on the stack , for which one? the least
1785 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1788 /* return a created spil location */
1789 sym = createStackSpil (leastUsedLR (selectS));
1790 sym->usl.spillLoc->allocreq = 1;
1794 /* this is an extreme situation we will spill
1795 this one : happens very rarely but it does happen */
1801 /*-----------------------------------------------------------------*/
1802 /* spilSomething - spil some variable & mark registers as free */
1803 /*-----------------------------------------------------------------*/
1805 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1810 debugLog ("%s\n", __FUNCTION__);
1811 /* get something we can spil */
1812 ssym = selectSpil (ic, ebp, forSym);
1814 /* mark it as spilt */
1816 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1818 /* mark it as not register assigned &
1819 take it away from the set */
1820 bitVectUnSetBit (_G.regAssigned, ssym->key);
1822 /* mark the registers as free */
1823 for (i = 0; i < ssym->nRegs; i++)
1825 freeReg (ssym->regs[i]);
1827 /* if spilt on stack then free up r0 & r1
1828 if they could have been assigned to as gprs */
1829 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1832 spillLRWithPtrReg (ssym);
1835 /* if this was a block level spil then insert push & pop
1836 at the start & end of block respectively */
1837 if (ssym->blockSpil)
1839 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1840 /* add push to the start of the block */
1841 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1842 ebp->sch->next : ebp->sch));
1843 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1844 /* add pop to the end of the block */
1845 addiCodeToeBBlock (ebp, nic, NULL);
1848 /* if spilt because not used in the remainder of the
1849 block then add a push before this instruction and
1850 a pop at the end of the block */
1851 if (ssym->remainSpil)
1854 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1855 /* add push just before this instruction */
1856 addiCodeToeBBlock (ebp, nic, ic);
1858 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1859 /* add pop to the end of the block */
1860 addiCodeToeBBlock (ebp, nic, NULL);
1869 /*-----------------------------------------------------------------*/
1870 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1871 /*-----------------------------------------------------------------*/
1873 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1878 debugLog ("%s\n", __FUNCTION__);
1880 /* try for a ptr type */
1881 if ((reg = allocReg (REG_PTR)))
1884 /* try for gpr type */
1885 if ((reg = allocReg (REG_GPR)))
1888 /* we have to spil */
1889 if (!spilSomething (ic, ebp, sym))
1892 /* make sure partially assigned registers aren't reused */
1893 for (j=0; j<=sym->nRegs; j++)
1895 sym->regs[j]->isFree = 0;
1897 /* this looks like an infinite loop but
1898 in really selectSpil will abort */
1902 /*-----------------------------------------------------------------*/
1903 /* getRegGpr - will try for GPR if not spil */
1904 /*-----------------------------------------------------------------*/
1906 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1911 debugLog ("%s\n", __FUNCTION__);
1913 /* try for gpr type */
1914 if ((reg = allocReg (REG_GPR)))
1917 if (!pic14_ptrRegReq)
1918 if ((reg = allocReg (REG_PTR)))
1921 /* we have to spil */
1922 if (!spilSomething (ic, ebp, sym))
1925 /* make sure partially assigned registers aren't reused */
1926 for (j=0; j<=sym->nRegs; j++)
1928 sym->regs[j]->isFree = 0;
1930 /* this looks like an infinite loop but
1931 in really selectSpil will abort */
1935 /*-----------------------------------------------------------------*/
1936 /* symHasReg - symbol has a given register */
1937 /*-----------------------------------------------------------------*/
1939 symHasReg (symbol * sym, regs * reg)
1943 debugLog ("%s\n", __FUNCTION__);
1944 for (i = 0; i < sym->nRegs; i++)
1945 if (sym->regs[i] == reg)
1951 /*-----------------------------------------------------------------*/
1952 /* deassignLRs - check the live to and if they have registers & are */
1953 /* not spilt then free up the registers */
1954 /*-----------------------------------------------------------------*/
1956 deassignLRs (iCode * ic, eBBlock * ebp)
1962 debugLog ("%s\n", __FUNCTION__);
1963 for (sym = hTabFirstItem (liveRanges, &k); sym;
1964 sym = hTabNextItem (liveRanges, &k))
1967 symbol *psym = NULL;
1968 /* if it does not end here */
1969 if (sym->liveTo > ic->seq)
1972 /* Prevent the result from being assigned the same registers as (one)
1973 * operand as many genXXX-functions fail otherwise.
1974 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1975 * are known to fail. */
1976 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1980 case '=': /* assignment */
1981 case BITWISEAND: /* bitwise AND */
1982 case '|': /* bitwise OR */
1983 case '^': /* bitwise XOR */
1984 case '~': /* bitwise negate */
1985 case RLC: /* rotate through carry */
1988 case '+': /* addition */
1989 case '-': /* subtraction */
1990 /* go ahead, these are safe to use with
1991 * non-disjoint register sets */
1995 /* do not release operand registers */
1996 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
2001 /* if it was spilt on stack then we can
2002 mark the stack spil location as free */
2007 sym->usl.spillLoc->isFree = 1;
2013 if (!bitVectBitValue (_G.regAssigned, sym->key))
2015 /* special case check if this is an IFX &
2016 the privious one was a pop and the
2017 previous one was not spilt then keep track
2019 if (ic->op == IFX && ic->prev &&
2020 ic->prev->op == IPOP &&
2021 !ic->prev->parmPush &&
2022 IS_SYMOP(IC_LEFT (ic->prev)) &&
2023 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2024 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2030 bitVectUnSetBit (_G.regAssigned, sym->key);
2032 /* if the result of this one needs registers
2033 and does not have it then assign it right
2035 if (IC_RESULT (ic) &&
2036 !(SKIP_IC2 (ic) || /* not a special icode */
2037 ic->op == JUMPTABLE ||
2042 POINTER_SET (ic)) &&
2043 IS_SYMOP (IC_RESULT (ic)) &&
2044 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2045 result->liveTo > ic->seq && /* and will live beyond this */
2046 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2047 result->liveFrom == ic->seq && /* does not start before here */
2048 result->regType == sym->regType && /* same register types */
2049 result->regType == sym->regType && /* same register types */
2050 result->nRegs && /* which needs registers */
2051 !result->isspilt && /* and does not already have them */
2053 !bitVectBitValue (_G.regAssigned, result->key) &&
2054 /* the number of free regs + number of regs in this LR
2055 can accomodate the what result Needs */
2056 ((nfreeRegsType (result->regType) +
2057 sym->nRegs) >= result->nRegs)
2061 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2063 result->regs[i] = sym->regs[i];
2065 result->regs[i] = getRegGpr (ic, ebp, result);
2067 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2071 /* free the remaining */
2072 for (; i < sym->nRegs; i++)
2076 if (!symHasReg (psym, sym->regs[i]))
2077 freeReg (sym->regs[i]);
2080 freeReg (sym->regs[i]);
2087 /*-----------------------------------------------------------------*/
2088 /* reassignLR - reassign this to registers */
2089 /*-----------------------------------------------------------------*/
2091 reassignLR (operand * op)
2093 symbol *sym = OP_SYMBOL (op);
2096 debugLog ("%s\n", __FUNCTION__);
2097 /* not spilt any more */
2098 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2099 bitVectUnSetBit (_G.spiltSet, sym->key);
2101 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2105 for (i = 0; i < sym->nRegs; i++)
2106 sym->regs[i]->isFree = 0;
2109 /*-----------------------------------------------------------------*/
2110 /* willCauseSpill - determines if allocating will cause a spill */
2111 /*-----------------------------------------------------------------*/
2113 willCauseSpill (int nr, int rt)
2115 debugLog ("%s\n", __FUNCTION__);
2116 /* first check if there are any avlb registers
2117 of te type required */
2120 /* special case for pointer type
2121 if pointer type not avlb then
2122 check for type gpr */
2123 if (nFreeRegs (rt) >= nr)
2125 if (nFreeRegs (REG_GPR) >= nr)
2130 if (pic14_ptrRegReq)
2132 if (nFreeRegs (rt) >= nr)
2137 if (nFreeRegs (REG_PTR) +
2138 nFreeRegs (REG_GPR) >= nr)
2143 debugLog (" ... yep it will (cause a spill)\n");
2144 /* it will cause a spil */
2148 /*-----------------------------------------------------------------*/
2149 /* positionRegs - the allocator can allocate same registers to res- */
2150 /* ult and operand, if this happens make sure they are in the same */
2151 /* position as the operand otherwise chaos results */
2152 /*-----------------------------------------------------------------*/
2154 positionRegs (symbol * result, symbol * opsym, int lineno)
2156 int count = min (result->nRegs, opsym->nRegs);
2157 int i, j = 0, shared = 0;
2159 debugLog ("%s\n", __FUNCTION__);
2160 /* if the result has been spilt then cannot share */
2165 /* first make sure that they actually share */
2166 for (i = 0; i < count; i++)
2168 for (j = 0; j < count; j++)
2170 if (result->regs[i] == opsym->regs[j] && i != j)
2180 regs *tmp = result->regs[i];
2181 result->regs[i] = result->regs[j];
2182 result->regs[j] = tmp;
2187 /*------------------------------------------------------------------*/
2188 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2189 /* it should either have registers or have beed spilled. Otherwise, */
2190 /* there was an uninitialized variable, so just spill this to get */
2191 /* the operand in a valid state. */
2192 /*------------------------------------------------------------------*/
2194 verifyRegsAssigned (operand *op, iCode * ic)
2199 if (!IS_ITEMP (op)) return;
2201 sym = OP_SYMBOL (op);
2202 if (sym->isspilt) return;
2203 if (!sym->nRegs) return;
2204 if (sym->regs[0]) return;
2206 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2207 sym->prereqv ? sym->prereqv->name : sym->name);
2212 /*-----------------------------------------------------------------*/
2213 /* serialRegAssign - serially allocate registers to the variables */
2214 /*-----------------------------------------------------------------*/
2216 serialRegAssign (eBBlock ** ebbs, int count)
2220 debugLog ("%s\n", __FUNCTION__);
2221 /* for all blocks */
2222 for (i = 0; i < count; i++)
2227 if (ebbs[i]->noPath &&
2228 (ebbs[i]->entryLabel != entryLabel &&
2229 ebbs[i]->entryLabel != returnLabel))
2232 /* of all instructions do */
2233 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2235 debugLog (" op: %s\n", decodeOp (ic->op));
2237 /* if this is an ipop that means some live
2238 range will have to be assigned again */
2240 reassignLR (IC_LEFT (ic));
2242 /* if result is present && is a true symbol */
2243 if (IC_RESULT (ic) && ic->op != IFX &&
2244 IS_TRUE_SYMOP (IC_RESULT (ic)))
2245 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2247 /* take away registers from live
2248 ranges that end at this instruction */
2249 deassignLRs (ic, ebbs[i]);
2251 /* some don't need registers */
2252 if (SKIP_IC2 (ic) ||
2253 ic->op == JUMPTABLE ||
2257 (IC_RESULT (ic) && POINTER_SET (ic)))
2260 /* now we need to allocate registers
2261 only for the result */
2262 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2264 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2270 /* Make sure any spill location is definately allocated */
2271 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2272 !sym->usl.spillLoc->allocreq)
2274 sym->usl.spillLoc->allocreq++;
2277 /* if it does not need or is spilt
2278 or is already assigned to registers
2279 or will not live beyond this instructions */
2282 bitVectBitValue (_G.regAssigned, sym->key) ||
2283 sym->liveTo <= ic->seq)
2286 /* if some liverange has been spilt at the block level
2287 and this one live beyond this block then spil this
2289 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2294 /* if trying to allocate this will cause
2295 a spill and there is nothing to spill
2296 or this one is rematerializable then
2298 willCS = willCauseSpill (sym->nRegs, sym->regType);
2299 spillable = computeSpillable (ic);
2301 (willCS && bitVectIsZero (spillable)))
2309 /* If the live range preceeds the point of definition
2310 then ideally we must take into account registers that
2311 have been allocated after sym->liveFrom but freed
2312 before ic->seq. This is complicated, so spill this
2313 symbol instead and let fillGaps handle the allocation. */
2314 if (sym->liveFrom < ic->seq)
2320 /* if it has a spillocation & is used less than
2321 all other live ranges then spill this */
2323 if (sym->usl.spillLoc) {
2324 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2325 allLRs, ebbs[i], ic));
2326 if (leastUsed && leastUsed->used > sym->used) {
2331 /* if none of the liveRanges have a spillLocation then better
2332 to spill this one than anything else already assigned to registers */
2333 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2334 /* if this is local to this block then we might find a block spil */
2335 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2343 if (ic->op == RECEIVE)
2344 debugLog ("When I get clever, I'll optimize the receive logic\n");
2346 /* if we need ptr regs for the right side
2348 if (POINTER_GET (ic)
2349 && IS_SYMOP(IC_LEFT(ic))
2350 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2351 <= (unsigned) PTRSIZE)
2356 /* else we assign registers to it */
2357 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2359 debugLog (" %d - \n", __LINE__);
2361 bitVectDebugOn(_G.regAssigned, debugF);
2362 for (j = 0; j < sym->nRegs; j++)
2364 if (sym->regType == REG_PTR)
2365 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2367 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2369 /* if the allocation failed which means
2370 this was spilt then break */
2374 debugLog (" %d - \n", __LINE__);
2376 /* if it shares registers with operands make sure
2377 that they are in the same position */
2378 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2379 IS_SYMOP(IC_RESULT(ic)) &&
2380 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2381 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2382 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2383 /* do the same for the right operand */
2384 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2385 IS_SYMOP(IC_RESULT(ic)) &&
2386 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2387 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2388 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2390 debugLog (" %d - \n", __LINE__);
2393 debugLog (" %d - \n", __LINE__);
2402 /* Check for and fix any problems with uninitialized operands */
2403 for (i = 0; i < count; i++)
2407 if (ebbs[i]->noPath &&
2408 (ebbs[i]->entryLabel != entryLabel &&
2409 ebbs[i]->entryLabel != returnLabel))
2412 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2419 verifyRegsAssigned (IC_COND (ic), ic);
2423 if (ic->op == JUMPTABLE)
2425 verifyRegsAssigned (IC_JTCOND (ic), ic);
2429 verifyRegsAssigned (IC_RESULT (ic), ic);
2430 verifyRegsAssigned (IC_LEFT (ic), ic);
2431 verifyRegsAssigned (IC_RIGHT (ic), ic);
2437 /*-----------------------------------------------------------------*/
2438 /* rUmaskForOp :- returns register mask for an operand */
2439 /*-----------------------------------------------------------------*/
2441 rUmaskForOp (operand * op)
2447 debugLog ("%s\n", __FUNCTION__);
2448 /* only temporaries are assigned registers */
2452 sym = OP_SYMBOL (op);
2454 /* if spilt or no registers assigned to it
2456 if (sym->isspilt || !sym->nRegs)
2459 rumask = newBitVect (pic14_nRegs);
2461 for (j = 0; j < sym->nRegs; j++)
2463 rumask = bitVectSetBit (rumask,
2464 sym->regs[j]->rIdx);
2470 /*-----------------------------------------------------------------*/
2471 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2472 /*-----------------------------------------------------------------*/
2474 regsUsedIniCode (iCode * ic)
2476 bitVect *rmask = newBitVect (pic14_nRegs);
2478 debugLog ("%s\n", __FUNCTION__);
2479 /* do the special cases first */
2482 rmask = bitVectUnion (rmask,
2483 rUmaskForOp (IC_COND (ic)));
2487 /* for the jumptable */
2488 if (ic->op == JUMPTABLE)
2490 rmask = bitVectUnion (rmask,
2491 rUmaskForOp (IC_JTCOND (ic)));
2496 /* of all other cases */
2498 rmask = bitVectUnion (rmask,
2499 rUmaskForOp (IC_LEFT (ic)));
2503 rmask = bitVectUnion (rmask,
2504 rUmaskForOp (IC_RIGHT (ic)));
2507 rmask = bitVectUnion (rmask,
2508 rUmaskForOp (IC_RESULT (ic)));
2514 /*-----------------------------------------------------------------*/
2515 /* createRegMask - for each instruction will determine the regsUsed */
2516 /*-----------------------------------------------------------------*/
2518 createRegMask (eBBlock ** ebbs, int count)
2522 debugLog ("%s\n", __FUNCTION__);
2523 /* for all blocks */
2524 for (i = 0; i < count; i++)
2528 if (ebbs[i]->noPath &&
2529 (ebbs[i]->entryLabel != entryLabel &&
2530 ebbs[i]->entryLabel != returnLabel))
2533 /* for all instructions */
2534 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2539 if (SKIP_IC2 (ic) || !ic->rlive)
2542 /* first mark the registers used in this
2544 ic->rUsed = regsUsedIniCode (ic);
2545 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2547 /* now create the register mask for those
2548 registers that are in use : this is a
2549 super set of ic->rUsed */
2550 ic->rMask = newBitVect (pic14_nRegs + 1);
2552 /* for all live Ranges alive at this point */
2553 for (j = 1; j < ic->rlive->size; j++)
2558 /* if not alive then continue */
2559 if (!bitVectBitValue (ic->rlive, j))
2562 /* find the live range we are interested in */
2563 if (!(sym = hTabItemWithKey (liveRanges, j)))
2565 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2566 "createRegMask cannot find live range");
2570 /* if no register assigned to it */
2571 if (!sym->nRegs || sym->isspilt)
2574 /* for all the registers allocated to it */
2575 for (k = 0; k < sym->nRegs; k++)
2578 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2584 /* This was the active version */
2585 /*-----------------------------------------------------------------*/
2586 /* rematStr - returns the rematerialized string for a remat var */
2587 /*-----------------------------------------------------------------*/
2589 rematStr (symbol * sym)
2592 iCode *ic = sym->rematiCode;
2593 symbol *psym = NULL;
2595 debugLog ("%s\n", __FUNCTION__);
2597 //printf ("%s\n", s);
2599 /* if plus or minus print the right hand side */
2601 if (ic->op == '+' || ic->op == '-') {
2603 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2605 sprintf (s, "(%s %c 0x%04x)",
2606 OP_SYMBOL (IC_LEFT (ric))->rname,
2608 (int) operandLitValue (IC_RIGHT (ic)));
2611 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2613 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2614 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2619 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2620 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2622 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2628 /* deprecated version */
2629 /*-----------------------------------------------------------------*/
2630 /* rematStr - returns the rematerialized string for a remat var */
2631 /*-----------------------------------------------------------------*/
2633 rematStr (symbol * sym)
2636 iCode *ic = sym->rematiCode;
2638 debugLog ("%s\n", __FUNCTION__);
2643 /* if plus or minus print the right hand side */
2645 if (ic->op == '+' || ic->op == '-') {
2646 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2649 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2653 if (ic->op == '+' || ic->op == '-')
2655 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2656 sprintf (s, "(%s %c 0x%04x)",
2657 OP_SYMBOL (IC_LEFT (ric))->rname,
2659 (int) operandLitValue (IC_RIGHT (ic)));
2662 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2664 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2668 /* we reached the end */
2669 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2673 printf ("%s\n", buffer);
2678 /*-----------------------------------------------------------------*/
2679 /* regTypeNum - computes the type & number of registers required */
2680 /*-----------------------------------------------------------------*/
2688 debugLog ("%s\n", __FUNCTION__);
2689 /* for each live range do */
2690 for (sym = hTabFirstItem (liveRanges, &k); sym;
2691 sym = hTabNextItem (liveRanges, &k)) {
2693 debugLog (" %d - %s\n", __LINE__, sym->rname);
2695 /* if used zero times then no registers needed */
2696 if ((sym->liveTo - sym->liveFrom) == 0)
2700 /* if the live range is a temporary */
2703 debugLog (" %d - itemp register\n", __LINE__);
2705 /* if the type is marked as a conditional */
2706 if (sym->regType == REG_CND)
2709 /* if used in return only then we don't
2712 if (IS_AGGREGATE (sym->type) || sym->isptr)
2713 sym->type = aggrToPtr (sym->type, FALSE);
2714 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2720 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2721 // sym->type = aggrToPtr (sym->type, FALSE);
2722 debugLog (" %d - used as a return\n", __LINE__);
2727 /* if the symbol has only one definition &
2728 that definition is a get_pointer and the
2729 pointer we are getting is rematerializable and
2733 if (bitVectnBitsOn (sym->defs) == 1 &&
2734 (ic = hTabItemWithKey (iCodehTab,
2735 bitVectFirstBit (sym->defs))) &&
2737 !IS_BITVAR (sym->etype) &&
2738 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2740 if (ptrPseudoSymSafe (sym, ic)) {
2744 debugLog (" %d - \n", __LINE__);
2746 /* create a pseudo symbol & force a spil */
2747 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2748 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2749 psym->type = sym->type;
2750 psym->etype = sym->etype;
2751 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2752 strcpy (psym->rname, psym->name);
2754 sym->usl.spillLoc = psym;
2758 /* if in data space or idata space then try to
2759 allocate pointer register */
2764 /* if not then we require registers */
2765 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2766 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2767 getSize (sym->type));
2770 if(IS_PTR_CONST (sym->type)) {
2771 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2775 if (sym->nRegs > 4) {
2776 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2777 printTypeChain (sym->type, stderr);
2778 fprintf (stderr, "\n");
2781 /* determine the type of register required */
2782 if (sym->nRegs == 1 &&
2783 IS_PTR (sym->type) &&
2785 sym->regType = REG_PTR;
2787 sym->regType = REG_GPR;
2790 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2794 /* for the first run we don't provide */
2795 /* registers for true symbols we will */
2796 /* see how things go */
2801 DEFSETFUNC (markRegFree)
2803 ((regs *)item)->isFree = 1;
2808 DEFSETFUNC (deallocReg)
2810 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2811 ((regs *)item)->isFree = 1;
2812 ((regs *)item)->wasUsed = 0;
2816 /*-----------------------------------------------------------------*/
2817 /* freeAllRegs - mark all registers as free */
2818 /*-----------------------------------------------------------------*/
2820 pic14_freeAllRegs ()
2824 debugLog ("%s\n", __FUNCTION__);
2826 applyToSet(dynAllocRegs,markRegFree);
2827 applyToSet(dynStackRegs,markRegFree);
2830 for (i = 0; i < pic14_nRegs; i++)
2831 regspic14[i].isFree = 1;
2835 /*-----------------------------------------------------------------*/
2836 /*-----------------------------------------------------------------*/
2838 pic14_deallocateAllRegs ()
2842 debugLog ("%s\n", __FUNCTION__);
2844 applyToSet(dynAllocRegs,deallocReg);
2847 for (i = 0; i < pic14_nRegs; i++) {
2848 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2849 regspic14[i].isFree = 1;
2850 regspic14[i].wasUsed = 0;
2857 /*-----------------------------------------------------------------*/
2858 /* deallocStackSpil - this will set the stack pointer back */
2859 /*-----------------------------------------------------------------*/
2861 DEFSETFUNC (deallocStackSpil)
2865 debugLog ("%s\n", __FUNCTION__);
2870 /*-----------------------------------------------------------------*/
2871 /* farSpacePackable - returns the packable icode for far variables */
2872 /*-----------------------------------------------------------------*/
2874 farSpacePackable (iCode * ic)
2878 debugLog ("%s\n", __FUNCTION__);
2879 /* go thru till we find a definition for the
2880 symbol on the right */
2881 for (dic = ic->prev; dic; dic = dic->prev)
2884 /* if the definition is a call then no */
2885 if ((dic->op == CALL || dic->op == PCALL) &&
2886 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2891 /* if shift by unknown amount then not */
2892 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2893 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2896 /* if pointer get and size > 1 */
2897 if (POINTER_GET (dic) &&
2898 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2901 if (POINTER_SET (dic) &&
2902 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2905 /* if any three is a true symbol in far space */
2906 if (IC_RESULT (dic) &&
2907 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2908 isOperandInFarSpace (IC_RESULT (dic)))
2911 if (IC_RIGHT (dic) &&
2912 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2913 isOperandInFarSpace (IC_RIGHT (dic)) &&
2914 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2917 if (IC_LEFT (dic) &&
2918 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2919 isOperandInFarSpace (IC_LEFT (dic)) &&
2920 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2923 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2925 if ((dic->op == LEFT_OP ||
2926 dic->op == RIGHT_OP ||
2928 IS_OP_LITERAL (IC_RIGHT (dic)))
2938 /*-----------------------------------------------------------------*/
2939 /* packRegsForAssign - register reduction for assignment */
2940 /*-----------------------------------------------------------------*/
2942 packRegsForAssign (iCode * ic, eBBlock * ebp)
2947 debugLog ("%s\n", __FUNCTION__);
2949 debugAopGet (" result:", IC_RESULT (ic));
2950 debugAopGet (" left:", IC_LEFT (ic));
2951 debugAopGet (" right:", IC_RIGHT (ic));
2953 /* if this is at an absolute address, then get the address. */
2954 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2955 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2956 debugLog (" %d - found config word declaration\n", __LINE__);
2957 if(IS_VALOP(IC_RIGHT(ic))) {
2958 debugLog (" setting config word to %x\n",
2959 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2960 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2961 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2964 /* remove the assignment from the iCode chain. */
2966 remiCodeFromeBBlock (ebp, ic);
2967 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2968 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2975 if (!IS_ITEMP (IC_RESULT (ic))) {
2976 allocDirReg(IC_RESULT (ic));
2977 debugLog (" %d - result is not temp\n", __LINE__);
2980 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2981 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2982 allocDirReg(IC_LEFT (ic));
2986 if (!IS_ITEMP (IC_RIGHT (ic))) {
2987 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2989 /* only pack if this is not a function pointer */
2990 if (!IS_REF (IC_RIGHT (ic)))
2991 allocDirReg(IC_RIGHT (ic));
2995 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2996 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2998 debugLog (" %d - not packing - right side fails \n", __LINE__);
3002 /* if the true symbol is defined in far space or on stack
3003 then we should not since this will increase register pressure */
3004 if (isOperandInFarSpace (IC_RESULT (ic)))
3006 if ((dic = farSpacePackable (ic)))
3012 /* find the definition of iTempNN scanning backwards if we find a
3013 a use of the true symbol before we find the definition then
3015 for (dic = ic->prev; dic; dic = dic->prev)
3018 /* if there is a function call and this is
3019 a parameter & not my parameter then don't pack it */
3020 if ((dic->op == CALL || dic->op == PCALL) &&
3021 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3022 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3024 debugLog (" %d - \n", __LINE__);
3032 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3033 IS_OP_VOLATILE (IC_RESULT (dic)))
3035 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3040 if (IS_SYMOP (IC_RESULT (dic)) &&
3041 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3043 /* A previous result was assigned to the same register - we'll our definition */
3044 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3045 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3046 if (POINTER_SET (dic))
3052 if (IS_SYMOP (IC_RIGHT (dic)) &&
3053 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3054 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3056 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3061 if (IS_SYMOP (IC_LEFT (dic)) &&
3062 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3063 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3065 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3070 if (POINTER_SET (dic) &&
3071 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3073 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3081 return 0; /* did not find */
3083 /* if the result is on stack or iaccess then it must be
3084 the same at least one of the operands */
3085 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3086 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3089 /* the operation has only one symbol
3090 operator then we can pack */
3091 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3092 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3095 if (!((IC_LEFT (dic) &&
3096 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3098 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3102 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3103 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3104 /* found the definition */
3105 /* replace the result with the result of */
3106 /* this assignment and remove this assignment */
3107 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3108 IC_RESULT (dic) = IC_RESULT (ic);
3110 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3112 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3114 /* delete from liverange table also
3115 delete from all the points inbetween and the new
3117 for (sic = dic; sic != ic; sic = sic->next)
3119 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3120 if (IS_ITEMP (IC_RESULT (dic)))
3121 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3124 remiCodeFromeBBlock (ebp, ic);
3125 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3126 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3127 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3133 /*-----------------------------------------------------------------*/
3134 /* findAssignToSym : scanning backwards looks for first assig found */
3135 /*-----------------------------------------------------------------*/
3137 findAssignToSym (operand * op, iCode * ic)
3141 debugLog ("%s\n", __FUNCTION__);
3142 for (dic = ic->prev; dic; dic = dic->prev)
3145 /* if definition by assignment */
3146 if (dic->op == '=' &&
3147 !POINTER_SET (dic) &&
3148 IC_RESULT (dic)->key == op->key
3149 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3153 /* we are interested only if defined in far space */
3154 /* or in stack space in case of + & - */
3156 /* if assigned to a non-symbol then return
3158 if (!IS_SYMOP (IC_RIGHT (dic)))
3161 /* if the symbol is in far space then
3163 if (isOperandInFarSpace (IC_RIGHT (dic)))
3166 /* for + & - operations make sure that
3167 if it is on the stack it is the same
3168 as one of the three operands */
3169 if ((ic->op == '+' || ic->op == '-') &&
3170 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3173 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3174 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3175 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3183 /* if we find an usage then we cannot delete it */
3184 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3187 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3190 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3194 /* now make sure that the right side of dic
3195 is not defined between ic & dic */
3198 iCode *sic = dic->next;
3200 for (; sic != ic; sic = sic->next)
3201 if (IC_RESULT (sic) &&
3202 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3211 /*-----------------------------------------------------------------*/
3212 /* packRegsForSupport :- reduce some registers for support calls */
3213 /*-----------------------------------------------------------------*/
3215 packRegsForSupport (iCode * ic, eBBlock * ebp)
3219 debugLog ("%s\n", __FUNCTION__);
3220 /* for the left & right operand :- look to see if the
3221 left was assigned a true symbol in far space in that
3222 case replace them */
3223 if (IS_ITEMP (IC_LEFT (ic)) &&
3224 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3226 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3232 debugAopGet ("removing left:", IC_LEFT (ic));
3234 /* found it we need to remove it from the
3236 for (sic = dic; sic != ic; sic = sic->next)
3237 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3239 IC_LEFT (ic)->operand.symOperand =
3240 IC_RIGHT (dic)->operand.symOperand;
3241 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3242 remiCodeFromeBBlock (ebp, dic);
3243 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3244 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3248 /* do the same for the right operand */
3251 IS_ITEMP (IC_RIGHT (ic)) &&
3252 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3254 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3260 /* if this is a subtraction & the result
3261 is a true symbol in far space then don't pack */
3262 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3264 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3265 if (IN_FARSPACE (SPEC_OCLS (etype)))
3269 debugAopGet ("removing right:", IC_RIGHT (ic));
3271 /* found it we need to remove it from the
3273 for (sic = dic; sic != ic; sic = sic->next)
3274 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3276 IC_RIGHT (ic)->operand.symOperand =
3277 IC_RIGHT (dic)->operand.symOperand;
3278 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3280 remiCodeFromeBBlock (ebp, dic);
3281 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3282 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3289 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3292 /*-----------------------------------------------------------------*/
3293 /* packRegsForOneuse : - will reduce some registers for single Use */
3294 /*-----------------------------------------------------------------*/
3296 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3301 debugLog ("%s\n", __FUNCTION__);
3302 /* if returning a literal then do nothing */
3306 /* only upto 2 bytes since we cannot predict
3307 the usage of b, & acc */
3308 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3313 /* this routine will mark the a symbol as used in one
3314 instruction use only && if the definition is local
3315 (ie. within the basic block) && has only one definition &&
3316 that definition is either a return value from a
3317 function or does not contain any variables in
3319 uses = bitVectCopy (OP_USES (op));
3320 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3321 if (!bitVectIsZero (uses)) /* has other uses */
3324 /* if it has only one defintion */
3325 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3326 return NULL; /* has more than one definition */
3328 /* get that definition */
3330 hTabItemWithKey (iCodehTab,
3331 bitVectFirstBit (OP_DEFS (op)))))
3334 /* found the definition now check if it is local */
3335 if (dic->seq < ebp->fSeq ||
3336 dic->seq > ebp->lSeq)
3337 return NULL; /* non-local */
3339 /* now check if it is the return from
3341 if (dic->op == CALL || dic->op == PCALL)
3343 if (ic->op != SEND && ic->op != RETURN &&
3344 !POINTER_SET(ic) && !POINTER_GET(ic))
3346 OP_SYMBOL (op)->ruonly = 1;
3353 /* otherwise check that the definition does
3354 not contain any symbols in far space */
3355 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3356 isOperandInFarSpace (IC_RIGHT (dic)) ||
3357 IS_OP_RUONLY (IC_LEFT (ic)) ||
3358 IS_OP_RUONLY (IC_RIGHT (ic)))
3363 /* if pointer set then make sure the pointer
3365 if (POINTER_SET (dic) &&
3366 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3369 if (POINTER_GET (dic) &&
3370 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3375 /* also make sure the intervenening instructions
3376 don't have any thing in far space */
3377 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3380 /* if there is an intervening function call then no */
3381 if (dic->op == CALL || dic->op == PCALL)
3383 /* if pointer set then make sure the pointer
3385 if (POINTER_SET (dic) &&
3386 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3389 if (POINTER_GET (dic) &&
3390 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3393 /* if address of & the result is remat then okay */
3394 if (dic->op == ADDRESS_OF &&
3395 OP_SYMBOL (IC_RESULT (dic))->remat)
3398 /* if operand has size of three or more & this
3399 operation is a '*','/' or '%' then 'b' may
3401 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3402 getSize (operandType (op)) >= 3)
3405 /* if left or right or result is in far space */
3406 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3407 isOperandInFarSpace (IC_RIGHT (dic)) ||
3408 isOperandInFarSpace (IC_RESULT (dic)) ||
3409 IS_OP_RUONLY (IC_LEFT (dic)) ||
3410 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3411 IS_OP_RUONLY (IC_RESULT (dic)))
3417 OP_SYMBOL (op)->ruonly = 1;
3422 /*-----------------------------------------------------------------*/
3423 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3424 /*-----------------------------------------------------------------*/
3426 isBitwiseOptimizable (iCode * ic)
3428 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3429 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3431 debugLog ("%s\n", __FUNCTION__);
3432 /* bitwise operations are considered optimizable
3433 under the following conditions (Jean-Louis VERN)
3445 if (IS_LITERAL (rtype) ||
3446 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3452 /*-----------------------------------------------------------------*/
3453 /* packRegsForAccUse - pack registers for acc use */
3454 /*-----------------------------------------------------------------*/
3456 packRegsForAccUse (iCode * ic)
3460 debugLog ("%s\n", __FUNCTION__);
3462 /* result too large for WREG? */
3463 if (getSize (operandType (IC_RESULT (ic))) > 1)
3466 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3467 * is never used as an operand to an instruction that
3468 * cannot have WREG as an operand (e.g. BTFSx cannot
3469 * operate on WREG...
3470 * For now, store all results into proper registers. */
3474 /* if this is an aggregate, e.g. a one byte char array */
3475 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3478 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3480 /* if + or - then it has to be one byte result */
3481 if ((ic->op == '+' || ic->op == '-')
3482 && getSize (operandType (IC_RESULT (ic))) > 1)
3485 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3486 /* if shift operation make sure right side is not a literal */
3487 if (ic->op == RIGHT_OP &&
3488 (isOperandLiteral (IC_RIGHT (ic)) ||
3489 getSize (operandType (IC_RESULT (ic))) > 1))
3492 if (ic->op == LEFT_OP &&
3493 (isOperandLiteral (IC_RIGHT (ic)) ||
3494 getSize (operandType (IC_RESULT (ic))) > 1))
3497 if (IS_BITWISE_OP (ic) &&
3498 getSize (operandType (IC_RESULT (ic))) > 1)
3502 /* has only one definition */
3503 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3506 /* has only one use */
3507 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3510 /* and the usage immediately follows this iCode */
3511 if (!(uic = hTabItemWithKey (iCodehTab,
3512 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3515 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3516 if (ic->next != uic)
3519 /* if it is a conditional branch then we definitely can */
3523 if (uic->op == JUMPTABLE)
3526 /* if the usage is not is an assignment
3527 or an arithmetic / bitwise / shift operation then not */
3528 if (POINTER_SET (uic) &&
3529 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3532 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3533 if (uic->op != '=' &&
3534 !IS_ARITHMETIC_OP (uic) &&
3535 !IS_BITWISE_OP (uic) &&
3536 uic->op != LEFT_OP &&
3537 uic->op != RIGHT_OP)
3540 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3541 /* if used in ^ operation then make sure right is not a
3543 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3546 /* if shift operation make sure right side is not a literal */
3547 if (uic->op == RIGHT_OP &&
3548 (isOperandLiteral (IC_RIGHT (uic)) ||
3549 getSize (operandType (IC_RESULT (uic))) > 1))
3552 if (uic->op == LEFT_OP &&
3553 (isOperandLiteral (IC_RIGHT (uic)) ||
3554 getSize (operandType (IC_RESULT (uic))) > 1))
3557 /* make sure that the result of this icode is not on the
3558 stack, since acc is used to compute stack offset */
3559 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3560 OP_SYMBOL (IC_RESULT (uic))->onStack)
3563 /* if either one of them in far space then we cannot */
3564 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3565 isOperandInFarSpace (IC_LEFT (uic))) ||
3566 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3567 isOperandInFarSpace (IC_RIGHT (uic))))
3570 /* if the usage has only one operand then we can */
3571 if (IC_LEFT (uic) == NULL ||
3572 IC_RIGHT (uic) == NULL)
3575 /* make sure this is on the left side if not
3576 a '+' since '+' is commutative */
3577 if (ic->op != '+' &&
3578 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3581 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3582 /* if one of them is a literal then we can */
3583 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3584 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3585 (getSize (operandType (IC_RESULT (uic))) <= 1))
3587 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3591 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3592 /* if the other one is not on stack then we can */
3593 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3594 (IS_ITEMP (IC_RIGHT (uic)) ||
3595 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3596 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3599 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3600 (IS_ITEMP (IC_LEFT (uic)) ||
3601 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3602 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3608 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3609 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3613 /*-----------------------------------------------------------------*/
3614 /* packForPush - hueristics to reduce iCode for pushing */
3615 /*-----------------------------------------------------------------*/
3617 packForReceive (iCode * ic, eBBlock * ebp)
3621 debugLog ("%s\n", __FUNCTION__);
3622 debugAopGet (" result:", IC_RESULT (ic));
3623 debugAopGet (" left:", IC_LEFT (ic));
3624 debugAopGet (" right:", IC_RIGHT (ic));
3629 for (dic = ic->next; dic; dic = dic->next)
3634 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3635 debugLog (" used on left\n");
3636 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3637 debugLog (" used on right\n");
3638 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3639 debugLog (" used on result\n");
3641 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3642 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3647 debugLog (" hey we can remove this unnecessary assign\n");
3649 /*-----------------------------------------------------------------*/
3650 /* packForPush - hueristics to reduce iCode for pushing */
3651 /*-----------------------------------------------------------------*/
3653 packForPush (iCode * ic, eBBlock * ebp)
3657 debugLog ("%s\n", __FUNCTION__);
3658 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3661 /* must have only definition & one usage */
3662 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3663 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3666 /* find the definition */
3667 if (!(dic = hTabItemWithKey (iCodehTab,
3668 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3671 if (dic->op != '=' || POINTER_SET (dic))
3674 /* we now we know that it has one & only one def & use
3675 and the that the definition is an assignment */
3676 IC_LEFT (ic) = IC_RIGHT (dic);
3678 remiCodeFromeBBlock (ebp, dic);
3679 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3680 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3683 void printSymType(char * str, sym_link *sl)
3685 debugLog (" %s Symbol type: ",str);
3686 printTypeChain( sl, debugF);
3691 /*-----------------------------------------------------------------*/
3692 /* some debug code to print the symbol S_TYPE. Note that
3693 * the function checkSClass in src/SDCCsymt.c dinks with
3694 * the S_TYPE in ways the PIC port doesn't fully like...*/
3695 /*-----------------------------------------------------------------*/
3696 void isData(sym_link *sl)
3706 for ( ; sl; sl=sl->next) {
3708 switch (SPEC_SCLS(sl)) {
3710 case S_DATA: fprintf (of, "data "); break;
3711 case S_XDATA: fprintf (of, "xdata "); break;
3712 case S_SFR: fprintf (of, "sfr "); break;
3713 case S_SBIT: fprintf (of, "sbit "); break;
3714 case S_CODE: fprintf (of, "code "); break;
3715 case S_IDATA: fprintf (of, "idata "); break;
3716 case S_PDATA: fprintf (of, "pdata "); break;
3717 case S_LITERAL: fprintf (of, "literal "); break;
3718 case S_STACK: fprintf (of, "stack "); break;
3719 case S_XSTACK: fprintf (of, "xstack "); break;
3720 case S_BIT: fprintf (of, "bit "); break;
3721 case S_EEPROM: fprintf (of, "eeprom "); break;
3731 /*-----------------------------------------------------------------*/
3732 /* packRegisters - does some transformations to reduce register */
3734 /*-----------------------------------------------------------------*/
3736 packRegisters (eBBlock * ebp)
3741 debugLog ("%s\n", __FUNCTION__);
3747 /* look for assignments of the form */
3748 /* iTempNN = TRueSym (someoperation) SomeOperand */
3750 /* TrueSym := iTempNN:1 */
3751 for (ic = ebp->sch; ic; ic = ic->next)
3754 /* find assignment of the form TrueSym := iTempNN:1 */
3755 if (ic->op == '=' && !POINTER_SET (ic))
3756 change += packRegsForAssign (ic, ebp);
3760 if (POINTER_SET (ic))
3761 debugLog ("pointer is set\n");
3762 debugAopGet (" result:", IC_RESULT (ic));
3763 debugAopGet (" left:", IC_LEFT (ic));
3764 debugAopGet (" right:", IC_RIGHT (ic));
3773 for (ic = ebp->sch; ic; ic = ic->next) {
3775 if(IS_SYMOP ( IC_LEFT(ic))) {
3776 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3778 debugAopGet (" left:", IC_LEFT (ic));
3779 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3780 debugLog (" is a pointer\n");
3782 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3783 debugLog (" is volatile\n");
3787 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3790 if(IS_SYMOP ( IC_RIGHT(ic))) {
3791 debugAopGet (" right:", IC_RIGHT (ic));
3792 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3795 if(IS_SYMOP ( IC_RESULT(ic))) {
3796 debugAopGet (" result:", IC_RESULT (ic));
3797 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3800 if (POINTER_SET (ic))
3801 debugLog (" %d - Pointer set\n", __LINE__);
3804 /* Look for two subsequent iCodes with */
3806 /* _c = iTemp & op; */
3807 /* and replace them by */
3810 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3812 ic->prev->op == '=' &&
3813 IS_ITEMP (IC_LEFT (ic)) &&
3814 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3815 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3817 iCode* ic_prev = ic->prev;
3818 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3820 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3821 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3823 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3824 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3825 prev_result_sym->liveTo == ic->seq)
3827 prev_result_sym->liveTo = ic_prev->seq;
3830 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3832 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3834 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3836 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3837 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3838 remiCodeFromeBBlock (ebp, ic_prev);
3839 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3843 /* if this is an itemp & result of a address of a true sym
3844 then mark this as rematerialisable */
3845 if (ic->op == ADDRESS_OF &&
3846 IS_ITEMP (IC_RESULT (ic)) &&
3847 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3848 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3849 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3852 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3854 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3855 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3856 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3860 /* if straight assignment then carry remat flag if
3861 this is the only definition */
3862 if (ic->op == '=' &&
3863 !POINTER_SET (ic) &&
3864 IS_SYMOP (IC_RIGHT (ic)) &&
3865 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3866 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3868 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3870 OP_SYMBOL (IC_RESULT (ic))->remat =
3871 OP_SYMBOL (IC_RIGHT (ic))->remat;
3872 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3873 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3876 /* if this is a +/- operation with a rematerizable
3877 then mark this as rematerializable as well */
3878 if ((ic->op == '+' || ic->op == '-') &&
3879 (IS_SYMOP (IC_LEFT (ic)) &&
3880 IS_ITEMP (IC_RESULT (ic)) &&
3881 OP_SYMBOL (IC_LEFT (ic))->remat &&
3882 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3883 IS_OP_LITERAL (IC_RIGHT (ic))))
3885 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3887 operandLitValue (IC_RIGHT (ic));
3888 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3889 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3890 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3893 /* mark the pointer usages */
3894 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3896 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3897 debugLog (" marking as a pointer (set) =>");
3898 debugAopGet (" result:", IC_RESULT (ic));
3900 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3902 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3903 debugLog (" marking as a pointer (get) =>");
3904 debugAopGet (" left:", IC_LEFT (ic));
3909 /* if we are using a symbol on the stack
3910 then we should say pic14_ptrRegReq */
3911 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3912 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3913 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3914 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3915 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3916 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3919 if (IS_SYMOP (IC_LEFT (ic)))
3920 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3921 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3922 if (IS_SYMOP (IC_RIGHT (ic)))
3923 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3924 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3925 if (IS_SYMOP (IC_RESULT (ic)))
3926 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3927 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3930 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3934 /* if the condition of an if instruction
3935 is defined in the previous instruction then
3936 mark the itemp as a conditional */
3937 if ((IS_CONDITIONAL (ic) ||
3938 ((ic->op == BITWISEAND ||
3941 isBitwiseOptimizable (ic))) &&
3942 ic->next && ic->next->op == IFX &&
3943 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3944 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3947 debugLog (" %d\n", __LINE__);
3948 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3952 /* reduce for support function calls */
3953 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3954 packRegsForSupport (ic, ebp);
3956 /* if a parameter is passed, it's in W, so we may not
3957 need to place a copy in a register */
3958 if (ic->op == RECEIVE)
3959 packForReceive (ic, ebp);
3961 /* some cases the redundant moves can
3962 can be eliminated for return statements */
3963 if ((ic->op == RETURN || ic->op == SEND) &&
3964 !isOperandInFarSpace (IC_LEFT (ic)) &&
3966 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3968 /* if pointer set & left has a size more than
3969 one and right is not in far space */
3970 if (POINTER_SET (ic) &&
3971 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3972 IS_SYMOP(IC_RESULT(ic)) &&
3973 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3974 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3975 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3977 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3979 /* if pointer get */
3980 if (POINTER_GET (ic) &&
3981 !isOperandInFarSpace (IC_RESULT (ic)) &&
3982 IS_SYMOP(IC_LEFT(ic)) &&
3983 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3984 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3985 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3987 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3990 /* if this is cast for intergral promotion then
3991 check if only use of the definition of the
3992 operand being casted/ if yes then replace
3993 the result of that arithmetic operation with
3994 this result and get rid of the cast */
3995 if (ic->op == CAST) {
3997 sym_link *fromType = operandType (IC_RIGHT (ic));
3998 sym_link *toType = operandType (IC_LEFT (ic));
4000 debugLog (" %d - casting\n", __LINE__);
4002 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4003 getSize (fromType) != getSize (toType)) {
4006 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4009 if (IS_ARITHMETIC_OP (dic)) {
4011 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4012 IC_RESULT (dic) = IC_RESULT (ic);
4013 remiCodeFromeBBlock (ebp, ic);
4014 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4015 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4016 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4020 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4024 /* if the type from and type to are the same
4025 then if this is the only use then packit */
4026 if (compareType (operandType (IC_RIGHT (ic)),
4027 operandType (IC_LEFT (ic))) == 1) {
4029 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4032 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4033 IC_RESULT (dic) = IC_RESULT (ic);
4034 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4035 remiCodeFromeBBlock (ebp, ic);
4036 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4037 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4045 iTempNN := (some variable in farspace) V1
4050 if (ic->op == IPUSH)
4052 packForPush (ic, ebp);
4056 /* pack registers for accumulator use, when the
4057 result of an arithmetic or bit wise operation
4058 has only one use, that use is immediately following
4059 the defintion and the using iCode has only one
4060 operand or has two operands but one is literal &
4061 the result of that operation is not on stack then
4062 we can leave the result of this operation in acc:b
4064 if ((IS_ARITHMETIC_OP (ic)
4066 || IS_BITWISE_OP (ic)
4068 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4071 IS_ITEMP (IC_RESULT (ic)) &&
4072 getSize (operandType (IC_RESULT (ic))) <= 2)
4074 packRegsForAccUse (ic);
4080 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4084 if (!debug || !debugF)
4087 for (i = 0; i < count; i++)
4089 fprintf (debugF, "\n----------------------------------------------------------------\n");
4090 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4091 ebbs[i]->entryLabel->name,
4094 ebbs[i]->isLastInLoop);
4095 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4100 fprintf (debugF, "visited %d : hasFcall = %d\n",
4104 fprintf (debugF, "\ndefines bitVector :");
4105 bitVectDebugOn (ebbs[i]->defSet, debugF);
4106 fprintf (debugF, "\nlocal defines bitVector :");
4107 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4108 fprintf (debugF, "\npointers Set bitvector :");
4109 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4110 fprintf (debugF, "\nin pointers Set bitvector :");
4111 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4112 fprintf (debugF, "\ninDefs Set bitvector :");
4113 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4114 fprintf (debugF, "\noutDefs Set bitvector :");
4115 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4116 fprintf (debugF, "\nusesDefs Set bitvector :");
4117 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4118 fprintf (debugF, "\n----------------------------------------------------------------\n");
4119 printiCChain (ebbs[i]->sch, debugF);
4122 /*-----------------------------------------------------------------*/
4123 /* assignRegisters - assigns registers to each live range as need */
4124 /*-----------------------------------------------------------------*/
4126 pic14_assignRegisters (ebbIndex * ebbi)
4128 eBBlock ** ebbs = ebbi->bbOrder;
4129 int count = ebbi->count;
4133 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4134 debugLog ("\nebbs before optimizing:\n");
4135 dumpEbbsToDebug (ebbs, count);
4137 setToNull ((void *) &_G.funcrUsed);
4138 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4141 /* change assignments this will remove some
4142 live ranges reducing some register pressure */
4143 for (i = 0; i < count; i++)
4144 packRegisters (ebbs[i]);
4151 debugLog("dir registers allocated so far:\n");
4152 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4155 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4156 reg = hTabNextItem(dynDirectRegNames, &hkey);
4161 if (options.dump_pack)
4162 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4164 /* first determine for each live range the number of
4165 registers & the type of registers required for each */
4168 /* and serially allocate registers */
4169 serialRegAssign (ebbs, count);
4171 /* if stack was extended then tell the user */
4174 /* werror(W_TOOMANY_SPILS,"stack", */
4175 /* _G.stackExtend,currFunc->name,""); */
4181 /* werror(W_TOOMANY_SPILS,"data space", */
4182 /* _G.dataExtend,currFunc->name,""); */
4186 /* after that create the register mask
4187 for each of the instruction */
4188 createRegMask (ebbs, count);
4190 /* redo that offsets for stacked automatic variables */
4191 redoStackOffsets ();
4193 if (options.dump_rassgn)
4194 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4196 /* now get back the chain */
4197 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4199 debugLog ("ebbs after optimizing:\n");
4200 dumpEbbsToDebug (ebbs, count);
4205 /* free up any _G.stackSpil locations allocated */
4206 applyToSet (_G.stackSpil, deallocStackSpil);
4208 setToNull ((void *) &_G.stackSpil);
4209 setToNull ((void *) &_G.spiltSet);
4210 /* mark all registers as free */
4211 //pic14_freeAllRegs ();
4213 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");