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 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
36 #define FENTRY2 1 ? (void)0 : printf
38 #define STRCASECMP strcasecmp
39 //#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0)
40 #define FENTRY2 1 ? (void)0 : printf
43 /* this should go in SDCCicode.h, but it doesn't. */
44 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
46 /*-----------------------------------------------------------------*/
47 /* At this point we start getting processor specific although */
48 /* some routines are non-processor specific & can be reused when */
49 /* targetting other processors. The decision for this will have */
50 /* to be made on a routine by routine basis */
51 /* routines used to pack registers are most definitely not reusable */
52 /* since the pack the registers depending strictly on the MCU */
53 /*-----------------------------------------------------------------*/
55 extern void genpic14Code (iCode *);
56 extern void pic14_assignConfigWordValue(int address, int value);
66 bitVect *funcrUsed; /* registers used in a function */
72 /* Shared with gen.c */
73 int pic14_ptrRegReq; /* one byte pointer register required */
76 set *dynAllocRegs=NULL;
77 set *dynStackRegs=NULL;
78 set *dynProcessorRegs=NULL;
79 set *dynDirectRegs=NULL;
80 set *dynDirectBitRegs=NULL;
81 set *dynInternalRegs=NULL;
83 static hTab *dynDirectRegNames= NULL;
84 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
86 static int dynrIdx = 0x1000;
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 RANGE: return "RANGE";
261 case FAR: return "FAR";
262 case CASE: return "CASE";
263 case DEFAULT: return "DEFAULT";
264 case IF: return "IF";
265 case ELSE: return "ELSE";
266 case SWITCH: return "SWITCH";
267 case WHILE: return "WHILE";
268 case DO: return "DO";
269 case FOR: return "FOR";
270 case GOTO: return "GOTO";
271 case CONTINUE: return "CONTINUE";
272 case BREAK: return "BREAK";
273 case RETURN: return "RETURN";
274 case INLINEASM: return "INLINEASM";
275 case IFX: return "IFX";
276 case ADDRESS_OF: return "ADDRESS_OF";
277 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
278 case SPIL: return "SPIL";
279 case UNSPIL: return "UNSPIL";
280 case GETHBIT: return "GETHBIT";
281 case BITWISEAND: return "BITWISEAND";
282 case UNARYMINUS: return "UNARYMINUS";
283 case IPUSH: return "IPUSH";
284 case IPOP: return "IPOP";
285 case PCALL: return "PCALL";
286 case ENDFUNCTION: return "ENDFUNCTION";
287 case JUMPTABLE: return "JUMPTABLE";
288 case RRC: return "RRC";
289 case RLC: return "RLC";
290 case CAST: return "CAST";
291 case CALL: return "CALL";
292 case PARAM: return "PARAM ";
293 case NULLOP: return "NULLOP";
294 case BLOCK: return "BLOCK";
295 case LABEL: return "LABEL";
296 case RECEIVE: return "RECEIVE";
297 case SEND: return "SEND";
299 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
302 /*-----------------------------------------------------------------*/
303 /*-----------------------------------------------------------------*/
305 debugLogRegType (short type)
310 case REG_GPR: return "REG_GPR";
311 case REG_PTR: return "REG_PTR";
312 case REG_CND: return "REG_CND";
315 sprintf (buffer, "unknown reg type %d", type);
319 /*-----------------------------------------------------------------*/
320 /*-----------------------------------------------------------------*/
321 static int regname2key(char const *name)
330 key += (*name++) + 1;
334 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
338 static regs *regWithIdx (set *dRegs, int idx, int fixed);
339 /*-----------------------------------------------------------------*/
340 /* newReg - allocate and init memory for a new register */
341 /*-----------------------------------------------------------------*/
342 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
345 regs *dReg, *reg_alias;
347 /* check whether a matching register already exists */
348 dReg = dirregWithName( name );
350 //printf( "%s: already present: %s\n", __FUNCTION__, name );
354 // check whether a register at that location exists
355 reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
356 if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
358 // create a new register
359 dReg = Safe_calloc(1,sizeof(regs));
361 dReg->pc_type = pc_type;
364 dReg->name = Safe_strdup(name);
366 sprintf(buffer,"r0x%02X", dReg->rIdx);
367 dReg->name = Safe_strdup(buffer);
383 dReg->reg_alias = reg_alias;
384 dReg->reglives.usedpFlows = newSet();
385 dReg->reglives.assignedpFlows = newSet();
386 if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
387 debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
392 /*-----------------------------------------------------------------*/
393 /* regWithIdx - Search through a set of registers that matches idx */
394 /*-----------------------------------------------------------------*/
396 regWithIdx (set *dRegs, int idx, int fixed)
400 for (dReg = setFirstItem(dRegs) ; dReg ;
401 dReg = setNextItem(dRegs)) {
403 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
404 while (dReg->reg_alias) dReg = dReg->reg_alias;
412 /*-----------------------------------------------------------------*/
413 /* regWithName - Search through a set of registers that matches name */
414 /*-----------------------------------------------------------------*/
416 regWithName (set *dRegs, const char *name)
420 for (dReg = setFirstItem(dRegs) ; dReg ;
421 dReg = setNextItem(dRegs)) {
423 if((strcmp(name,dReg->name)==0)) {
431 /*-----------------------------------------------------------------*/
432 /* regWithName - Search for a registers that matches name */
433 /*-----------------------------------------------------------------*/
435 regFindWithName (const char *name)
439 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
440 debugLog ("Found a Direct Register!\n");
443 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
444 debugLog ("Found a Direct Bit Register!\n");
448 if (*name=='_') name++; // Step passed '_'
450 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
451 debugLog ("Found a Dynamic Register!\n");
454 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
455 debugLog ("Found a Processor Register!\n");
458 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
459 debugLog ("Found an Internal Register!\n");
462 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
463 debugLog ("Found an Stack Register!\n");
470 /*-----------------------------------------------------------------*/
471 /* regFindFree - Search for a free register in a set of registers */
472 /*-----------------------------------------------------------------*/
474 regFindFree (set *dRegs)
478 for (dReg = setFirstItem(dRegs) ; dReg ;
479 dReg = setNextItem(dRegs)) {
487 /*-----------------------------------------------------------------*/
488 /* initStack - allocate registers for a pseudo stack */
489 /*-----------------------------------------------------------------*/
490 void initStack(int base_address, int size, int shared)
496 pic = pic14_getPIC();
497 Gstack_base_addr = base_address;
499 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
501 for(i = 0; i<size; i++) {
504 SNPRINTF(&buffer[0], 16, "STK%02d", i);
505 // multi-bank device, sharebank prohibited by user
506 r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
511 addSet(&dynStackRegs,r);
515 /*-----------------------------------------------------------------*
516 *-----------------------------------------------------------------*/
518 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
521 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
522 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
525 /*-----------------------------------------------------------------*
526 *-----------------------------------------------------------------*/
529 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
531 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
533 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
536 return addSet(&dynInternalRegs,reg);
541 /*-----------------------------------------------------------------*/
542 /* allocReg - allocates register of given type */
543 /*-----------------------------------------------------------------*/
545 allocReg (short type)
549 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
550 //fprintf(stderr,"allocReg\n");
552 reg = pic14_findFreeReg (type);
560 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
565 /*-----------------------------------------------------------------*/
566 /* dirregWithName - search for register by name */
567 /*-----------------------------------------------------------------*/
569 dirregWithName (char *name)
577 /* hash the name to get a key */
579 hkey = regname2key(name);
581 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
585 if(STRCASECMP(reg->name, name) == 0) {
586 // handle registers with multiple names
587 while (reg->reg_alias) reg = reg->reg_alias;
591 reg = hTabNextItemWK (dynDirectRegNames);
595 return NULL; // name wasn't found in the hash table
598 int IS_CONFIG_ADDRESS(int address)
601 return ((address == 0x2007) || (address == 0x2008));
604 /*-----------------------------------------------------------------*/
605 /* allocNewDirReg - allocates a new register of given type */
606 /*-----------------------------------------------------------------*/
608 allocNewDirReg (sym_link *symlnk,const char *name)
612 sym_link *spec = getSpec (symlnk);
614 /* if this is at an absolute address, then get the address. */
615 if (SPEC_ABSA (spec) ) {
616 address = SPEC_ADDR (spec);
617 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
620 /* Register wasn't found in hash, so let's create
621 * a new one and put it in the hash table AND in the
622 * dynDirectRegNames set */
623 if (IS_CONFIG_ADDRESS(address)) {
624 debugLog (" -- %s is declared at address 0x2007\n",name);
629 if (IS_BITVAR (spec))
636 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
637 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
639 if (SPEC_ABSA (spec) ) {
643 if (IS_BITVAR (spec)) {
644 addSet(&dynDirectBitRegs, reg);
647 addSet(&dynDirectRegs, reg);
649 if (!IS_STATIC (spec)) {
652 if (IS_EXTERN (spec)) {
658 if (address && reg) {
660 reg->address = address;
661 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
667 /*-----------------------------------------------------------------*/
668 /* allocDirReg - allocates register of given type */
669 /*-----------------------------------------------------------------*/
671 allocDirReg (operand *op )
678 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
682 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
684 /* If the symbol is at a fixed address, then remove the leading underscore
685 * from the name. This is hack to allow the .asm include file named registers
686 * to match the .c declared register names */
688 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
691 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
693 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
694 debugLog(" %d const char\n",__LINE__);
695 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
698 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
699 if (IS_CODE ( OP_SYM_ETYPE(op)) )
700 debugLog(" %d code space\n",__LINE__);
702 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
703 debugLog(" %d integral\n",__LINE__);
704 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
705 debugLog(" %d literal\n",__LINE__);
706 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
707 debugLog(" %d specifier\n",__LINE__);
708 debugAopGet(NULL, op);
711 if (IS_CODE ( OP_SYM_ETYPE(op)) )
714 /* First, search the hash table to see if there is a register with this name */
715 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
716 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
719 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
720 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
722 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
723 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
726 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
728 reg = dirregWithName(name);
735 /* if this is at an absolute address, then get the address. */
736 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
737 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
738 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
741 /* Register wasn't found in hash, so let's create
742 * a new one and put it in the hash table AND in the
743 * dynDirectRegNames set */
744 if(!IS_CONFIG_ADDRESS(address)) {
745 //fprintf(stderr,"allocating new reg %s\n",name);
747 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
748 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
750 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
752 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
754 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
758 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
759 addSet(&dynDirectBitRegs, reg);
762 addSet(&dynDirectRegs, reg);
764 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
767 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
773 debugLog (" -- %s is declared at address 0x2007\n",name);
778 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
780 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
781 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
786 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
788 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
789 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
792 allocNewDirReg (OP_SYM_TYPE(op),name);
799 /*-----------------------------------------------------------------*/
800 /* allocRegByName - allocates register with given name */
801 /*-----------------------------------------------------------------*/
803 allocRegByName (char *name, int size)
809 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
813 /* First, search the hash table to see if there is a register with this name */
814 reg = dirregWithName(name);
820 /* Register wasn't found in hash, so let's create
821 * a new one and put it in the hash table AND in the
822 * dynDirectRegNames set */
823 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
824 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
825 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
826 if (strcmp(reg->name+1,sym->name)==0) {
827 unsigned a = SPEC_ADDR(sym->etype);
831 if (!IS_STATIC (sym->etype)) {
834 if (IS_EXTERN (sym->etype)) {
837 if (IS_BITVAR (sym->etype))
844 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
845 if (strcmp(reg->name+1,sym->name)==0) {
846 unsigned a = SPEC_ADDR(sym->etype);
848 if (!IS_STATIC (sym->etype)) {
851 if (IS_EXTERN (sym->etype)) {
854 if (IS_BITVAR (sym->etype))
862 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
864 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
865 if (reg->isBitField) {
866 addSet(&dynDirectBitRegs, reg);
868 addSet(&dynDirectRegs, reg);
874 /*-----------------------------------------------------------------*/
875 /* RegWithIdx - returns pointer to register with index number */
876 /*-----------------------------------------------------------------*/
878 typeRegWithIdx (int idx, int type, int fixed)
883 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
888 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
890 debugLog ("Found a Dynamic Register!\n");
893 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
894 debugLog ("Found a Direct Register!\n");
900 if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
901 debugLog ("Found a Stack Register!\n");
904 if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
905 debugLog ("Found a Stack Register!\n");
909 werror (E_STACK_OUT, "Register");
910 /* return an existing register just to avoid the SDCC crash */
911 return regWithIdx ( dynStackRegs, 0x7f, 0);
915 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
916 debugLog ("Found a Processor Register!\n");
930 /*-----------------------------------------------------------------*/
931 /* pic14_regWithIdx - returns pointer to register with index number*/
932 /*-----------------------------------------------------------------*/
934 pic14_regWithIdx (int idx)
938 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
941 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
947 /*-----------------------------------------------------------------*/
948 /* pic14_regWithIdx - returns pointer to register with index number */
949 /*-----------------------------------------------------------------*/
951 pic14_allocWithIdx (int idx)
956 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
958 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
960 debugLog ("Found a Dynamic Register!\n");
961 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
962 debugLog ("Found a Stack Register!\n");
963 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
964 debugLog ("Found a Processor Register!\n");
965 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
966 debugLog ("Found an Internal Register!\n");
967 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
968 debugLog ("Found an Internal Register!\n");
971 debugLog ("Dynamic Register not found\n");
974 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
975 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
976 "regWithIdx not found");
986 /*-----------------------------------------------------------------*/
987 /*-----------------------------------------------------------------*/
989 pic14_findFreeReg(short type)
996 if((dReg = regFindFree(dynAllocRegs)) != NULL)
998 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1002 if((dReg = regFindFree(dynStackRegs)) != NULL)
1014 /*-----------------------------------------------------------------*/
1015 /* freeReg - frees a register */
1016 /*-----------------------------------------------------------------*/
1018 freeReg (regs * reg)
1020 debugLog ("%s\n", __FUNCTION__);
1025 /*-----------------------------------------------------------------*/
1026 /* nFreeRegs - returns number of free registers */
1027 /*-----------------------------------------------------------------*/
1029 nFreeRegs (int type)
1031 /* dynamically allocate as many as we need and worry about
1032 * fitting them into a PIC later */
1039 debugLog ("%s\n", __FUNCTION__);
1040 for (i = 0; i < pic14_nRegs; i++)
1041 if (regspic14[i].isFree && regspic14[i].type == type)
1047 /*-----------------------------------------------------------------*/
1048 /* nfreeRegsType - free registers with type */
1049 /*-----------------------------------------------------------------*/
1051 nfreeRegsType (int type)
1054 debugLog ("%s\n", __FUNCTION__);
1055 if (type == REG_PTR)
1057 if ((nfr = nFreeRegs (type)) == 0)
1058 return nFreeRegs (REG_GPR);
1061 return nFreeRegs (type);
1064 void writeSetUsedRegs(FILE *of, set *dRegs)
1069 for (dReg = setFirstItem(dRegs) ; dReg ;
1070 dReg = setNextItem(dRegs)) {
1073 fprintf (of, "\t%s\n",dReg->name);
1077 extern void dump_map(void);
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,dynrIdx++,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 = dynrIdx; /* 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",
1177 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1182 for (reg = setFirstItem(fregs) ; reg ;
1183 reg = setNextItem(fregs)) {
1185 //if(!reg->isEmitted && reg->wasUsed) {
1188 fprintf (of, "%s\tEQU\t0x%03x\n",
1192 fprintf (of, "%s\tEQU\t0x%03x\n",
1200 void writeUsedRegs(FILE *of)
1203 packBits(dynDirectBitRegs);
1207 bitEQUs(of,dynDirectBitRegs);
1210 /*-----------------------------------------------------------------*/
1211 /* computeSpillable - given a point find the spillable live ranges */
1212 /*-----------------------------------------------------------------*/
1214 computeSpillable (iCode * ic)
1218 debugLog ("%s\n", __FUNCTION__);
1219 /* spillable live ranges are those that are live at this
1220 point . the following categories need to be subtracted
1222 a) - those that are already spilt
1223 b) - if being used by this one
1224 c) - defined by this one */
1226 spillable = bitVectCopy (ic->rlive);
1228 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1230 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1231 bitVectUnSetBit (spillable, ic->defKey);
1232 spillable = bitVectIntersect (spillable, _G.regAssigned);
1237 /*-----------------------------------------------------------------*/
1238 /* noSpilLoc - return true if a variable has no spil location */
1239 /*-----------------------------------------------------------------*/
1241 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1243 debugLog ("%s\n", __FUNCTION__);
1244 return (sym->usl.spillLoc ? 0 : 1);
1247 /*-----------------------------------------------------------------*/
1248 /* hasSpilLoc - will return 1 if the symbol has spil location */
1249 /*-----------------------------------------------------------------*/
1251 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1253 debugLog ("%s\n", __FUNCTION__);
1254 return (sym->usl.spillLoc ? 1 : 0);
1257 /*-----------------------------------------------------------------*/
1258 /* directSpilLoc - will return 1 if the splilocation is in direct */
1259 /*-----------------------------------------------------------------*/
1261 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1263 debugLog ("%s\n", __FUNCTION__);
1264 if (sym->usl.spillLoc &&
1265 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1271 /*-----------------------------------------------------------------*/
1272 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1273 /* but is not used as a pointer */
1274 /*-----------------------------------------------------------------*/
1276 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1278 debugLog ("%s\n", __FUNCTION__);
1279 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1282 /*-----------------------------------------------------------------*/
1283 /* rematable - will return 1 if the remat flag is set */
1284 /*-----------------------------------------------------------------*/
1286 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1288 debugLog ("%s\n", __FUNCTION__);
1292 /*-----------------------------------------------------------------*/
1293 /* notUsedInRemaining - not used or defined in remain of the block */
1294 /*-----------------------------------------------------------------*/
1296 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1298 debugLog ("%s\n", __FUNCTION__);
1299 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1300 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1303 /*-----------------------------------------------------------------*/
1304 /* allLRs - return true for all */
1305 /*-----------------------------------------------------------------*/
1307 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1309 debugLog ("%s\n", __FUNCTION__);
1313 /*-----------------------------------------------------------------*/
1314 /* liveRangesWith - applies function to a given set of live range */
1315 /*-----------------------------------------------------------------*/
1317 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1318 eBBlock * ebp, iCode * ic)
1323 debugLog ("%s\n", __FUNCTION__);
1324 if (!lrs || !lrs->size)
1327 for (i = 1; i < lrs->size; i++)
1330 if (!bitVectBitValue (lrs, i))
1333 /* if we don't find it in the live range
1334 hash table we are in serious trouble */
1335 if (!(sym = hTabItemWithKey (liveRanges, i)))
1337 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1338 "liveRangesWith could not find liveRange");
1342 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1343 addSetHead (&rset, sym);
1350 /*-----------------------------------------------------------------*/
1351 /* leastUsedLR - given a set determines which is the least used */
1352 /*-----------------------------------------------------------------*/
1354 leastUsedLR (set * sset)
1356 symbol *sym = NULL, *lsym = NULL;
1358 debugLog ("%s\n", __FUNCTION__);
1359 sym = lsym = setFirstItem (sset);
1364 for (; lsym; lsym = setNextItem (sset))
1367 /* if usage is the same then prefer
1368 the spill the smaller of the two */
1369 if (lsym->used == sym->used)
1370 if (getSize (lsym->type) < getSize (sym->type))
1374 if (lsym->used < sym->used)
1379 setToNull ((void *) &sset);
1384 /*-----------------------------------------------------------------*/
1385 /* noOverLap - will iterate through the list looking for over lap */
1386 /*-----------------------------------------------------------------*/
1388 noOverLap (set * itmpStack, symbol * fsym)
1391 debugLog ("%s\n", __FUNCTION__);
1394 for (sym = setFirstItem (itmpStack); sym;
1395 sym = setNextItem (itmpStack))
1397 if (sym->liveTo > fsym->liveFrom)
1405 /*-----------------------------------------------------------------*/
1406 /* isFree - will return 1 if the a free spil location is found */
1407 /*-----------------------------------------------------------------*/
1412 V_ARG (symbol **, sloc);
1413 V_ARG (symbol *, fsym);
1415 debugLog ("%s\n", __FUNCTION__);
1416 /* if already found */
1420 /* if it is free && and the itmp assigned to
1421 this does not have any overlapping live ranges
1422 with the one currently being assigned and
1423 the size can be accomodated */
1425 noOverLap (sym->usl.itmpStack, fsym) &&
1426 getSize (sym->type) >= getSize (fsym->type))
1435 /*-----------------------------------------------------------------*/
1436 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1437 /*-----------------------------------------------------------------*/
1439 spillLRWithPtrReg (symbol * forSym)
1445 debugLog ("%s\n", __FUNCTION__);
1446 if (!_G.regAssigned ||
1447 bitVectIsZero (_G.regAssigned))
1450 r0 = pic14_regWithIdx (R0_IDX);
1451 r1 = pic14_regWithIdx (R1_IDX);
1453 /* for all live ranges */
1454 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1455 lrsym = hTabNextItem (liveRanges, &k))
1459 /* if no registers assigned to it or
1461 /* if it does not overlap with this then
1462 not need to spill it */
1464 if (lrsym->isspilt || !lrsym->nRegs ||
1465 (lrsym->liveTo < forSym->liveFrom))
1468 /* go thru the registers : if it is either
1469 r0 or r1 then spil it */
1470 for (j = 0; j < lrsym->nRegs; j++)
1471 if (lrsym->regs[j] == r0 ||
1472 lrsym->regs[j] == r1)
1481 /*-----------------------------------------------------------------*/
1482 /* createStackSpil - create a location on the stack to spil */
1483 /*-----------------------------------------------------------------*/
1485 createStackSpil (symbol * sym)
1487 symbol *sloc = NULL;
1488 int useXstack, model, noOverlay;
1490 char slocBuffer[30];
1491 debugLog ("%s\n", __FUNCTION__);
1495 /* first go try and find a free one that is already
1496 existing on the stack */
1497 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1499 /* found a free one : just update & return */
1500 sym->usl.spillLoc = sloc;
1503 addSetHead (&sloc->usl.itmpStack, sym);
1507 /* could not then have to create one , this is the hard part
1508 we need to allocate this on the stack : this is really a
1509 hack!! but cannot think of anything better at this time */
1511 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1513 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1514 __FILE__, __LINE__);
1518 sloc = newiTemp (slocBuffer);
1520 /* set the type to the spilling symbol */
1521 sloc->type = copyLinkChain (sym->type);
1522 sloc->etype = getSpec (sloc->type);
1523 SPEC_SCLS (sloc->etype) = S_DATA;
1524 SPEC_EXTR (sloc->etype) = 0;
1525 SPEC_STAT (sloc->etype) = 0;
1527 /* we don't allow it to be allocated`
1528 onto the external stack since : so we
1529 temporarily turn it off ; we also
1530 turn off memory model to prevent
1531 the spil from going to the external storage
1532 and turn off overlaying
1535 useXstack = options.useXstack;
1536 model = options.model;
1537 noOverlay = options.noOverlay;
1538 options.noOverlay = 1;
1539 options.model = options.useXstack = 0;
1543 options.useXstack = useXstack;
1544 options.model = model;
1545 options.noOverlay = noOverlay;
1546 sloc->isref = 1; /* to prevent compiler warning */
1548 /* if it is on the stack then update the stack */
1549 if (IN_STACK (sloc->etype))
1551 currFunc->stack += getSize (sloc->type);
1552 _G.stackExtend += getSize (sloc->type);
1555 _G.dataExtend += getSize (sloc->type);
1557 /* add it to the _G.stackSpil set */
1558 addSetHead (&_G.stackSpil, sloc);
1559 sym->usl.spillLoc = sloc;
1562 /* add it to the set of itempStack set
1563 of the spill location */
1564 addSetHead (&sloc->usl.itmpStack, sym);
1568 /*-----------------------------------------------------------------*/
1569 /* isSpiltOnStack - returns true if the spil location is on stack */
1570 /*-----------------------------------------------------------------*/
1572 isSpiltOnStack (symbol * sym)
1576 debugLog ("%s\n", __FUNCTION__);
1585 /* if (sym->_G.stackSpil) */
1588 if (!sym->usl.spillLoc)
1591 etype = getSpec (sym->usl.spillLoc->type);
1592 if (IN_STACK (etype))
1598 /*-----------------------------------------------------------------*/
1599 /* spillThis - spils a specific operand */
1600 /*-----------------------------------------------------------------*/
1602 spillThis (symbol * sym)
1605 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1606 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1608 /* if this is rematerializable or has a spillLocation
1609 we are okay, else we need to create a spillLocation
1611 if (!(sym->remat || sym->usl.spillLoc))
1612 createStackSpil (sym);
1615 /* mark it has spilt & put it in the spilt set */
1617 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1619 bitVectUnSetBit (_G.regAssigned, sym->key);
1621 for (i = 0; i < sym->nRegs; i++)
1625 freeReg (sym->regs[i]);
1626 sym->regs[i] = NULL;
1630 /* if spilt on stack then free up r0 & r1
1631 if they could have been assigned to some
1633 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1636 spillLRWithPtrReg (sym);
1639 if (sym->usl.spillLoc && !sym->remat)
1640 sym->usl.spillLoc->allocreq = 1;
1645 /*-----------------------------------------------------------------*/
1646 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1647 /*-----------------------------------------------------------------*/
1649 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1651 bitVect *lrcs = NULL;
1655 debugLog ("%s\n", __FUNCTION__);
1657 /* get the spillable live ranges */
1658 lrcs = computeSpillable (ic);
1661 /* get all live ranges that are rematerizable */
1662 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1664 /* return the least used of these */
1665 return leastUsedLR (selectS);
1668 /* get live ranges with spillLocations in direct space */
1669 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1671 sym = leastUsedLR (selectS);
1672 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1673 sym->usl.spillLoc->rname :
1674 sym->usl.spillLoc->name));
1676 /* mark it as allocation required */
1677 sym->usl.spillLoc->allocreq = 1;
1681 /* if the symbol is local to the block then */
1682 if (forSym->liveTo < ebp->lSeq)
1685 /* check if there are any live ranges allocated
1686 to registers that are not used in this block */
1687 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1689 sym = leastUsedLR (selectS);
1690 /* if this is not rematerializable */
1699 /* check if there are any live ranges that not
1700 used in the remainder of the block */
1701 if (!_G.blockSpil &&
1702 !isiCodeInFunctionCall (ic) &&
1703 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1705 sym = leastUsedLR (selectS);
1708 sym->remainSpil = 1;
1715 /* find live ranges with spillocation && not used as pointers */
1716 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1719 sym = leastUsedLR (selectS);
1720 /* mark this as allocation required */
1721 sym->usl.spillLoc->allocreq = 1;
1725 /* find live ranges with spillocation */
1726 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1729 sym = leastUsedLR (selectS);
1730 sym->usl.spillLoc->allocreq = 1;
1734 /* couldn't find then we need to create a spil
1735 location on the stack , for which one? the least
1737 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1740 /* return a created spil location */
1741 sym = createStackSpil (leastUsedLR (selectS));
1742 sym->usl.spillLoc->allocreq = 1;
1746 /* this is an extreme situation we will spill
1747 this one : happens very rarely but it does happen */
1753 /*-----------------------------------------------------------------*/
1754 /* spilSomething - spil some variable & mark registers as free */
1755 /*-----------------------------------------------------------------*/
1757 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1762 debugLog ("%s\n", __FUNCTION__);
1763 /* get something we can spil */
1764 ssym = selectSpil (ic, ebp, forSym);
1766 /* mark it as spilt */
1768 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1770 /* mark it as not register assigned &
1771 take it away from the set */
1772 bitVectUnSetBit (_G.regAssigned, ssym->key);
1774 /* mark the registers as free */
1775 for (i = 0; i < ssym->nRegs; i++)
1777 freeReg (ssym->regs[i]);
1779 /* if spilt on stack then free up r0 & r1
1780 if they could have been assigned to as gprs */
1781 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1784 spillLRWithPtrReg (ssym);
1787 /* if this was a block level spil then insert push & pop
1788 at the start & end of block respectively */
1789 if (ssym->blockSpil)
1791 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1792 /* add push to the start of the block */
1793 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1794 ebp->sch->next : ebp->sch));
1795 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1796 /* add pop to the end of the block */
1797 addiCodeToeBBlock (ebp, nic, NULL);
1800 /* if spilt because not used in the remainder of the
1801 block then add a push before this instruction and
1802 a pop at the end of the block */
1803 if (ssym->remainSpil)
1806 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1807 /* add push just before this instruction */
1808 addiCodeToeBBlock (ebp, nic, ic);
1810 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1811 /* add pop to the end of the block */
1812 addiCodeToeBBlock (ebp, nic, NULL);
1821 /*-----------------------------------------------------------------*/
1822 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1823 /*-----------------------------------------------------------------*/
1825 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1830 debugLog ("%s\n", __FUNCTION__);
1832 /* try for a ptr type */
1833 if ((reg = allocReg (REG_PTR)))
1836 /* try for gpr type */
1837 if ((reg = allocReg (REG_GPR)))
1840 /* we have to spil */
1841 if (!spilSomething (ic, ebp, sym))
1844 /* make sure partially assigned registers aren't reused */
1845 for (j=0; j<=sym->nRegs; j++)
1847 sym->regs[j]->isFree = 0;
1849 /* this looks like an infinite loop but
1850 in really selectSpil will abort */
1854 /*-----------------------------------------------------------------*/
1855 /* getRegGpr - will try for GPR if not spil */
1856 /*-----------------------------------------------------------------*/
1858 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1863 debugLog ("%s\n", __FUNCTION__);
1865 /* try for gpr type */
1866 if ((reg = allocReg (REG_GPR)))
1869 if (!pic14_ptrRegReq)
1870 if ((reg = allocReg (REG_PTR)))
1873 /* we have to spil */
1874 if (!spilSomething (ic, ebp, sym))
1877 /* make sure partially assigned registers aren't reused */
1878 for (j=0; j<=sym->nRegs; j++)
1880 sym->regs[j]->isFree = 0;
1882 /* this looks like an infinite loop but
1883 in really selectSpil will abort */
1887 /*-----------------------------------------------------------------*/
1888 /* symHasReg - symbol has a given register */
1889 /*-----------------------------------------------------------------*/
1891 symHasReg (symbol * sym, regs * reg)
1895 debugLog ("%s\n", __FUNCTION__);
1896 for (i = 0; i < sym->nRegs; i++)
1897 if (sym->regs[i] == reg)
1903 /*-----------------------------------------------------------------*/
1904 /* deassignLRs - check the live to and if they have registers & are */
1905 /* not spilt then free up the registers */
1906 /*-----------------------------------------------------------------*/
1908 deassignLRs (iCode * ic, eBBlock * ebp)
1914 debugLog ("%s\n", __FUNCTION__);
1915 for (sym = hTabFirstItem (liveRanges, &k); sym;
1916 sym = hTabNextItem (liveRanges, &k))
1919 symbol *psym = NULL;
1920 /* if it does not end here */
1921 if (sym->liveTo > ic->seq)
1924 /* Prevent the result from being assigned the same registers as (one)
1925 * operand as many genXXX-functions fail otherwise.
1926 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1927 * are known to fail. */
1928 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1932 case '=': /* assignment */
1933 case BITWISEAND: /* bitwise AND */
1934 case '|': /* bitwise OR */
1935 case '^': /* bitwise XOR */
1936 case '~': /* bitwise negate */
1937 case RLC: /* rotate through carry */
1940 case '+': /* addition */
1941 case '-': /* subtraction */
1942 /* go ahead, these are safe to use with
1943 * non-disjoint register sets */
1947 /* do not release operand registers */
1948 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1953 /* if it was spilt on stack then we can
1954 mark the stack spil location as free */
1959 sym->usl.spillLoc->isFree = 1;
1965 if (!bitVectBitValue (_G.regAssigned, sym->key))
1967 /* special case check if this is an IFX &
1968 the privious one was a pop and the
1969 previous one was not spilt then keep track
1971 if (ic->op == IFX && ic->prev &&
1972 ic->prev->op == IPOP &&
1973 !ic->prev->parmPush &&
1974 IS_SYMOP(IC_LEFT (ic->prev)) &&
1975 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1976 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1982 bitVectUnSetBit (_G.regAssigned, sym->key);
1984 /* if the result of this one needs registers
1985 and does not have it then assign it right
1987 if (IC_RESULT (ic) &&
1988 !(SKIP_IC2 (ic) || /* not a special icode */
1989 ic->op == JUMPTABLE ||
1994 POINTER_SET (ic)) &&
1995 IS_SYMOP (IC_RESULT (ic)) &&
1996 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1997 result->liveTo > ic->seq && /* and will live beyond this */
1998 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1999 result->liveFrom == ic->seq && /* does not start before here */
2000 result->regType == sym->regType && /* same register types */
2001 result->regType == sym->regType && /* same register types */
2002 result->nRegs && /* which needs registers */
2003 !result->isspilt && /* and does not already have them */
2005 !bitVectBitValue (_G.regAssigned, result->key) &&
2006 /* the number of free regs + number of regs in this LR
2007 can accomodate the what result Needs */
2008 ((nfreeRegsType (result->regType) +
2009 sym->nRegs) >= result->nRegs)
2013 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2015 result->regs[i] = sym->regs[i];
2017 result->regs[i] = getRegGpr (ic, ebp, result);
2019 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2023 /* free the remaining */
2024 for (; i < sym->nRegs; i++)
2028 if (!symHasReg (psym, sym->regs[i]))
2029 freeReg (sym->regs[i]);
2032 freeReg (sym->regs[i]);
2039 /*-----------------------------------------------------------------*/
2040 /* reassignLR - reassign this to registers */
2041 /*-----------------------------------------------------------------*/
2043 reassignLR (operand * op)
2045 symbol *sym = OP_SYMBOL (op);
2048 debugLog ("%s\n", __FUNCTION__);
2049 /* not spilt any more */
2050 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2051 bitVectUnSetBit (_G.spiltSet, sym->key);
2053 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2057 for (i = 0; i < sym->nRegs; i++)
2058 sym->regs[i]->isFree = 0;
2061 /*-----------------------------------------------------------------*/
2062 /* willCauseSpill - determines if allocating will cause a spill */
2063 /*-----------------------------------------------------------------*/
2065 willCauseSpill (int nr, int rt)
2067 debugLog ("%s\n", __FUNCTION__);
2068 /* first check if there are any avlb registers
2069 of te type required */
2072 /* special case for pointer type
2073 if pointer type not avlb then
2074 check for type gpr */
2075 if (nFreeRegs (rt) >= nr)
2077 if (nFreeRegs (REG_GPR) >= nr)
2082 if (pic14_ptrRegReq)
2084 if (nFreeRegs (rt) >= nr)
2089 if (nFreeRegs (REG_PTR) +
2090 nFreeRegs (REG_GPR) >= nr)
2095 debugLog (" ... yep it will (cause a spill)\n");
2096 /* it will cause a spil */
2100 /*-----------------------------------------------------------------*/
2101 /* positionRegs - the allocator can allocate same registers to res- */
2102 /* ult and operand, if this happens make sure they are in the same */
2103 /* position as the operand otherwise chaos results */
2104 /*-----------------------------------------------------------------*/
2106 positionRegs (symbol * result, symbol * opsym, int lineno)
2108 int count = min (result->nRegs, opsym->nRegs);
2109 int i, j = 0, shared = 0;
2111 debugLog ("%s\n", __FUNCTION__);
2112 /* if the result has been spilt then cannot share */
2117 /* first make sure that they actually share */
2118 for (i = 0; i < count; i++)
2120 for (j = 0; j < count; j++)
2122 if (result->regs[i] == opsym->regs[j] && i != j)
2132 regs *tmp = result->regs[i];
2133 result->regs[i] = result->regs[j];
2134 result->regs[j] = tmp;
2139 /*------------------------------------------------------------------*/
2140 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2141 /* it should either have registers or have beed spilled. Otherwise, */
2142 /* there was an uninitialized variable, so just spill this to get */
2143 /* the operand in a valid state. */
2144 /*------------------------------------------------------------------*/
2146 verifyRegsAssigned (operand *op, iCode * ic)
2151 if (!IS_ITEMP (op)) return;
2153 sym = OP_SYMBOL (op);
2154 if (sym->isspilt) return;
2155 if (!sym->nRegs) return;
2156 if (sym->regs[0]) return;
2158 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2159 sym->prereqv ? sym->prereqv->name : sym->name);
2164 /*-----------------------------------------------------------------*/
2165 /* serialRegAssign - serially allocate registers to the variables */
2166 /*-----------------------------------------------------------------*/
2168 serialRegAssign (eBBlock ** ebbs, int count)
2172 debugLog ("%s\n", __FUNCTION__);
2173 /* for all blocks */
2174 for (i = 0; i < count; i++)
2179 if (ebbs[i]->noPath &&
2180 (ebbs[i]->entryLabel != entryLabel &&
2181 ebbs[i]->entryLabel != returnLabel))
2184 /* of all instructions do */
2185 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2187 debugLog (" op: %s\n", decodeOp (ic->op));
2189 /* if this is an ipop that means some live
2190 range will have to be assigned again */
2192 reassignLR (IC_LEFT (ic));
2194 /* if result is present && is a true symbol */
2195 if (IC_RESULT (ic) && ic->op != IFX &&
2196 IS_TRUE_SYMOP (IC_RESULT (ic)))
2197 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2199 /* take away registers from live
2200 ranges that end at this instruction */
2201 deassignLRs (ic, ebbs[i]);
2203 /* some don't need registers */
2204 if (SKIP_IC2 (ic) ||
2205 ic->op == JUMPTABLE ||
2209 (IC_RESULT (ic) && POINTER_SET (ic)))
2212 /* now we need to allocate registers
2213 only for the result */
2214 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2216 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2222 /* Make sure any spill location is definately allocated */
2223 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2224 !sym->usl.spillLoc->allocreq)
2226 sym->usl.spillLoc->allocreq++;
2229 /* if it does not need or is spilt
2230 or is already assigned to registers
2231 or will not live beyond this instructions */
2234 bitVectBitValue (_G.regAssigned, sym->key) ||
2235 sym->liveTo <= ic->seq)
2238 /* if some liverange has been spilt at the block level
2239 and this one live beyond this block then spil this
2241 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2246 /* if trying to allocate this will cause
2247 a spill and there is nothing to spill
2248 or this one is rematerializable then
2250 willCS = willCauseSpill (sym->nRegs, sym->regType);
2251 spillable = computeSpillable (ic);
2253 (willCS && bitVectIsZero (spillable)))
2261 /* If the live range preceeds the point of definition
2262 then ideally we must take into account registers that
2263 have been allocated after sym->liveFrom but freed
2264 before ic->seq. This is complicated, so spill this
2265 symbol instead and let fillGaps handle the allocation. */
2266 if (sym->liveFrom < ic->seq)
2272 /* if it has a spillocation & is used less than
2273 all other live ranges then spill this */
2275 if (sym->usl.spillLoc) {
2276 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2277 allLRs, ebbs[i], ic));
2278 if (leastUsed && leastUsed->used > sym->used) {
2283 /* if none of the liveRanges have a spillLocation then better
2284 to spill this one than anything else already assigned to registers */
2285 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2286 /* if this is local to this block then we might find a block spil */
2287 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2295 if (ic->op == RECEIVE)
2296 debugLog ("When I get clever, I'll optimize the receive logic\n");
2298 /* if we need ptr regs for the right side
2300 if (POINTER_GET (ic)
2301 && IS_SYMOP(IC_LEFT(ic))
2302 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2303 <= (unsigned) PTRSIZE)
2308 /* else we assign registers to it */
2309 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2311 debugLog (" %d - \n", __LINE__);
2313 bitVectDebugOn(_G.regAssigned, debugF);
2314 for (j = 0; j < sym->nRegs; j++)
2316 if (sym->regType == REG_PTR)
2317 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2319 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2321 /* if the allocation failed which means
2322 this was spilt then break */
2326 debugLog (" %d - \n", __LINE__);
2328 /* if it shares registers with operands make sure
2329 that they are in the same position */
2330 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2331 IS_SYMOP(IC_RESULT(ic)) &&
2332 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2333 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2334 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2335 /* do the same for the right operand */
2336 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2337 IS_SYMOP(IC_RESULT(ic)) &&
2338 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2339 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2340 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2342 debugLog (" %d - \n", __LINE__);
2345 debugLog (" %d - \n", __LINE__);
2354 /* Check for and fix any problems with uninitialized operands */
2355 for (i = 0; i < count; i++)
2359 if (ebbs[i]->noPath &&
2360 (ebbs[i]->entryLabel != entryLabel &&
2361 ebbs[i]->entryLabel != returnLabel))
2364 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2371 verifyRegsAssigned (IC_COND (ic), ic);
2375 if (ic->op == JUMPTABLE)
2377 verifyRegsAssigned (IC_JTCOND (ic), ic);
2381 verifyRegsAssigned (IC_RESULT (ic), ic);
2382 verifyRegsAssigned (IC_LEFT (ic), ic);
2383 verifyRegsAssigned (IC_RIGHT (ic), ic);
2389 /*-----------------------------------------------------------------*/
2390 /* rUmaskForOp :- returns register mask for an operand */
2391 /*-----------------------------------------------------------------*/
2393 rUmaskForOp (operand * op)
2399 debugLog ("%s\n", __FUNCTION__);
2400 /* only temporaries are assigned registers */
2404 sym = OP_SYMBOL (op);
2406 /* if spilt or no registers assigned to it
2408 if (sym->isspilt || !sym->nRegs)
2411 rumask = newBitVect (pic14_nRegs);
2413 for (j = 0; j < sym->nRegs; j++)
2415 rumask = bitVectSetBit (rumask,
2416 sym->regs[j]->rIdx);
2422 /*-----------------------------------------------------------------*/
2423 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2424 /*-----------------------------------------------------------------*/
2426 regsUsedIniCode (iCode * ic)
2428 bitVect *rmask = newBitVect (pic14_nRegs);
2430 debugLog ("%s\n", __FUNCTION__);
2431 /* do the special cases first */
2434 rmask = bitVectUnion (rmask,
2435 rUmaskForOp (IC_COND (ic)));
2439 /* for the jumptable */
2440 if (ic->op == JUMPTABLE)
2442 rmask = bitVectUnion (rmask,
2443 rUmaskForOp (IC_JTCOND (ic)));
2448 /* of all other cases */
2450 rmask = bitVectUnion (rmask,
2451 rUmaskForOp (IC_LEFT (ic)));
2455 rmask = bitVectUnion (rmask,
2456 rUmaskForOp (IC_RIGHT (ic)));
2459 rmask = bitVectUnion (rmask,
2460 rUmaskForOp (IC_RESULT (ic)));
2466 /*-----------------------------------------------------------------*/
2467 /* createRegMask - for each instruction will determine the regsUsed */
2468 /*-----------------------------------------------------------------*/
2470 createRegMask (eBBlock ** ebbs, int count)
2474 debugLog ("%s\n", __FUNCTION__);
2475 /* for all blocks */
2476 for (i = 0; i < count; i++)
2480 if (ebbs[i]->noPath &&
2481 (ebbs[i]->entryLabel != entryLabel &&
2482 ebbs[i]->entryLabel != returnLabel))
2485 /* for all instructions */
2486 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2491 if (SKIP_IC2 (ic) || !ic->rlive)
2494 /* first mark the registers used in this
2496 ic->rUsed = regsUsedIniCode (ic);
2497 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2499 /* now create the register mask for those
2500 registers that are in use : this is a
2501 super set of ic->rUsed */
2502 ic->rMask = newBitVect (pic14_nRegs + 1);
2504 /* for all live Ranges alive at this point */
2505 for (j = 1; j < ic->rlive->size; j++)
2510 /* if not alive then continue */
2511 if (!bitVectBitValue (ic->rlive, j))
2514 /* find the live range we are interested in */
2515 if (!(sym = hTabItemWithKey (liveRanges, j)))
2517 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2518 "createRegMask cannot find live range");
2522 /* if no register assigned to it */
2523 if (!sym->nRegs || sym->isspilt)
2526 /* for all the registers allocated to it */
2527 for (k = 0; k < sym->nRegs; k++)
2530 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2536 /* This was the active version */
2537 /*-----------------------------------------------------------------*/
2538 /* rematStr - returns the rematerialized string for a remat var */
2539 /*-----------------------------------------------------------------*/
2541 rematStr (symbol * sym)
2544 iCode *ic = sym->rematiCode;
2545 symbol *psym = NULL;
2547 debugLog ("%s\n", __FUNCTION__);
2549 //printf ("%s\n", s);
2551 /* if plus or minus print the right hand side */
2553 if (ic->op == '+' || ic->op == '-') {
2555 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2557 sprintf (s, "(%s %c 0x%04x)",
2558 OP_SYMBOL (IC_LEFT (ric))->rname,
2560 (int) operandLitValue (IC_RIGHT (ic)));
2563 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2565 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2566 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2571 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2572 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2574 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2580 /* deprecated version */
2581 /*-----------------------------------------------------------------*/
2582 /* rematStr - returns the rematerialized string for a remat var */
2583 /*-----------------------------------------------------------------*/
2585 rematStr (symbol * sym)
2588 iCode *ic = sym->rematiCode;
2590 debugLog ("%s\n", __FUNCTION__);
2595 /* if plus or minus print the right hand side */
2597 if (ic->op == '+' || ic->op == '-') {
2598 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2601 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2605 if (ic->op == '+' || ic->op == '-')
2607 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2608 sprintf (s, "(%s %c 0x%04x)",
2609 OP_SYMBOL (IC_LEFT (ric))->rname,
2611 (int) operandLitValue (IC_RIGHT (ic)));
2614 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2616 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2620 /* we reached the end */
2621 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2625 printf ("%s\n", buffer);
2630 /*-----------------------------------------------------------------*/
2631 /* regTypeNum - computes the type & number of registers required */
2632 /*-----------------------------------------------------------------*/
2640 debugLog ("%s\n", __FUNCTION__);
2641 /* for each live range do */
2642 for (sym = hTabFirstItem (liveRanges, &k); sym;
2643 sym = hTabNextItem (liveRanges, &k)) {
2645 debugLog (" %d - %s\n", __LINE__, sym->rname);
2647 /* if used zero times then no registers needed */
2648 if ((sym->liveTo - sym->liveFrom) == 0)
2652 /* if the live range is a temporary */
2655 debugLog (" %d - itemp register\n", __LINE__);
2657 /* if the type is marked as a conditional */
2658 if (sym->regType == REG_CND)
2661 /* if used in return only then we don't
2664 if (IS_AGGREGATE (sym->type) || sym->isptr)
2665 sym->type = aggrToPtr (sym->type, FALSE);
2666 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2672 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2673 // sym->type = aggrToPtr (sym->type, FALSE);
2674 debugLog (" %d - used as a return\n", __LINE__);
2679 /* if the symbol has only one definition &
2680 that definition is a get_pointer and the
2681 pointer we are getting is rematerializable and
2685 if (bitVectnBitsOn (sym->defs) == 1 &&
2686 (ic = hTabItemWithKey (iCodehTab,
2687 bitVectFirstBit (sym->defs))) &&
2689 !IS_BITVAR (sym->etype) &&
2690 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2692 if (ptrPseudoSymSafe (sym, ic)) {
2696 debugLog (" %d - \n", __LINE__);
2698 /* create a pseudo symbol & force a spil */
2699 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2700 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2701 psym->type = sym->type;
2702 psym->etype = sym->etype;
2703 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2704 strcpy (psym->rname, psym->name);
2706 sym->usl.spillLoc = psym;
2710 /* if in data space or idata space then try to
2711 allocate pointer register */
2716 /* if not then we require registers */
2717 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2718 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2719 getSize (sym->type));
2722 if(IS_PTR_CONST (sym->type)) {
2723 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2727 if (sym->nRegs > 4) {
2728 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2729 printTypeChain (sym->type, stderr);
2730 fprintf (stderr, "\n");
2733 /* determine the type of register required */
2734 if (sym->nRegs == 1 &&
2735 IS_PTR (sym->type) &&
2737 sym->regType = REG_PTR;
2739 sym->regType = REG_GPR;
2742 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2746 /* for the first run we don't provide */
2747 /* registers for true symbols we will */
2748 /* see how things go */
2753 DEFSETFUNC (markRegFree)
2755 ((regs *)item)->isFree = 1;
2760 DEFSETFUNC (deallocReg)
2762 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2763 ((regs *)item)->isFree = 1;
2764 ((regs *)item)->wasUsed = 0;
2768 /*-----------------------------------------------------------------*/
2769 /* freeAllRegs - mark all registers as free */
2770 /*-----------------------------------------------------------------*/
2772 pic14_freeAllRegs ()
2776 debugLog ("%s\n", __FUNCTION__);
2778 applyToSet(dynAllocRegs,markRegFree);
2779 applyToSet(dynStackRegs,markRegFree);
2782 for (i = 0; i < pic14_nRegs; i++)
2783 regspic14[i].isFree = 1;
2787 /*-----------------------------------------------------------------*/
2788 /*-----------------------------------------------------------------*/
2790 pic14_deallocateAllRegs ()
2794 debugLog ("%s\n", __FUNCTION__);
2796 applyToSet(dynAllocRegs,deallocReg);
2799 for (i = 0; i < pic14_nRegs; i++) {
2800 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2801 regspic14[i].isFree = 1;
2802 regspic14[i].wasUsed = 0;
2809 /*-----------------------------------------------------------------*/
2810 /* deallocStackSpil - this will set the stack pointer back */
2811 /*-----------------------------------------------------------------*/
2813 DEFSETFUNC (deallocStackSpil)
2817 debugLog ("%s\n", __FUNCTION__);
2822 /*-----------------------------------------------------------------*/
2823 /* farSpacePackable - returns the packable icode for far variables */
2824 /*-----------------------------------------------------------------*/
2826 farSpacePackable (iCode * ic)
2830 debugLog ("%s\n", __FUNCTION__);
2831 /* go thru till we find a definition for the
2832 symbol on the right */
2833 for (dic = ic->prev; dic; dic = dic->prev)
2836 /* if the definition is a call then no */
2837 if ((dic->op == CALL || dic->op == PCALL) &&
2838 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2843 /* if shift by unknown amount then not */
2844 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2845 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2848 /* if pointer get and size > 1 */
2849 if (POINTER_GET (dic) &&
2850 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2853 if (POINTER_SET (dic) &&
2854 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2857 /* if any three is a true symbol in far space */
2858 if (IC_RESULT (dic) &&
2859 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2860 isOperandInFarSpace (IC_RESULT (dic)))
2863 if (IC_RIGHT (dic) &&
2864 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2865 isOperandInFarSpace (IC_RIGHT (dic)) &&
2866 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2869 if (IC_LEFT (dic) &&
2870 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2871 isOperandInFarSpace (IC_LEFT (dic)) &&
2872 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2875 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2877 if ((dic->op == LEFT_OP ||
2878 dic->op == RIGHT_OP ||
2880 IS_OP_LITERAL (IC_RIGHT (dic)))
2890 /*-----------------------------------------------------------------*/
2891 /* packRegsForAssign - register reduction for assignment */
2892 /*-----------------------------------------------------------------*/
2894 packRegsForAssign (iCode * ic, eBBlock * ebp)
2899 debugLog ("%s\n", __FUNCTION__);
2901 debugAopGet (" result:", IC_RESULT (ic));
2902 debugAopGet (" left:", IC_LEFT (ic));
2903 debugAopGet (" right:", IC_RIGHT (ic));
2905 /* if this is at an absolute address, then get the address. */
2906 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2907 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2908 debugLog (" %d - found config word declaration\n", __LINE__);
2909 if(IS_VALOP(IC_RIGHT(ic))) {
2910 debugLog (" setting config word to %x\n",
2911 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2912 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2913 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2916 /* remove the assignment from the iCode chain. */
2918 remiCodeFromeBBlock (ebp, ic);
2919 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2920 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2927 if (!IS_ITEMP (IC_RESULT (ic))) {
2928 allocDirReg(IC_RESULT (ic));
2929 debugLog (" %d - result is not temp\n", __LINE__);
2932 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2933 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2934 allocDirReg(IC_LEFT (ic));
2938 if (!IS_ITEMP (IC_RIGHT (ic))) {
2939 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2941 /* only pack if this is not a function pointer */
2942 if (!IS_REF (IC_RIGHT (ic)))
2943 allocDirReg(IC_RIGHT (ic));
2947 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2948 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2950 debugLog (" %d - not packing - right side fails \n", __LINE__);
2954 /* if the true symbol is defined in far space or on stack
2955 then we should not since this will increase register pressure */
2956 if (isOperandInFarSpace (IC_RESULT (ic)))
2958 if ((dic = farSpacePackable (ic)))
2964 /* find the definition of iTempNN scanning backwards if we find a
2965 a use of the true symbol before we find the definition then
2967 for (dic = ic->prev; dic; dic = dic->prev)
2970 /* if there is a function call and this is
2971 a parameter & not my parameter then don't pack it */
2972 if ((dic->op == CALL || dic->op == PCALL) &&
2973 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2974 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2976 debugLog (" %d - \n", __LINE__);
2984 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2985 IS_OP_VOLATILE (IC_RESULT (dic)))
2987 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2992 if (IS_SYMOP (IC_RESULT (dic)) &&
2993 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2995 /* A previous result was assigned to the same register - we'll our definition */
2996 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2997 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2998 if (POINTER_SET (dic))
3004 if (IS_SYMOP (IC_RIGHT (dic)) &&
3005 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3006 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3008 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3013 if (IS_SYMOP (IC_LEFT (dic)) &&
3014 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3015 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3017 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3022 if (POINTER_SET (dic) &&
3023 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3025 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3033 return 0; /* did not find */
3035 /* if assignment then check that right is not a bit */
3036 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
3038 sym_link *etype = operandType (IC_RESULT (dic));
3039 if (IS_BITFIELD (etype))
3041 /* if result is a bit too then it's ok */
3042 etype = operandType (IC_RESULT (ic));
3043 if (!IS_BITFIELD (etype))
3048 /* if the result is on stack or iaccess then it must be
3049 the same at least one of the operands */
3050 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3051 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3054 /* the operation has only one symbol
3055 operator then we can pack */
3056 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3057 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3060 if (!((IC_LEFT (dic) &&
3061 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3063 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3067 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3068 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3069 /* found the definition */
3070 /* replace the result with the result of */
3071 /* this assignment and remove this assignment */
3072 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3073 IC_RESULT (dic) = IC_RESULT (ic);
3075 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3077 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3079 /* delete from liverange table also
3080 delete from all the points inbetween and the new
3082 for (sic = dic; sic != ic; sic = sic->next)
3084 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3085 if (IS_ITEMP (IC_RESULT (dic)))
3086 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3089 remiCodeFromeBBlock (ebp, ic);
3090 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3091 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3092 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3098 /*-----------------------------------------------------------------*/
3099 /* findAssignToSym : scanning backwards looks for first assig found */
3100 /*-----------------------------------------------------------------*/
3102 findAssignToSym (operand * op, iCode * ic)
3106 debugLog ("%s\n", __FUNCTION__);
3107 for (dic = ic->prev; dic; dic = dic->prev)
3110 /* if definition by assignment */
3111 if (dic->op == '=' &&
3112 !POINTER_SET (dic) &&
3113 IC_RESULT (dic)->key == op->key
3114 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3118 /* we are interested only if defined in far space */
3119 /* or in stack space in case of + & - */
3121 /* if assigned to a non-symbol then return
3123 if (!IS_SYMOP (IC_RIGHT (dic)))
3126 /* if the symbol is in far space then
3128 if (isOperandInFarSpace (IC_RIGHT (dic)))
3131 /* for + & - operations make sure that
3132 if it is on the stack it is the same
3133 as one of the three operands */
3134 if ((ic->op == '+' || ic->op == '-') &&
3135 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3138 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3139 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3140 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3148 /* if we find an usage then we cannot delete it */
3149 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3152 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3155 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3159 /* now make sure that the right side of dic
3160 is not defined between ic & dic */
3163 iCode *sic = dic->next;
3165 for (; sic != ic; sic = sic->next)
3166 if (IC_RESULT (sic) &&
3167 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3176 /*-----------------------------------------------------------------*/
3177 /* packRegsForSupport :- reduce some registers for support calls */
3178 /*-----------------------------------------------------------------*/
3180 packRegsForSupport (iCode * ic, eBBlock * ebp)
3184 debugLog ("%s\n", __FUNCTION__);
3185 /* for the left & right operand :- look to see if the
3186 left was assigned a true symbol in far space in that
3187 case replace them */
3188 if (IS_ITEMP (IC_LEFT (ic)) &&
3189 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3191 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3197 debugAopGet ("removing left:", IC_LEFT (ic));
3199 /* found it we need to remove it from the
3201 for (sic = dic; sic != ic; sic = sic->next)
3202 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3204 IC_LEFT (ic)->operand.symOperand =
3205 IC_RIGHT (dic)->operand.symOperand;
3206 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3207 remiCodeFromeBBlock (ebp, dic);
3208 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3209 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3213 /* do the same for the right operand */
3216 IS_ITEMP (IC_RIGHT (ic)) &&
3217 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3219 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3225 /* if this is a subtraction & the result
3226 is a true symbol in far space then don't pack */
3227 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3229 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3230 if (IN_FARSPACE (SPEC_OCLS (etype)))
3234 debugAopGet ("removing right:", IC_RIGHT (ic));
3236 /* found it we need to remove it from the
3238 for (sic = dic; sic != ic; sic = sic->next)
3239 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3241 IC_RIGHT (ic)->operand.symOperand =
3242 IC_RIGHT (dic)->operand.symOperand;
3243 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3245 remiCodeFromeBBlock (ebp, dic);
3246 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3247 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3254 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3257 /*-----------------------------------------------------------------*/
3258 /* packRegsForOneuse : - will reduce some registers for single Use */
3259 /*-----------------------------------------------------------------*/
3261 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3266 debugLog ("%s\n", __FUNCTION__);
3267 /* if returning a literal then do nothing */
3271 /* only upto 2 bytes since we cannot predict
3272 the usage of b, & acc */
3273 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3278 /* this routine will mark the a symbol as used in one
3279 instruction use only && if the definition is local
3280 (ie. within the basic block) && has only one definition &&
3281 that definition is either a return value from a
3282 function or does not contain any variables in
3284 uses = bitVectCopy (OP_USES (op));
3285 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3286 if (!bitVectIsZero (uses)) /* has other uses */
3289 /* if it has only one defintion */
3290 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3291 return NULL; /* has more than one definition */
3293 /* get that definition */
3295 hTabItemWithKey (iCodehTab,
3296 bitVectFirstBit (OP_DEFS (op)))))
3299 /* found the definition now check if it is local */
3300 if (dic->seq < ebp->fSeq ||
3301 dic->seq > ebp->lSeq)
3302 return NULL; /* non-local */
3304 /* now check if it is the return from
3306 if (dic->op == CALL || dic->op == PCALL)
3308 if (ic->op != SEND && ic->op != RETURN &&
3309 !POINTER_SET(ic) && !POINTER_GET(ic))
3311 OP_SYMBOL (op)->ruonly = 1;
3318 /* otherwise check that the definition does
3319 not contain any symbols in far space */
3320 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3321 isOperandInFarSpace (IC_RIGHT (dic)) ||
3322 IS_OP_RUONLY (IC_LEFT (ic)) ||
3323 IS_OP_RUONLY (IC_RIGHT (ic)))
3328 /* if pointer set then make sure the pointer
3330 if (POINTER_SET (dic) &&
3331 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3334 if (POINTER_GET (dic) &&
3335 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3340 /* also make sure the intervenening instructions
3341 don't have any thing in far space */
3342 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3345 /* if there is an intervening function call then no */
3346 if (dic->op == CALL || dic->op == PCALL)
3348 /* if pointer set then make sure the pointer
3350 if (POINTER_SET (dic) &&
3351 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3354 if (POINTER_GET (dic) &&
3355 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3358 /* if address of & the result is remat then okay */
3359 if (dic->op == ADDRESS_OF &&
3360 OP_SYMBOL (IC_RESULT (dic))->remat)
3363 /* if operand has size of three or more & this
3364 operation is a '*','/' or '%' then 'b' may
3366 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3367 getSize (operandType (op)) >= 3)
3370 /* if left or right or result is in far space */
3371 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3372 isOperandInFarSpace (IC_RIGHT (dic)) ||
3373 isOperandInFarSpace (IC_RESULT (dic)) ||
3374 IS_OP_RUONLY (IC_LEFT (dic)) ||
3375 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3376 IS_OP_RUONLY (IC_RESULT (dic)))
3382 OP_SYMBOL (op)->ruonly = 1;
3387 /*-----------------------------------------------------------------*/
3388 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3389 /*-----------------------------------------------------------------*/
3391 isBitwiseOptimizable (iCode * ic)
3393 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3394 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3396 debugLog ("%s\n", __FUNCTION__);
3397 /* bitwise operations are considered optimizable
3398 under the following conditions (Jean-Louis VERN)
3410 if (IS_LITERAL (rtype) ||
3411 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3417 /*-----------------------------------------------------------------*/
3418 /* packRegsForAccUse - pack registers for acc use */
3419 /*-----------------------------------------------------------------*/
3421 packRegsForAccUse (iCode * ic)
3425 debugLog ("%s\n", __FUNCTION__);
3427 /* result too large for WREG? */
3428 if (getSize (operandType (IC_RESULT (ic))) > 1)
3431 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3432 * is never used as an operand to an instruction that
3433 * cannot have WREG as an operand (e.g. BTFSx cannot
3434 * operate on WREG...
3435 * For now, store all results into proper registers. */
3439 /* if this is an aggregate, e.g. a one byte char array */
3440 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3443 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3445 /* if + or - then it has to be one byte result */
3446 if ((ic->op == '+' || ic->op == '-')
3447 && getSize (operandType (IC_RESULT (ic))) > 1)
3450 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3451 /* if shift operation make sure right side is not a literal */
3452 if (ic->op == RIGHT_OP &&
3453 (isOperandLiteral (IC_RIGHT (ic)) ||
3454 getSize (operandType (IC_RESULT (ic))) > 1))
3457 if (ic->op == LEFT_OP &&
3458 (isOperandLiteral (IC_RIGHT (ic)) ||
3459 getSize (operandType (IC_RESULT (ic))) > 1))
3462 if (IS_BITWISE_OP (ic) &&
3463 getSize (operandType (IC_RESULT (ic))) > 1)
3467 /* has only one definition */
3468 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3471 /* has only one use */
3472 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3475 /* and the usage immediately follows this iCode */
3476 if (!(uic = hTabItemWithKey (iCodehTab,
3477 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3480 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3481 if (ic->next != uic)
3484 /* if it is a conditional branch then we definitely can */
3488 if (uic->op == JUMPTABLE)
3491 /* if the usage is not is an assignment
3492 or an arithmetic / bitwise / shift operation then not */
3493 if (POINTER_SET (uic) &&
3494 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3497 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3498 if (uic->op != '=' &&
3499 !IS_ARITHMETIC_OP (uic) &&
3500 !IS_BITWISE_OP (uic) &&
3501 uic->op != LEFT_OP &&
3502 uic->op != RIGHT_OP)
3505 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3506 /* if used in ^ operation then make sure right is not a
3508 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3511 /* if shift operation make sure right side is not a literal */
3512 if (uic->op == RIGHT_OP &&
3513 (isOperandLiteral (IC_RIGHT (uic)) ||
3514 getSize (operandType (IC_RESULT (uic))) > 1))
3517 if (uic->op == LEFT_OP &&
3518 (isOperandLiteral (IC_RIGHT (uic)) ||
3519 getSize (operandType (IC_RESULT (uic))) > 1))
3522 /* make sure that the result of this icode is not on the
3523 stack, since acc is used to compute stack offset */
3524 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3525 OP_SYMBOL (IC_RESULT (uic))->onStack)
3528 /* if either one of them in far space then we cannot */
3529 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3530 isOperandInFarSpace (IC_LEFT (uic))) ||
3531 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3532 isOperandInFarSpace (IC_RIGHT (uic))))
3535 /* if the usage has only one operand then we can */
3536 if (IC_LEFT (uic) == NULL ||
3537 IC_RIGHT (uic) == NULL)
3540 /* make sure this is on the left side if not
3541 a '+' since '+' is commutative */
3542 if (ic->op != '+' &&
3543 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3546 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3547 /* if one of them is a literal then we can */
3548 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3549 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3550 (getSize (operandType (IC_RESULT (uic))) <= 1))
3552 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3556 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3557 /* if the other one is not on stack then we can */
3558 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3559 (IS_ITEMP (IC_RIGHT (uic)) ||
3560 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3561 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3564 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3565 (IS_ITEMP (IC_LEFT (uic)) ||
3566 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3567 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3573 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3574 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3578 /*-----------------------------------------------------------------*/
3579 /* packForPush - hueristics to reduce iCode for pushing */
3580 /*-----------------------------------------------------------------*/
3582 packForReceive (iCode * ic, eBBlock * ebp)
3586 debugLog ("%s\n", __FUNCTION__);
3587 debugAopGet (" result:", IC_RESULT (ic));
3588 debugAopGet (" left:", IC_LEFT (ic));
3589 debugAopGet (" right:", IC_RIGHT (ic));
3594 for (dic = ic->next; dic; dic = dic->next)
3599 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3600 debugLog (" used on left\n");
3601 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3602 debugLog (" used on right\n");
3603 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3604 debugLog (" used on result\n");
3606 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3607 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3612 debugLog (" hey we can remove this unnecessary assign\n");
3614 /*-----------------------------------------------------------------*/
3615 /* packForPush - hueristics to reduce iCode for pushing */
3616 /*-----------------------------------------------------------------*/
3618 packForPush (iCode * ic, eBBlock * ebp)
3622 debugLog ("%s\n", __FUNCTION__);
3623 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3626 /* must have only definition & one usage */
3627 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3628 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3631 /* find the definition */
3632 if (!(dic = hTabItemWithKey (iCodehTab,
3633 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3636 if (dic->op != '=' || POINTER_SET (dic))
3639 /* we now we know that it has one & only one def & use
3640 and the that the definition is an assignment */
3641 IC_LEFT (ic) = IC_RIGHT (dic);
3643 remiCodeFromeBBlock (ebp, dic);
3644 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3645 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3648 void printSymType(char * str, sym_link *sl)
3650 debugLog (" %s Symbol type: ",str);
3651 printTypeChain( sl, debugF);
3656 /*-----------------------------------------------------------------*/
3657 /* some debug code to print the symbol S_TYPE. Note that
3658 * the function checkSClass in src/SDCCsymt.c dinks with
3659 * the S_TYPE in ways the PIC port doesn't fully like...*/
3660 /*-----------------------------------------------------------------*/
3661 void isData(sym_link *sl)
3671 for ( ; sl; sl=sl->next) {
3673 switch (SPEC_SCLS(sl)) {
3675 case S_DATA: fprintf (of, "data "); break;
3676 case S_XDATA: fprintf (of, "xdata "); break;
3677 case S_SFR: fprintf (of, "sfr "); break;
3678 case S_SBIT: fprintf (of, "sbit "); break;
3679 case S_CODE: fprintf (of, "code "); break;
3680 case S_IDATA: fprintf (of, "idata "); break;
3681 case S_PDATA: fprintf (of, "pdata "); break;
3682 case S_LITERAL: fprintf (of, "literal "); break;
3683 case S_STACK: fprintf (of, "stack "); break;
3684 case S_XSTACK: fprintf (of, "xstack "); break;
3685 case S_BIT: fprintf (of, "bit "); break;
3686 case S_EEPROM: fprintf (of, "eeprom "); break;
3696 /*-----------------------------------------------------------------*/
3697 /* packRegisters - does some transformations to reduce register */
3699 /*-----------------------------------------------------------------*/
3701 packRegisters (eBBlock * ebp)
3706 debugLog ("%s\n", __FUNCTION__);
3712 /* look for assignments of the form */
3713 /* iTempNN = TRueSym (someoperation) SomeOperand */
3715 /* TrueSym := iTempNN:1 */
3716 for (ic = ebp->sch; ic; ic = ic->next)
3719 /* find assignment of the form TrueSym := iTempNN:1 */
3720 if (ic->op == '=' && !POINTER_SET (ic))
3721 change += packRegsForAssign (ic, ebp);
3725 if (POINTER_SET (ic))
3726 debugLog ("pointer is set\n");
3727 debugAopGet (" result:", IC_RESULT (ic));
3728 debugAopGet (" left:", IC_LEFT (ic));
3729 debugAopGet (" right:", IC_RIGHT (ic));
3738 for (ic = ebp->sch; ic; ic = ic->next) {
3740 if(IS_SYMOP ( IC_LEFT(ic))) {
3741 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3743 debugAopGet (" left:", IC_LEFT (ic));
3744 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3745 debugLog (" is a pointer\n");
3747 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3748 debugLog (" is volatile\n");
3752 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3755 if(IS_SYMOP ( IC_RIGHT(ic))) {
3756 debugAopGet (" right:", IC_RIGHT (ic));
3757 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3760 if(IS_SYMOP ( IC_RESULT(ic))) {
3761 debugAopGet (" result:", IC_RESULT (ic));
3762 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3765 if (POINTER_SET (ic))
3766 debugLog (" %d - Pointer set\n", __LINE__);
3769 /* Look for two subsequent iCodes with */
3771 /* _c = iTemp & op; */
3772 /* and replace them by */
3775 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3777 ic->prev->op == '=' &&
3778 IS_ITEMP (IC_LEFT (ic)) &&
3779 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3780 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3782 iCode* ic_prev = ic->prev;
3783 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3785 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3786 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3788 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3789 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3790 prev_result_sym->liveTo == ic->seq)
3792 prev_result_sym->liveTo = ic_prev->seq;
3795 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3797 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3799 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3801 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3802 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3803 remiCodeFromeBBlock (ebp, ic_prev);
3804 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3808 /* if this is an itemp & result of a address of a true sym
3809 then mark this as rematerialisable */
3810 if (ic->op == ADDRESS_OF &&
3811 IS_ITEMP (IC_RESULT (ic)) &&
3812 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3813 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3814 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3817 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3819 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3820 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3821 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3825 /* if straight assignment then carry remat flag if
3826 this is the only definition */
3827 if (ic->op == '=' &&
3828 !POINTER_SET (ic) &&
3829 IS_SYMOP (IC_RIGHT (ic)) &&
3830 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3831 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3833 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3835 OP_SYMBOL (IC_RESULT (ic))->remat =
3836 OP_SYMBOL (IC_RIGHT (ic))->remat;
3837 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3838 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3841 /* if this is a +/- operation with a rematerizable
3842 then mark this as rematerializable as well */
3843 if ((ic->op == '+' || ic->op == '-') &&
3844 (IS_SYMOP (IC_LEFT (ic)) &&
3845 IS_ITEMP (IC_RESULT (ic)) &&
3846 OP_SYMBOL (IC_LEFT (ic))->remat &&
3847 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3848 IS_OP_LITERAL (IC_RIGHT (ic))))
3850 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3852 operandLitValue (IC_RIGHT (ic));
3853 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3854 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3855 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3858 /* mark the pointer usages */
3859 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3861 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3862 debugLog (" marking as a pointer (set) =>");
3863 debugAopGet (" result:", IC_RESULT (ic));
3865 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3867 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3868 debugLog (" marking as a pointer (get) =>");
3869 debugAopGet (" left:", IC_LEFT (ic));
3874 /* if we are using a symbol on the stack
3875 then we should say pic14_ptrRegReq */
3876 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3877 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3878 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3879 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3880 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3881 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3884 if (IS_SYMOP (IC_LEFT (ic)))
3885 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3886 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3887 if (IS_SYMOP (IC_RIGHT (ic)))
3888 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3889 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3890 if (IS_SYMOP (IC_RESULT (ic)))
3891 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3892 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3895 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3899 /* if the condition of an if instruction
3900 is defined in the previous instruction then
3901 mark the itemp as a conditional */
3902 if ((IS_CONDITIONAL (ic) ||
3903 ((ic->op == BITWISEAND ||
3906 isBitwiseOptimizable (ic))) &&
3907 ic->next && ic->next->op == IFX &&
3908 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3909 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3912 debugLog (" %d\n", __LINE__);
3913 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3917 /* reduce for support function calls */
3918 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3919 packRegsForSupport (ic, ebp);
3921 /* if a parameter is passed, it's in W, so we may not
3922 need to place a copy in a register */
3923 if (ic->op == RECEIVE)
3924 packForReceive (ic, ebp);
3926 /* some cases the redundant moves can
3927 can be eliminated for return statements */
3928 if ((ic->op == RETURN || ic->op == SEND) &&
3929 !isOperandInFarSpace (IC_LEFT (ic)) &&
3931 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3933 /* if pointer set & left has a size more than
3934 one and right is not in far space */
3935 if (POINTER_SET (ic) &&
3936 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3937 IS_SYMOP(IC_RESULT(ic)) &&
3938 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3939 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3940 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3942 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3944 /* if pointer get */
3945 if (POINTER_GET (ic) &&
3946 !isOperandInFarSpace (IC_RESULT (ic)) &&
3947 IS_SYMOP(IC_LEFT(ic)) &&
3948 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3949 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3950 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3952 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3955 /* if this is cast for intergral promotion then
3956 check if only use of the definition of the
3957 operand being casted/ if yes then replace
3958 the result of that arithmetic operation with
3959 this result and get rid of the cast */
3960 if (ic->op == CAST) {
3962 sym_link *fromType = operandType (IC_RIGHT (ic));
3963 sym_link *toType = operandType (IC_LEFT (ic));
3965 debugLog (" %d - casting\n", __LINE__);
3967 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3968 getSize (fromType) != getSize (toType)) {
3971 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3974 if (IS_ARITHMETIC_OP (dic)) {
3976 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3977 IC_RESULT (dic) = IC_RESULT (ic);
3978 remiCodeFromeBBlock (ebp, ic);
3979 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3980 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3981 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3985 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3989 /* if the type from and type to are the same
3990 then if this is the only use then packit */
3991 if (compareType (operandType (IC_RIGHT (ic)),
3992 operandType (IC_LEFT (ic))) == 1) {
3994 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3997 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3998 IC_RESULT (dic) = IC_RESULT (ic);
3999 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4000 remiCodeFromeBBlock (ebp, ic);
4001 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4002 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4010 iTempNN := (some variable in farspace) V1
4015 if (ic->op == IPUSH)
4017 packForPush (ic, ebp);
4021 /* pack registers for accumulator use, when the
4022 result of an arithmetic or bit wise operation
4023 has only one use, that use is immediately following
4024 the defintion and the using iCode has only one
4025 operand or has two operands but one is literal &
4026 the result of that operation is not on stack then
4027 we can leave the result of this operation in acc:b
4029 if ((IS_ARITHMETIC_OP (ic)
4031 || IS_BITWISE_OP (ic)
4033 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4036 IS_ITEMP (IC_RESULT (ic)) &&
4037 getSize (operandType (IC_RESULT (ic))) <= 2)
4039 packRegsForAccUse (ic);
4045 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4049 if (!debug || !debugF)
4052 for (i = 0; i < count; i++)
4054 fprintf (debugF, "\n----------------------------------------------------------------\n");
4055 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4056 ebbs[i]->entryLabel->name,
4059 ebbs[i]->isLastInLoop);
4060 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4065 fprintf (debugF, "visited %d : hasFcall = %d\n",
4069 fprintf (debugF, "\ndefines bitVector :");
4070 bitVectDebugOn (ebbs[i]->defSet, debugF);
4071 fprintf (debugF, "\nlocal defines bitVector :");
4072 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4073 fprintf (debugF, "\npointers Set bitvector :");
4074 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4075 fprintf (debugF, "\nin pointers Set bitvector :");
4076 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4077 fprintf (debugF, "\ninDefs Set bitvector :");
4078 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4079 fprintf (debugF, "\noutDefs Set bitvector :");
4080 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4081 fprintf (debugF, "\nusesDefs Set bitvector :");
4082 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4083 fprintf (debugF, "\n----------------------------------------------------------------\n");
4084 printiCChain (ebbs[i]->sch, debugF);
4087 /*-----------------------------------------------------------------*/
4088 /* assignRegisters - assigns registers to each live range as need */
4089 /*-----------------------------------------------------------------*/
4091 pic14_assignRegisters (ebbIndex * ebbi)
4093 eBBlock ** ebbs = ebbi->bbOrder;
4094 int count = ebbi->count;
4098 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4099 debugLog ("ebbs before optimizing:\n");
4100 dumpEbbsToDebug (ebbs, count);
4102 setToNull ((void *) &_G.funcrUsed);
4103 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4106 /* change assignments this will remove some
4107 live ranges reducing some register pressure */
4108 for (i = 0; i < count; i++)
4109 packRegisters (ebbs[i]);
4116 debugLog("dir registers allocated so far:\n");
4117 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4120 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4121 reg = hTabNextItem(dynDirectRegNames, &hkey);
4126 if (options.dump_pack)
4127 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4129 /* first determine for each live range the number of
4130 registers & the type of registers required for each */
4133 /* and serially allocate registers */
4134 serialRegAssign (ebbs, count);
4136 /* if stack was extended then tell the user */
4139 /* werror(W_TOOMANY_SPILS,"stack", */
4140 /* _G.stackExtend,currFunc->name,""); */
4146 /* werror(W_TOOMANY_SPILS,"data space", */
4147 /* _G.dataExtend,currFunc->name,""); */
4151 /* after that create the register mask
4152 for each of the instruction */
4153 createRegMask (ebbs, count);
4155 /* redo that offsets for stacked automatic variables */
4156 redoStackOffsets ();
4158 if (options.dump_rassgn)
4159 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4161 /* now get back the chain */
4162 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4164 debugLog ("ebbs after optimizing:\n");
4165 dumpEbbsToDebug (ebbs, count);
4170 /* free up any _G.stackSpil locations allocated */
4171 applyToSet (_G.stackSpil, deallocStackSpil);
4173 setToNull ((void *) &_G.stackSpil);
4174 setToNull ((void *) &_G.spiltSet);
4175 /* mark all registers as free */
4176 //pic14_freeAllRegs ();
4178 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");