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 ELIPSIS: return "ELIPSIS";
261 case RANGE: return "RANGE";
262 case FAR: return "FAR";
263 case CASE: return "CASE";
264 case DEFAULT: return "DEFAULT";
265 case IF: return "IF";
266 case ELSE: return "ELSE";
267 case SWITCH: return "SWITCH";
268 case WHILE: return "WHILE";
269 case DO: return "DO";
270 case FOR: return "FOR";
271 case GOTO: return "GOTO";
272 case CONTINUE: return "CONTINUE";
273 case BREAK: return "BREAK";
274 case RETURN: return "RETURN";
275 case INLINEASM: return "INLINEASM";
276 case IFX: return "IFX";
277 case ADDRESS_OF: return "ADDRESS_OF";
278 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
279 case SPIL: return "SPIL";
280 case UNSPIL: return "UNSPIL";
281 case GETHBIT: return "GETHBIT";
282 case BITWISEAND: return "BITWISEAND";
283 case UNARYMINUS: return "UNARYMINUS";
284 case IPUSH: return "IPUSH";
285 case IPOP: return "IPOP";
286 case PCALL: return "PCALL";
287 case ENDFUNCTION: return "ENDFUNCTION";
288 case JUMPTABLE: return "JUMPTABLE";
289 case RRC: return "RRC";
290 case RLC: return "RLC";
291 case CAST: return "CAST";
292 case CALL: return "CALL";
293 case PARAM: return "PARAM ";
294 case NULLOP: return "NULLOP";
295 case BLOCK: return "BLOCK";
296 case LABEL: return "LABEL";
297 case RECEIVE: return "RECEIVE";
298 case SEND: return "SEND";
300 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
303 /*-----------------------------------------------------------------*/
304 /*-----------------------------------------------------------------*/
306 debugLogRegType (short type)
311 case REG_GPR: return "REG_GPR";
312 case REG_PTR: return "REG_PTR";
313 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
320 /*-----------------------------------------------------------------*/
321 /*-----------------------------------------------------------------*/
322 static int regname2key(char const *name)
331 key += (*name++) + 1;
335 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
339 static regs *regWithIdx (set *dRegs, int idx, int fixed);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
346 regs *dReg, *reg_alias;
348 /* check whether a matching register already exists */
349 dReg = dirregWithName( name );
351 //printf( "%s: already present: %s\n", __FUNCTION__, name );
355 // check whether a register at that location exists
356 reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
357 if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
359 // create a new register
360 dReg = Safe_calloc(1,sizeof(regs));
362 dReg->pc_type = pc_type;
365 dReg->name = Safe_strdup(name);
367 sprintf(buffer,"r0x%02X", dReg->rIdx);
368 dReg->name = Safe_strdup(buffer);
384 dReg->reg_alias = reg_alias;
385 dReg->reglives.usedpFlows = newSet();
386 dReg->reglives.assignedpFlows = newSet();
387 if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
388 debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
393 /*-----------------------------------------------------------------*/
394 /* regWithIdx - Search through a set of registers that matches idx */
395 /*-----------------------------------------------------------------*/
397 regWithIdx (set *dRegs, int idx, int fixed)
401 for (dReg = setFirstItem(dRegs) ; dReg ;
402 dReg = setNextItem(dRegs)) {
404 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
405 while (dReg->reg_alias) dReg = dReg->reg_alias;
413 /*-----------------------------------------------------------------*/
414 /* regWithName - Search through a set of registers that matches name */
415 /*-----------------------------------------------------------------*/
417 regWithName (set *dRegs, const char *name)
421 for (dReg = setFirstItem(dRegs) ; dReg ;
422 dReg = setNextItem(dRegs)) {
424 if((strcmp(name,dReg->name)==0)) {
432 /*-----------------------------------------------------------------*/
433 /* regWithName - Search for a registers that matches name */
434 /*-----------------------------------------------------------------*/
436 regFindWithName (const char *name)
440 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
441 debugLog ("Found a Direct Register!\n");
444 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
445 debugLog ("Found a Direct Bit Register!\n");
449 if (*name=='_') name++; // Step passed '_'
451 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
452 debugLog ("Found a Dynamic Register!\n");
455 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
456 debugLog ("Found a Processor Register!\n");
459 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
460 debugLog ("Found an Internal Register!\n");
463 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
464 debugLog ("Found an Stack Register!\n");
471 /*-----------------------------------------------------------------*/
472 /* regFindFree - Search for a free register in a set of registers */
473 /*-----------------------------------------------------------------*/
475 regFindFree (set *dRegs)
479 for (dReg = setFirstItem(dRegs) ; dReg ;
480 dReg = setNextItem(dRegs)) {
488 /*-----------------------------------------------------------------*/
489 /* initStack - allocate registers for a pseudo stack */
490 /*-----------------------------------------------------------------*/
491 void initStack(int base_address, int size, int shared)
497 pic = pic14_getPIC();
498 Gstack_base_addr = base_address;
500 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
502 for(i = 0; i<size; i++) {
505 SNPRINTF(&buffer[0], 16, "STK%02d", i);
506 // multi-bank device, sharebank prohibited by user
507 r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
512 addSet(&dynStackRegs,r);
516 /*-----------------------------------------------------------------*
517 *-----------------------------------------------------------------*/
519 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
522 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
523 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
526 /*-----------------------------------------------------------------*
527 *-----------------------------------------------------------------*/
530 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
532 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
534 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
537 return addSet(&dynInternalRegs,reg);
542 /*-----------------------------------------------------------------*/
543 /* allocReg - allocates register of given type */
544 /*-----------------------------------------------------------------*/
546 allocReg (short type)
550 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
551 //fprintf(stderr,"allocReg\n");
553 reg = pic14_findFreeReg (type);
561 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
566 /*-----------------------------------------------------------------*/
567 /* dirregWithName - search for register by name */
568 /*-----------------------------------------------------------------*/
570 dirregWithName (char *name)
578 /* hash the name to get a key */
580 hkey = regname2key(name);
582 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
586 if(STRCASECMP(reg->name, name) == 0) {
587 // handle registers with multiple names
588 while (reg->reg_alias) reg = reg->reg_alias;
592 reg = hTabNextItemWK (dynDirectRegNames);
596 return NULL; // name wasn't found in the hash table
599 int IS_CONFIG_ADDRESS(int address)
602 return ((address == 0x2007) || (address == 0x2008));
605 /*-----------------------------------------------------------------*/
606 /* allocNewDirReg - allocates a new register of given type */
607 /*-----------------------------------------------------------------*/
609 allocNewDirReg (sym_link *symlnk,const char *name)
613 sym_link *spec = getSpec (symlnk);
615 /* if this is at an absolute address, then get the address. */
616 if (SPEC_ABSA (spec) ) {
617 address = SPEC_ADDR (spec);
618 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
621 /* Register wasn't found in hash, so let's create
622 * a new one and put it in the hash table AND in the
623 * dynDirectRegNames set */
624 if (IS_CONFIG_ADDRESS(address)) {
625 debugLog (" -- %s is declared at address 0x2007\n",name);
630 if (IS_BITVAR (spec))
637 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
638 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
640 if (SPEC_ABSA (spec) ) {
644 if (IS_BITVAR (spec)) {
645 addSet(&dynDirectBitRegs, reg);
648 addSet(&dynDirectRegs, reg);
650 if (!IS_STATIC (spec)) {
653 if (IS_EXTERN (spec)) {
659 if (address && reg) {
661 reg->address = address;
662 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
668 /*-----------------------------------------------------------------*/
669 /* allocDirReg - allocates register of given type */
670 /*-----------------------------------------------------------------*/
672 allocDirReg (operand *op )
679 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
683 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
685 /* If the symbol is at a fixed address, then remove the leading underscore
686 * from the name. This is hack to allow the .asm include file named registers
687 * to match the .c declared register names */
689 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
692 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
694 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
695 debugLog(" %d const char\n",__LINE__);
696 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
699 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
700 if (IS_CODE ( OP_SYM_ETYPE(op)) )
701 debugLog(" %d code space\n",__LINE__);
703 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
704 debugLog(" %d integral\n",__LINE__);
705 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
706 debugLog(" %d literal\n",__LINE__);
707 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
708 debugLog(" %d specifier\n",__LINE__);
709 debugAopGet(NULL, op);
712 if (IS_CODE ( OP_SYM_ETYPE(op)) )
715 /* First, search the hash table to see if there is a register with this name */
716 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
717 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
720 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
721 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
723 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
724 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
727 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
729 reg = dirregWithName(name);
736 /* if this is at an absolute address, then get the address. */
737 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
738 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
739 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
742 /* Register wasn't found in hash, so let's create
743 * a new one and put it in the hash table AND in the
744 * dynDirectRegNames set */
745 if(!IS_CONFIG_ADDRESS(address)) {
746 //fprintf(stderr,"allocating new reg %s\n",name);
748 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
749 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
751 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
753 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
755 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
759 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
760 addSet(&dynDirectBitRegs, reg);
763 addSet(&dynDirectRegs, reg);
765 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
768 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
774 debugLog (" -- %s is declared at address 0x2007\n",name);
779 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
781 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
782 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
787 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
789 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
790 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
793 allocNewDirReg (OP_SYM_TYPE(op),name);
800 /*-----------------------------------------------------------------*/
801 /* allocRegByName - allocates register with given name */
802 /*-----------------------------------------------------------------*/
804 allocRegByName (char *name, int size)
810 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
814 /* First, search the hash table to see if there is a register with this name */
815 reg = dirregWithName(name);
821 /* Register wasn't found in hash, so let's create
822 * a new one and put it in the hash table AND in the
823 * dynDirectRegNames set */
824 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
825 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
826 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
827 if (strcmp(reg->name+1,sym->name)==0) {
828 unsigned a = SPEC_ADDR(sym->etype);
832 if (!IS_STATIC (sym->etype)) {
835 if (IS_EXTERN (sym->etype)) {
838 if (IS_BITVAR (sym->etype))
845 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
846 if (strcmp(reg->name+1,sym->name)==0) {
847 unsigned a = SPEC_ADDR(sym->etype);
849 if (!IS_STATIC (sym->etype)) {
852 if (IS_EXTERN (sym->etype)) {
855 if (IS_BITVAR (sym->etype))
863 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
865 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
866 if (reg->isBitField) {
867 addSet(&dynDirectBitRegs, reg);
869 addSet(&dynDirectRegs, reg);
875 /*-----------------------------------------------------------------*/
876 /* RegWithIdx - returns pointer to register with index number */
877 /*-----------------------------------------------------------------*/
879 typeRegWithIdx (int idx, int type, int fixed)
884 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
889 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
891 debugLog ("Found a Dynamic Register!\n");
894 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
895 debugLog ("Found a Direct Register!\n");
901 if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
902 debugLog ("Found a Stack Register!\n");
905 if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
906 debugLog ("Found a Stack Register!\n");
910 werror (E_STACK_OUT, "Register");
911 /* return an existing register just to avoid the SDCC crash */
912 return regWithIdx ( dynStackRegs, 0x7f, 0);
916 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
917 debugLog ("Found a Processor Register!\n");
931 /*-----------------------------------------------------------------*/
932 /* pic14_regWithIdx - returns pointer to register with index number*/
933 /*-----------------------------------------------------------------*/
935 pic14_regWithIdx (int idx)
939 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
942 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
948 /*-----------------------------------------------------------------*/
949 /* pic14_regWithIdx - returns pointer to register with index number */
950 /*-----------------------------------------------------------------*/
952 pic14_allocWithIdx (int idx)
957 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
959 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
961 debugLog ("Found a Dynamic Register!\n");
962 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
963 debugLog ("Found a Stack Register!\n");
964 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
965 debugLog ("Found a Processor Register!\n");
966 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
967 debugLog ("Found an Internal Register!\n");
968 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
969 debugLog ("Found an Internal Register!\n");
972 debugLog ("Dynamic Register not found\n");
975 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
976 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
977 "regWithIdx not found");
987 /*-----------------------------------------------------------------*/
988 /*-----------------------------------------------------------------*/
990 pic14_findFreeReg(short type)
997 if((dReg = regFindFree(dynAllocRegs)) != NULL)
999 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1003 if((dReg = regFindFree(dynStackRegs)) != NULL)
1015 /*-----------------------------------------------------------------*/
1016 /* freeReg - frees a register */
1017 /*-----------------------------------------------------------------*/
1019 freeReg (regs * reg)
1021 debugLog ("%s\n", __FUNCTION__);
1026 /*-----------------------------------------------------------------*/
1027 /* nFreeRegs - returns number of free registers */
1028 /*-----------------------------------------------------------------*/
1030 nFreeRegs (int type)
1032 /* dynamically allocate as many as we need and worry about
1033 * fitting them into a PIC later */
1040 debugLog ("%s\n", __FUNCTION__);
1041 for (i = 0; i < pic14_nRegs; i++)
1042 if (regspic14[i].isFree && regspic14[i].type == type)
1048 /*-----------------------------------------------------------------*/
1049 /* nfreeRegsType - free registers with type */
1050 /*-----------------------------------------------------------------*/
1052 nfreeRegsType (int type)
1055 debugLog ("%s\n", __FUNCTION__);
1056 if (type == REG_PTR)
1058 if ((nfr = nFreeRegs (type)) == 0)
1059 return nFreeRegs (REG_GPR);
1062 return nFreeRegs (type);
1065 void writeSetUsedRegs(FILE *of, set *dRegs)
1070 for (dReg = setFirstItem(dRegs) ; dReg ;
1071 dReg = setNextItem(dRegs)) {
1074 fprintf (of, "\t%s\n",dReg->name);
1078 extern void dump_map(void);
1080 void packBits(set *bregs)
1084 regs *bitfield=NULL;
1085 regs *relocbitfield=NULL;
1091 for (regset = bregs ; regset ;
1092 regset = regset->next) {
1094 breg = regset->item;
1095 breg->isBitField = 1;
1096 //fprintf(stderr,"bit reg: %s\n",breg->name);
1099 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1101 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1102 breg->rIdx = breg->address & 7;
1103 breg->address >>= 3;
1106 //sprintf (buffer, "fbitfield%02x", breg->address);
1107 sprintf (buffer, "0x%02x", breg->address);
1108 //fprintf(stderr,"new bit field\n");
1109 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1110 bitfield->isBitField = 1;
1111 bitfield->isFixed = 1;
1112 bitfield->address = breg->address;
1113 //addSet(&dynDirectRegs,bitfield);
1114 addSet(&dynInternalRegs,bitfield);
1115 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1117 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1120 breg->reg_alias = bitfield;
1124 if(!relocbitfield || bit_no >7) {
1127 sprintf (buffer, "bitfield%d", byte_no);
1128 //fprintf(stderr,"new relocatable bit field\n");
1129 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
1130 relocbitfield->isBitField = 1;
1131 //addSet(&dynDirectRegs,relocbitfield);
1132 addSet(&dynInternalRegs,relocbitfield);
1133 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1137 breg->reg_alias = relocbitfield;
1138 breg->address = dynrIdx; /* byte_no; */
1139 breg->rIdx = bit_no++;
1147 void bitEQUs(FILE *of, set *bregs)
1149 regs *breg,*bytereg;
1152 //fprintf(stderr," %s\n",__FUNCTION__);
1153 for (breg = setFirstItem(bregs) ; breg ;
1154 breg = setNextItem(bregs)) {
1156 //fprintf(stderr,"bit reg: %s\n",breg->name);
1158 bytereg = breg->reg_alias;
1160 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1163 breg->rIdx & 0x0007);
1166 //fprintf(stderr, "bit field is not assigned to a register\n");
1167 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1178 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1183 for (reg = setFirstItem(fregs) ; reg ;
1184 reg = setNextItem(fregs)) {
1186 //if(!reg->isEmitted && reg->wasUsed) {
1189 fprintf (of, "%s\tEQU\t0x%03x\n",
1193 fprintf (of, "%s\tEQU\t0x%03x\n",
1201 void writeUsedRegs(FILE *of)
1204 packBits(dynDirectBitRegs);
1208 bitEQUs(of,dynDirectBitRegs);
1211 /*-----------------------------------------------------------------*/
1212 /* computeSpillable - given a point find the spillable live ranges */
1213 /*-----------------------------------------------------------------*/
1215 computeSpillable (iCode * ic)
1219 debugLog ("%s\n", __FUNCTION__);
1220 /* spillable live ranges are those that are live at this
1221 point . the following categories need to be subtracted
1223 a) - those that are already spilt
1224 b) - if being used by this one
1225 c) - defined by this one */
1227 spillable = bitVectCopy (ic->rlive);
1229 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1231 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1232 bitVectUnSetBit (spillable, ic->defKey);
1233 spillable = bitVectIntersect (spillable, _G.regAssigned);
1238 /*-----------------------------------------------------------------*/
1239 /* noSpilLoc - return true if a variable has no spil location */
1240 /*-----------------------------------------------------------------*/
1242 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1244 debugLog ("%s\n", __FUNCTION__);
1245 return (sym->usl.spillLoc ? 0 : 1);
1248 /*-----------------------------------------------------------------*/
1249 /* hasSpilLoc - will return 1 if the symbol has spil location */
1250 /*-----------------------------------------------------------------*/
1252 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1254 debugLog ("%s\n", __FUNCTION__);
1255 return (sym->usl.spillLoc ? 1 : 0);
1258 /*-----------------------------------------------------------------*/
1259 /* directSpilLoc - will return 1 if the splilocation is in direct */
1260 /*-----------------------------------------------------------------*/
1262 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1264 debugLog ("%s\n", __FUNCTION__);
1265 if (sym->usl.spillLoc &&
1266 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1272 /*-----------------------------------------------------------------*/
1273 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1274 /* but is not used as a pointer */
1275 /*-----------------------------------------------------------------*/
1277 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1279 debugLog ("%s\n", __FUNCTION__);
1280 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1283 /*-----------------------------------------------------------------*/
1284 /* rematable - will return 1 if the remat flag is set */
1285 /*-----------------------------------------------------------------*/
1287 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1289 debugLog ("%s\n", __FUNCTION__);
1293 /*-----------------------------------------------------------------*/
1294 /* notUsedInRemaining - not used or defined in remain of the block */
1295 /*-----------------------------------------------------------------*/
1297 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1299 debugLog ("%s\n", __FUNCTION__);
1300 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1301 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1304 /*-----------------------------------------------------------------*/
1305 /* allLRs - return true for all */
1306 /*-----------------------------------------------------------------*/
1308 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1310 debugLog ("%s\n", __FUNCTION__);
1314 /*-----------------------------------------------------------------*/
1315 /* liveRangesWith - applies function to a given set of live range */
1316 /*-----------------------------------------------------------------*/
1318 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1319 eBBlock * ebp, iCode * ic)
1324 debugLog ("%s\n", __FUNCTION__);
1325 if (!lrs || !lrs->size)
1328 for (i = 1; i < lrs->size; i++)
1331 if (!bitVectBitValue (lrs, i))
1334 /* if we don't find it in the live range
1335 hash table we are in serious trouble */
1336 if (!(sym = hTabItemWithKey (liveRanges, i)))
1338 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1339 "liveRangesWith could not find liveRange");
1343 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1344 addSetHead (&rset, sym);
1351 /*-----------------------------------------------------------------*/
1352 /* leastUsedLR - given a set determines which is the least used */
1353 /*-----------------------------------------------------------------*/
1355 leastUsedLR (set * sset)
1357 symbol *sym = NULL, *lsym = NULL;
1359 debugLog ("%s\n", __FUNCTION__);
1360 sym = lsym = setFirstItem (sset);
1365 for (; lsym; lsym = setNextItem (sset))
1368 /* if usage is the same then prefer
1369 the spill the smaller of the two */
1370 if (lsym->used == sym->used)
1371 if (getSize (lsym->type) < getSize (sym->type))
1375 if (lsym->used < sym->used)
1380 setToNull ((void *) &sset);
1385 /*-----------------------------------------------------------------*/
1386 /* noOverLap - will iterate through the list looking for over lap */
1387 /*-----------------------------------------------------------------*/
1389 noOverLap (set * itmpStack, symbol * fsym)
1392 debugLog ("%s\n", __FUNCTION__);
1395 for (sym = setFirstItem (itmpStack); sym;
1396 sym = setNextItem (itmpStack))
1398 if (sym->liveTo > fsym->liveFrom)
1406 /*-----------------------------------------------------------------*/
1407 /* isFree - will return 1 if the a free spil location is found */
1408 /*-----------------------------------------------------------------*/
1413 V_ARG (symbol **, sloc);
1414 V_ARG (symbol *, fsym);
1416 debugLog ("%s\n", __FUNCTION__);
1417 /* if already found */
1421 /* if it is free && and the itmp assigned to
1422 this does not have any overlapping live ranges
1423 with the one currently being assigned and
1424 the size can be accomodated */
1426 noOverLap (sym->usl.itmpStack, fsym) &&
1427 getSize (sym->type) >= getSize (fsym->type))
1436 /*-----------------------------------------------------------------*/
1437 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1438 /*-----------------------------------------------------------------*/
1440 spillLRWithPtrReg (symbol * forSym)
1446 debugLog ("%s\n", __FUNCTION__);
1447 if (!_G.regAssigned ||
1448 bitVectIsZero (_G.regAssigned))
1451 r0 = pic14_regWithIdx (R0_IDX);
1452 r1 = pic14_regWithIdx (R1_IDX);
1454 /* for all live ranges */
1455 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1456 lrsym = hTabNextItem (liveRanges, &k))
1460 /* if no registers assigned to it or
1462 /* if it does not overlap with this then
1463 not need to spill it */
1465 if (lrsym->isspilt || !lrsym->nRegs ||
1466 (lrsym->liveTo < forSym->liveFrom))
1469 /* go thru the registers : if it is either
1470 r0 or r1 then spil it */
1471 for (j = 0; j < lrsym->nRegs; j++)
1472 if (lrsym->regs[j] == r0 ||
1473 lrsym->regs[j] == r1)
1482 /*-----------------------------------------------------------------*/
1483 /* createStackSpil - create a location on the stack to spil */
1484 /*-----------------------------------------------------------------*/
1486 createStackSpil (symbol * sym)
1488 symbol *sloc = NULL;
1489 int useXstack, model, noOverlay;
1491 char slocBuffer[30];
1492 debugLog ("%s\n", __FUNCTION__);
1496 /* first go try and find a free one that is already
1497 existing on the stack */
1498 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1500 /* found a free one : just update & return */
1501 sym->usl.spillLoc = sloc;
1504 addSetHead (&sloc->usl.itmpStack, sym);
1508 /* could not then have to create one , this is the hard part
1509 we need to allocate this on the stack : this is really a
1510 hack!! but cannot think of anything better at this time */
1512 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1514 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1515 __FILE__, __LINE__);
1519 sloc = newiTemp (slocBuffer);
1521 /* set the type to the spilling symbol */
1522 sloc->type = copyLinkChain (sym->type);
1523 sloc->etype = getSpec (sloc->type);
1524 SPEC_SCLS (sloc->etype) = S_DATA;
1525 SPEC_EXTR (sloc->etype) = 0;
1526 SPEC_STAT (sloc->etype) = 0;
1528 /* we don't allow it to be allocated`
1529 onto the external stack since : so we
1530 temporarily turn it off ; we also
1531 turn off memory model to prevent
1532 the spil from going to the external storage
1533 and turn off overlaying
1536 useXstack = options.useXstack;
1537 model = options.model;
1538 noOverlay = options.noOverlay;
1539 options.noOverlay = 1;
1540 options.model = options.useXstack = 0;
1544 options.useXstack = useXstack;
1545 options.model = model;
1546 options.noOverlay = noOverlay;
1547 sloc->isref = 1; /* to prevent compiler warning */
1549 /* if it is on the stack then update the stack */
1550 if (IN_STACK (sloc->etype))
1552 currFunc->stack += getSize (sloc->type);
1553 _G.stackExtend += getSize (sloc->type);
1556 _G.dataExtend += getSize (sloc->type);
1558 /* add it to the _G.stackSpil set */
1559 addSetHead (&_G.stackSpil, sloc);
1560 sym->usl.spillLoc = sloc;
1563 /* add it to the set of itempStack set
1564 of the spill location */
1565 addSetHead (&sloc->usl.itmpStack, sym);
1569 /*-----------------------------------------------------------------*/
1570 /* isSpiltOnStack - returns true if the spil location is on stack */
1571 /*-----------------------------------------------------------------*/
1573 isSpiltOnStack (symbol * sym)
1577 debugLog ("%s\n", __FUNCTION__);
1586 /* if (sym->_G.stackSpil) */
1589 if (!sym->usl.spillLoc)
1592 etype = getSpec (sym->usl.spillLoc->type);
1593 if (IN_STACK (etype))
1599 /*-----------------------------------------------------------------*/
1600 /* spillThis - spils a specific operand */
1601 /*-----------------------------------------------------------------*/
1603 spillThis (symbol * sym)
1606 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1607 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1609 /* if this is rematerializable or has a spillLocation
1610 we are okay, else we need to create a spillLocation
1612 if (!(sym->remat || sym->usl.spillLoc))
1613 createStackSpil (sym);
1616 /* mark it has spilt & put it in the spilt set */
1618 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1620 bitVectUnSetBit (_G.regAssigned, sym->key);
1622 for (i = 0; i < sym->nRegs; i++)
1626 freeReg (sym->regs[i]);
1627 sym->regs[i] = NULL;
1631 /* if spilt on stack then free up r0 & r1
1632 if they could have been assigned to some
1634 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1637 spillLRWithPtrReg (sym);
1640 if (sym->usl.spillLoc && !sym->remat)
1641 sym->usl.spillLoc->allocreq = 1;
1646 /*-----------------------------------------------------------------*/
1647 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1648 /*-----------------------------------------------------------------*/
1650 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1652 bitVect *lrcs = NULL;
1656 debugLog ("%s\n", __FUNCTION__);
1658 /* get the spillable live ranges */
1659 lrcs = computeSpillable (ic);
1662 /* get all live ranges that are rematerizable */
1663 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1665 /* return the least used of these */
1666 return leastUsedLR (selectS);
1669 /* get live ranges with spillLocations in direct space */
1670 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1672 sym = leastUsedLR (selectS);
1673 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1674 sym->usl.spillLoc->rname :
1675 sym->usl.spillLoc->name));
1677 /* mark it as allocation required */
1678 sym->usl.spillLoc->allocreq = 1;
1682 /* if the symbol is local to the block then */
1683 if (forSym->liveTo < ebp->lSeq)
1686 /* check if there are any live ranges allocated
1687 to registers that are not used in this block */
1688 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1690 sym = leastUsedLR (selectS);
1691 /* if this is not rematerializable */
1700 /* check if there are any live ranges that not
1701 used in the remainder of the block */
1702 if (!_G.blockSpil &&
1703 !isiCodeInFunctionCall (ic) &&
1704 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1706 sym = leastUsedLR (selectS);
1709 sym->remainSpil = 1;
1716 /* find live ranges with spillocation && not used as pointers */
1717 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1720 sym = leastUsedLR (selectS);
1721 /* mark this as allocation required */
1722 sym->usl.spillLoc->allocreq = 1;
1726 /* find live ranges with spillocation */
1727 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1730 sym = leastUsedLR (selectS);
1731 sym->usl.spillLoc->allocreq = 1;
1735 /* couldn't find then we need to create a spil
1736 location on the stack , for which one? the least
1738 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1741 /* return a created spil location */
1742 sym = createStackSpil (leastUsedLR (selectS));
1743 sym->usl.spillLoc->allocreq = 1;
1747 /* this is an extreme situation we will spill
1748 this one : happens very rarely but it does happen */
1754 /*-----------------------------------------------------------------*/
1755 /* spilSomething - spil some variable & mark registers as free */
1756 /*-----------------------------------------------------------------*/
1758 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1763 debugLog ("%s\n", __FUNCTION__);
1764 /* get something we can spil */
1765 ssym = selectSpil (ic, ebp, forSym);
1767 /* mark it as spilt */
1769 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1771 /* mark it as not register assigned &
1772 take it away from the set */
1773 bitVectUnSetBit (_G.regAssigned, ssym->key);
1775 /* mark the registers as free */
1776 for (i = 0; i < ssym->nRegs; i++)
1778 freeReg (ssym->regs[i]);
1780 /* if spilt on stack then free up r0 & r1
1781 if they could have been assigned to as gprs */
1782 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1785 spillLRWithPtrReg (ssym);
1788 /* if this was a block level spil then insert push & pop
1789 at the start & end of block respectively */
1790 if (ssym->blockSpil)
1792 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1793 /* add push to the start of the block */
1794 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1795 ebp->sch->next : ebp->sch));
1796 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1797 /* add pop to the end of the block */
1798 addiCodeToeBBlock (ebp, nic, NULL);
1801 /* if spilt because not used in the remainder of the
1802 block then add a push before this instruction and
1803 a pop at the end of the block */
1804 if (ssym->remainSpil)
1807 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1808 /* add push just before this instruction */
1809 addiCodeToeBBlock (ebp, nic, ic);
1811 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1812 /* add pop to the end of the block */
1813 addiCodeToeBBlock (ebp, nic, NULL);
1822 /*-----------------------------------------------------------------*/
1823 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1824 /*-----------------------------------------------------------------*/
1826 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1831 debugLog ("%s\n", __FUNCTION__);
1833 /* try for a ptr type */
1834 if ((reg = allocReg (REG_PTR)))
1837 /* try for gpr type */
1838 if ((reg = allocReg (REG_GPR)))
1841 /* we have to spil */
1842 if (!spilSomething (ic, ebp, sym))
1845 /* make sure partially assigned registers aren't reused */
1846 for (j=0; j<=sym->nRegs; j++)
1848 sym->regs[j]->isFree = 0;
1850 /* this looks like an infinite loop but
1851 in really selectSpil will abort */
1855 /*-----------------------------------------------------------------*/
1856 /* getRegGpr - will try for GPR if not spil */
1857 /*-----------------------------------------------------------------*/
1859 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1864 debugLog ("%s\n", __FUNCTION__);
1866 /* try for gpr type */
1867 if ((reg = allocReg (REG_GPR)))
1870 if (!pic14_ptrRegReq)
1871 if ((reg = allocReg (REG_PTR)))
1874 /* we have to spil */
1875 if (!spilSomething (ic, ebp, sym))
1878 /* make sure partially assigned registers aren't reused */
1879 for (j=0; j<=sym->nRegs; j++)
1881 sym->regs[j]->isFree = 0;
1883 /* this looks like an infinite loop but
1884 in really selectSpil will abort */
1888 /*-----------------------------------------------------------------*/
1889 /* symHasReg - symbol has a given register */
1890 /*-----------------------------------------------------------------*/
1892 symHasReg (symbol * sym, regs * reg)
1896 debugLog ("%s\n", __FUNCTION__);
1897 for (i = 0; i < sym->nRegs; i++)
1898 if (sym->regs[i] == reg)
1904 /*-----------------------------------------------------------------*/
1905 /* deassignLRs - check the live to and if they have registers & are */
1906 /* not spilt then free up the registers */
1907 /*-----------------------------------------------------------------*/
1909 deassignLRs (iCode * ic, eBBlock * ebp)
1915 debugLog ("%s\n", __FUNCTION__);
1916 for (sym = hTabFirstItem (liveRanges, &k); sym;
1917 sym = hTabNextItem (liveRanges, &k))
1920 symbol *psym = NULL;
1921 /* if it does not end here */
1922 if (sym->liveTo > ic->seq)
1925 /* Prevent the result from being assigned the same registers as (one)
1926 * operand as many genXXX-functions fail otherwise.
1927 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1928 * are known to fail. */
1929 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1933 case '=': /* assignment */
1934 case BITWISEAND: /* bitwise AND */
1935 case '|': /* bitwise OR */
1936 case '^': /* bitwise XOR */
1937 case '~': /* bitwise negate */
1938 case RLC: /* rotate through carry */
1941 case '+': /* addition */
1942 case '-': /* subtraction */
1943 /* go ahead, these are safe to use with
1944 * non-disjoint register sets */
1948 /* do not release operand registers */
1949 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1954 /* if it was spilt on stack then we can
1955 mark the stack spil location as free */
1960 sym->usl.spillLoc->isFree = 1;
1966 if (!bitVectBitValue (_G.regAssigned, sym->key))
1968 /* special case check if this is an IFX &
1969 the privious one was a pop and the
1970 previous one was not spilt then keep track
1972 if (ic->op == IFX && ic->prev &&
1973 ic->prev->op == IPOP &&
1974 !ic->prev->parmPush &&
1975 IS_SYMOP(IC_LEFT (ic->prev)) &&
1976 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1977 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1983 bitVectUnSetBit (_G.regAssigned, sym->key);
1985 /* if the result of this one needs registers
1986 and does not have it then assign it right
1988 if (IC_RESULT (ic) &&
1989 !(SKIP_IC2 (ic) || /* not a special icode */
1990 ic->op == JUMPTABLE ||
1995 POINTER_SET (ic)) &&
1996 IS_SYMOP (IC_RESULT (ic)) &&
1997 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1998 result->liveTo > ic->seq && /* and will live beyond this */
1999 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2000 result->liveFrom == ic->seq && /* does not start before here */
2001 result->regType == sym->regType && /* same register types */
2002 result->regType == sym->regType && /* same register types */
2003 result->nRegs && /* which needs registers */
2004 !result->isspilt && /* and does not already have them */
2006 !bitVectBitValue (_G.regAssigned, result->key) &&
2007 /* the number of free regs + number of regs in this LR
2008 can accomodate the what result Needs */
2009 ((nfreeRegsType (result->regType) +
2010 sym->nRegs) >= result->nRegs)
2014 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2016 result->regs[i] = sym->regs[i];
2018 result->regs[i] = getRegGpr (ic, ebp, result);
2020 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2024 /* free the remaining */
2025 for (; i < sym->nRegs; i++)
2029 if (!symHasReg (psym, sym->regs[i]))
2030 freeReg (sym->regs[i]);
2033 freeReg (sym->regs[i]);
2040 /*-----------------------------------------------------------------*/
2041 /* reassignLR - reassign this to registers */
2042 /*-----------------------------------------------------------------*/
2044 reassignLR (operand * op)
2046 symbol *sym = OP_SYMBOL (op);
2049 debugLog ("%s\n", __FUNCTION__);
2050 /* not spilt any more */
2051 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2052 bitVectUnSetBit (_G.spiltSet, sym->key);
2054 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2058 for (i = 0; i < sym->nRegs; i++)
2059 sym->regs[i]->isFree = 0;
2062 /*-----------------------------------------------------------------*/
2063 /* willCauseSpill - determines if allocating will cause a spill */
2064 /*-----------------------------------------------------------------*/
2066 willCauseSpill (int nr, int rt)
2068 debugLog ("%s\n", __FUNCTION__);
2069 /* first check if there are any avlb registers
2070 of te type required */
2073 /* special case for pointer type
2074 if pointer type not avlb then
2075 check for type gpr */
2076 if (nFreeRegs (rt) >= nr)
2078 if (nFreeRegs (REG_GPR) >= nr)
2083 if (pic14_ptrRegReq)
2085 if (nFreeRegs (rt) >= nr)
2090 if (nFreeRegs (REG_PTR) +
2091 nFreeRegs (REG_GPR) >= nr)
2096 debugLog (" ... yep it will (cause a spill)\n");
2097 /* it will cause a spil */
2101 /*-----------------------------------------------------------------*/
2102 /* positionRegs - the allocator can allocate same registers to res- */
2103 /* ult and operand, if this happens make sure they are in the same */
2104 /* position as the operand otherwise chaos results */
2105 /*-----------------------------------------------------------------*/
2107 positionRegs (symbol * result, symbol * opsym, int lineno)
2109 int count = min (result->nRegs, opsym->nRegs);
2110 int i, j = 0, shared = 0;
2112 debugLog ("%s\n", __FUNCTION__);
2113 /* if the result has been spilt then cannot share */
2118 /* first make sure that they actually share */
2119 for (i = 0; i < count; i++)
2121 for (j = 0; j < count; j++)
2123 if (result->regs[i] == opsym->regs[j] && i != j)
2133 regs *tmp = result->regs[i];
2134 result->regs[i] = result->regs[j];
2135 result->regs[j] = tmp;
2140 /*------------------------------------------------------------------*/
2141 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2142 /* it should either have registers or have beed spilled. Otherwise, */
2143 /* there was an uninitialized variable, so just spill this to get */
2144 /* the operand in a valid state. */
2145 /*------------------------------------------------------------------*/
2147 verifyRegsAssigned (operand *op, iCode * ic)
2152 if (!IS_ITEMP (op)) return;
2154 sym = OP_SYMBOL (op);
2155 if (sym->isspilt) return;
2156 if (!sym->nRegs) return;
2157 if (sym->regs[0]) return;
2159 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2160 sym->prereqv ? sym->prereqv->name : sym->name);
2165 /*-----------------------------------------------------------------*/
2166 /* serialRegAssign - serially allocate registers to the variables */
2167 /*-----------------------------------------------------------------*/
2169 serialRegAssign (eBBlock ** ebbs, int count)
2173 debugLog ("%s\n", __FUNCTION__);
2174 /* for all blocks */
2175 for (i = 0; i < count; i++)
2180 if (ebbs[i]->noPath &&
2181 (ebbs[i]->entryLabel != entryLabel &&
2182 ebbs[i]->entryLabel != returnLabel))
2185 /* of all instructions do */
2186 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2188 debugLog (" op: %s\n", decodeOp (ic->op));
2190 /* if this is an ipop that means some live
2191 range will have to be assigned again */
2193 reassignLR (IC_LEFT (ic));
2195 /* if result is present && is a true symbol */
2196 if (IC_RESULT (ic) && ic->op != IFX &&
2197 IS_TRUE_SYMOP (IC_RESULT (ic)))
2198 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2200 /* take away registers from live
2201 ranges that end at this instruction */
2202 deassignLRs (ic, ebbs[i]);
2204 /* some don't need registers */
2205 if (SKIP_IC2 (ic) ||
2206 ic->op == JUMPTABLE ||
2210 (IC_RESULT (ic) && POINTER_SET (ic)))
2213 /* now we need to allocate registers
2214 only for the result */
2215 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2217 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2223 /* Make sure any spill location is definately allocated */
2224 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2225 !sym->usl.spillLoc->allocreq)
2227 sym->usl.spillLoc->allocreq++;
2230 /* if it does not need or is spilt
2231 or is already assigned to registers
2232 or will not live beyond this instructions */
2235 bitVectBitValue (_G.regAssigned, sym->key) ||
2236 sym->liveTo <= ic->seq)
2239 /* if some liverange has been spilt at the block level
2240 and this one live beyond this block then spil this
2242 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2247 /* if trying to allocate this will cause
2248 a spill and there is nothing to spill
2249 or this one is rematerializable then
2251 willCS = willCauseSpill (sym->nRegs, sym->regType);
2252 spillable = computeSpillable (ic);
2254 (willCS && bitVectIsZero (spillable)))
2262 /* If the live range preceeds the point of definition
2263 then ideally we must take into account registers that
2264 have been allocated after sym->liveFrom but freed
2265 before ic->seq. This is complicated, so spill this
2266 symbol instead and let fillGaps handle the allocation. */
2267 if (sym->liveFrom < ic->seq)
2273 /* if it has a spillocation & is used less than
2274 all other live ranges then spill this */
2276 if (sym->usl.spillLoc) {
2277 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2278 allLRs, ebbs[i], ic));
2279 if (leastUsed && leastUsed->used > sym->used) {
2284 /* if none of the liveRanges have a spillLocation then better
2285 to spill this one than anything else already assigned to registers */
2286 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2287 /* if this is local to this block then we might find a block spil */
2288 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2296 if (ic->op == RECEIVE)
2297 debugLog ("When I get clever, I'll optimize the receive logic\n");
2299 /* if we need ptr regs for the right side
2301 if (POINTER_GET (ic)
2302 && IS_SYMOP(IC_LEFT(ic))
2303 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2304 <= (unsigned) PTRSIZE)
2309 /* else we assign registers to it */
2310 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2312 debugLog (" %d - \n", __LINE__);
2314 bitVectDebugOn(_G.regAssigned, debugF);
2315 for (j = 0; j < sym->nRegs; j++)
2317 if (sym->regType == REG_PTR)
2318 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2320 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2322 /* if the allocation failed which means
2323 this was spilt then break */
2327 debugLog (" %d - \n", __LINE__);
2329 /* if it shares registers with operands make sure
2330 that they are in the same position */
2331 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2332 IS_SYMOP(IC_RESULT(ic)) &&
2333 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2334 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2335 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2336 /* do the same for the right operand */
2337 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2338 IS_SYMOP(IC_RESULT(ic)) &&
2339 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2340 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2341 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2343 debugLog (" %d - \n", __LINE__);
2346 debugLog (" %d - \n", __LINE__);
2355 /* Check for and fix any problems with uninitialized operands */
2356 for (i = 0; i < count; i++)
2360 if (ebbs[i]->noPath &&
2361 (ebbs[i]->entryLabel != entryLabel &&
2362 ebbs[i]->entryLabel != returnLabel))
2365 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2372 verifyRegsAssigned (IC_COND (ic), ic);
2376 if (ic->op == JUMPTABLE)
2378 verifyRegsAssigned (IC_JTCOND (ic), ic);
2382 verifyRegsAssigned (IC_RESULT (ic), ic);
2383 verifyRegsAssigned (IC_LEFT (ic), ic);
2384 verifyRegsAssigned (IC_RIGHT (ic), ic);
2390 /*-----------------------------------------------------------------*/
2391 /* rUmaskForOp :- returns register mask for an operand */
2392 /*-----------------------------------------------------------------*/
2394 rUmaskForOp (operand * op)
2400 debugLog ("%s\n", __FUNCTION__);
2401 /* only temporaries are assigned registers */
2405 sym = OP_SYMBOL (op);
2407 /* if spilt or no registers assigned to it
2409 if (sym->isspilt || !sym->nRegs)
2412 rumask = newBitVect (pic14_nRegs);
2414 for (j = 0; j < sym->nRegs; j++)
2416 rumask = bitVectSetBit (rumask,
2417 sym->regs[j]->rIdx);
2423 /*-----------------------------------------------------------------*/
2424 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2425 /*-----------------------------------------------------------------*/
2427 regsUsedIniCode (iCode * ic)
2429 bitVect *rmask = newBitVect (pic14_nRegs);
2431 debugLog ("%s\n", __FUNCTION__);
2432 /* do the special cases first */
2435 rmask = bitVectUnion (rmask,
2436 rUmaskForOp (IC_COND (ic)));
2440 /* for the jumptable */
2441 if (ic->op == JUMPTABLE)
2443 rmask = bitVectUnion (rmask,
2444 rUmaskForOp (IC_JTCOND (ic)));
2449 /* of all other cases */
2451 rmask = bitVectUnion (rmask,
2452 rUmaskForOp (IC_LEFT (ic)));
2456 rmask = bitVectUnion (rmask,
2457 rUmaskForOp (IC_RIGHT (ic)));
2460 rmask = bitVectUnion (rmask,
2461 rUmaskForOp (IC_RESULT (ic)));
2467 /*-----------------------------------------------------------------*/
2468 /* createRegMask - for each instruction will determine the regsUsed */
2469 /*-----------------------------------------------------------------*/
2471 createRegMask (eBBlock ** ebbs, int count)
2475 debugLog ("%s\n", __FUNCTION__);
2476 /* for all blocks */
2477 for (i = 0; i < count; i++)
2481 if (ebbs[i]->noPath &&
2482 (ebbs[i]->entryLabel != entryLabel &&
2483 ebbs[i]->entryLabel != returnLabel))
2486 /* for all instructions */
2487 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2492 if (SKIP_IC2 (ic) || !ic->rlive)
2495 /* first mark the registers used in this
2497 ic->rUsed = regsUsedIniCode (ic);
2498 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2500 /* now create the register mask for those
2501 registers that are in use : this is a
2502 super set of ic->rUsed */
2503 ic->rMask = newBitVect (pic14_nRegs + 1);
2505 /* for all live Ranges alive at this point */
2506 for (j = 1; j < ic->rlive->size; j++)
2511 /* if not alive then continue */
2512 if (!bitVectBitValue (ic->rlive, j))
2515 /* find the live range we are interested in */
2516 if (!(sym = hTabItemWithKey (liveRanges, j)))
2518 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2519 "createRegMask cannot find live range");
2523 /* if no register assigned to it */
2524 if (!sym->nRegs || sym->isspilt)
2527 /* for all the registers allocated to it */
2528 for (k = 0; k < sym->nRegs; k++)
2531 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2537 /* This was the active version */
2538 /*-----------------------------------------------------------------*/
2539 /* rematStr - returns the rematerialized string for a remat var */
2540 /*-----------------------------------------------------------------*/
2542 rematStr (symbol * sym)
2545 iCode *ic = sym->rematiCode;
2546 symbol *psym = NULL;
2548 debugLog ("%s\n", __FUNCTION__);
2550 //printf ("%s\n", s);
2552 /* if plus or minus print the right hand side */
2554 if (ic->op == '+' || ic->op == '-') {
2556 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2558 sprintf (s, "(%s %c 0x%04x)",
2559 OP_SYMBOL (IC_LEFT (ric))->rname,
2561 (int) operandLitValue (IC_RIGHT (ic)));
2564 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2566 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2567 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2572 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2573 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2575 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2581 /* deprecated version */
2582 /*-----------------------------------------------------------------*/
2583 /* rematStr - returns the rematerialized string for a remat var */
2584 /*-----------------------------------------------------------------*/
2586 rematStr (symbol * sym)
2589 iCode *ic = sym->rematiCode;
2591 debugLog ("%s\n", __FUNCTION__);
2596 /* if plus or minus print the right hand side */
2598 if (ic->op == '+' || ic->op == '-') {
2599 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2602 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2606 if (ic->op == '+' || ic->op == '-')
2608 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2609 sprintf (s, "(%s %c 0x%04x)",
2610 OP_SYMBOL (IC_LEFT (ric))->rname,
2612 (int) operandLitValue (IC_RIGHT (ic)));
2615 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2617 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2621 /* we reached the end */
2622 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2626 printf ("%s\n", buffer);
2631 /*-----------------------------------------------------------------*/
2632 /* regTypeNum - computes the type & number of registers required */
2633 /*-----------------------------------------------------------------*/
2641 debugLog ("%s\n", __FUNCTION__);
2642 /* for each live range do */
2643 for (sym = hTabFirstItem (liveRanges, &k); sym;
2644 sym = hTabNextItem (liveRanges, &k)) {
2646 debugLog (" %d - %s\n", __LINE__, sym->rname);
2648 /* if used zero times then no registers needed */
2649 if ((sym->liveTo - sym->liveFrom) == 0)
2653 /* if the live range is a temporary */
2656 debugLog (" %d - itemp register\n", __LINE__);
2658 /* if the type is marked as a conditional */
2659 if (sym->regType == REG_CND)
2662 /* if used in return only then we don't
2665 if (IS_AGGREGATE (sym->type) || sym->isptr)
2666 sym->type = aggrToPtr (sym->type, FALSE);
2667 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2673 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2674 // sym->type = aggrToPtr (sym->type, FALSE);
2675 debugLog (" %d - used as a return\n", __LINE__);
2680 /* if the symbol has only one definition &
2681 that definition is a get_pointer and the
2682 pointer we are getting is rematerializable and
2686 if (bitVectnBitsOn (sym->defs) == 1 &&
2687 (ic = hTabItemWithKey (iCodehTab,
2688 bitVectFirstBit (sym->defs))) &&
2690 !IS_BITVAR (sym->etype) &&
2691 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2693 if (ptrPseudoSymSafe (sym, ic)) {
2697 debugLog (" %d - \n", __LINE__);
2699 /* create a pseudo symbol & force a spil */
2700 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2701 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2702 psym->type = sym->type;
2703 psym->etype = sym->etype;
2704 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2705 strcpy (psym->rname, psym->name);
2707 sym->usl.spillLoc = psym;
2711 /* if in data space or idata space then try to
2712 allocate pointer register */
2717 /* if not then we require registers */
2718 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2719 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2720 getSize (sym->type));
2723 if(IS_PTR_CONST (sym->type)) {
2724 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2728 if (sym->nRegs > 4) {
2729 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2730 printTypeChain (sym->type, stderr);
2731 fprintf (stderr, "\n");
2734 /* determine the type of register required */
2735 if (sym->nRegs == 1 &&
2736 IS_PTR (sym->type) &&
2738 sym->regType = REG_PTR;
2740 sym->regType = REG_GPR;
2743 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2747 /* for the first run we don't provide */
2748 /* registers for true symbols we will */
2749 /* see how things go */
2754 DEFSETFUNC (markRegFree)
2756 ((regs *)item)->isFree = 1;
2761 DEFSETFUNC (deallocReg)
2763 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2764 ((regs *)item)->isFree = 1;
2765 ((regs *)item)->wasUsed = 0;
2769 /*-----------------------------------------------------------------*/
2770 /* freeAllRegs - mark all registers as free */
2771 /*-----------------------------------------------------------------*/
2773 pic14_freeAllRegs ()
2777 debugLog ("%s\n", __FUNCTION__);
2779 applyToSet(dynAllocRegs,markRegFree);
2780 applyToSet(dynStackRegs,markRegFree);
2783 for (i = 0; i < pic14_nRegs; i++)
2784 regspic14[i].isFree = 1;
2788 /*-----------------------------------------------------------------*/
2789 /*-----------------------------------------------------------------*/
2791 pic14_deallocateAllRegs ()
2795 debugLog ("%s\n", __FUNCTION__);
2797 applyToSet(dynAllocRegs,deallocReg);
2800 for (i = 0; i < pic14_nRegs; i++) {
2801 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2802 regspic14[i].isFree = 1;
2803 regspic14[i].wasUsed = 0;
2810 /*-----------------------------------------------------------------*/
2811 /* deallocStackSpil - this will set the stack pointer back */
2812 /*-----------------------------------------------------------------*/
2814 DEFSETFUNC (deallocStackSpil)
2818 debugLog ("%s\n", __FUNCTION__);
2823 /*-----------------------------------------------------------------*/
2824 /* farSpacePackable - returns the packable icode for far variables */
2825 /*-----------------------------------------------------------------*/
2827 farSpacePackable (iCode * ic)
2831 debugLog ("%s\n", __FUNCTION__);
2832 /* go thru till we find a definition for the
2833 symbol on the right */
2834 for (dic = ic->prev; dic; dic = dic->prev)
2837 /* if the definition is a call then no */
2838 if ((dic->op == CALL || dic->op == PCALL) &&
2839 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2844 /* if shift by unknown amount then not */
2845 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2846 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2849 /* if pointer get and size > 1 */
2850 if (POINTER_GET (dic) &&
2851 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2854 if (POINTER_SET (dic) &&
2855 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2858 /* if any three is a true symbol in far space */
2859 if (IC_RESULT (dic) &&
2860 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2861 isOperandInFarSpace (IC_RESULT (dic)))
2864 if (IC_RIGHT (dic) &&
2865 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2866 isOperandInFarSpace (IC_RIGHT (dic)) &&
2867 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2870 if (IC_LEFT (dic) &&
2871 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2872 isOperandInFarSpace (IC_LEFT (dic)) &&
2873 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2876 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2878 if ((dic->op == LEFT_OP ||
2879 dic->op == RIGHT_OP ||
2881 IS_OP_LITERAL (IC_RIGHT (dic)))
2891 /*-----------------------------------------------------------------*/
2892 /* packRegsForAssign - register reduction for assignment */
2893 /*-----------------------------------------------------------------*/
2895 packRegsForAssign (iCode * ic, eBBlock * ebp)
2900 debugLog ("%s\n", __FUNCTION__);
2902 debugAopGet (" result:", IC_RESULT (ic));
2903 debugAopGet (" left:", IC_LEFT (ic));
2904 debugAopGet (" right:", IC_RIGHT (ic));
2906 /* if this is at an absolute address, then get the address. */
2907 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2908 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2909 debugLog (" %d - found config word declaration\n", __LINE__);
2910 if(IS_VALOP(IC_RIGHT(ic))) {
2911 debugLog (" setting config word to %x\n",
2912 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2913 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2914 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2917 /* remove the assignment from the iCode chain. */
2919 remiCodeFromeBBlock (ebp, ic);
2920 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2921 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2928 if (!IS_ITEMP (IC_RESULT (ic))) {
2929 allocDirReg(IC_RESULT (ic));
2930 debugLog (" %d - result is not temp\n", __LINE__);
2933 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2934 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2935 allocDirReg(IC_LEFT (ic));
2939 if (!IS_ITEMP (IC_RIGHT (ic))) {
2940 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2942 /* only pack if this is not a function pointer */
2943 if (!IS_REF (IC_RIGHT (ic)))
2944 allocDirReg(IC_RIGHT (ic));
2948 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2949 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2951 debugLog (" %d - not packing - right side fails \n", __LINE__);
2955 /* if the true symbol is defined in far space or on stack
2956 then we should not since this will increase register pressure */
2957 if (isOperandInFarSpace (IC_RESULT (ic)))
2959 if ((dic = farSpacePackable (ic)))
2965 /* find the definition of iTempNN scanning backwards if we find a
2966 a use of the true symbol before we find the definition then
2968 for (dic = ic->prev; dic; dic = dic->prev)
2971 /* if there is a function call and this is
2972 a parameter & not my parameter then don't pack it */
2973 if ((dic->op == CALL || dic->op == PCALL) &&
2974 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2975 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2977 debugLog (" %d - \n", __LINE__);
2985 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2986 IS_OP_VOLATILE (IC_RESULT (dic)))
2988 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2993 if (IS_SYMOP (IC_RESULT (dic)) &&
2994 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2996 /* A previous result was assigned to the same register - we'll our definition */
2997 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2998 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2999 if (POINTER_SET (dic))
3005 if (IS_SYMOP (IC_RIGHT (dic)) &&
3006 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3007 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3009 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3014 if (IS_SYMOP (IC_LEFT (dic)) &&
3015 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3016 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3018 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3023 if (POINTER_SET (dic) &&
3024 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3026 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3034 return 0; /* did not find */
3036 /* if assignment then check that right is not a bit */
3037 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
3039 sym_link *etype = operandType (IC_RESULT (dic));
3040 if (IS_BITFIELD (etype))
3042 /* if result is a bit too then it's ok */
3043 etype = operandType (IC_RESULT (ic));
3044 if (!IS_BITFIELD (etype))
3049 /* if the result is on stack or iaccess then it must be
3050 the same at least one of the operands */
3051 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3052 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3055 /* the operation has only one symbol
3056 operator then we can pack */
3057 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3058 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3061 if (!((IC_LEFT (dic) &&
3062 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3064 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3068 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3069 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3070 /* found the definition */
3071 /* replace the result with the result of */
3072 /* this assignment and remove this assignment */
3073 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3074 IC_RESULT (dic) = IC_RESULT (ic);
3076 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3078 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3080 /* delete from liverange table also
3081 delete from all the points inbetween and the new
3083 for (sic = dic; sic != ic; sic = sic->next)
3085 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3086 if (IS_ITEMP (IC_RESULT (dic)))
3087 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3090 remiCodeFromeBBlock (ebp, ic);
3091 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3092 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3093 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3099 /*-----------------------------------------------------------------*/
3100 /* findAssignToSym : scanning backwards looks for first assig found */
3101 /*-----------------------------------------------------------------*/
3103 findAssignToSym (operand * op, iCode * ic)
3107 debugLog ("%s\n", __FUNCTION__);
3108 for (dic = ic->prev; dic; dic = dic->prev)
3111 /* if definition by assignment */
3112 if (dic->op == '=' &&
3113 !POINTER_SET (dic) &&
3114 IC_RESULT (dic)->key == op->key
3115 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3119 /* we are interested only if defined in far space */
3120 /* or in stack space in case of + & - */
3122 /* if assigned to a non-symbol then return
3124 if (!IS_SYMOP (IC_RIGHT (dic)))
3127 /* if the symbol is in far space then
3129 if (isOperandInFarSpace (IC_RIGHT (dic)))
3132 /* for + & - operations make sure that
3133 if it is on the stack it is the same
3134 as one of the three operands */
3135 if ((ic->op == '+' || ic->op == '-') &&
3136 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3139 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3140 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3141 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3149 /* if we find an usage then we cannot delete it */
3150 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3153 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3156 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3160 /* now make sure that the right side of dic
3161 is not defined between ic & dic */
3164 iCode *sic = dic->next;
3166 for (; sic != ic; sic = sic->next)
3167 if (IC_RESULT (sic) &&
3168 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3177 /*-----------------------------------------------------------------*/
3178 /* packRegsForSupport :- reduce some registers for support calls */
3179 /*-----------------------------------------------------------------*/
3181 packRegsForSupport (iCode * ic, eBBlock * ebp)
3185 debugLog ("%s\n", __FUNCTION__);
3186 /* for the left & right operand :- look to see if the
3187 left was assigned a true symbol in far space in that
3188 case replace them */
3189 if (IS_ITEMP (IC_LEFT (ic)) &&
3190 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3192 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3198 debugAopGet ("removing left:", IC_LEFT (ic));
3200 /* found it we need to remove it from the
3202 for (sic = dic; sic != ic; sic = sic->next)
3203 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3205 IC_LEFT (ic)->operand.symOperand =
3206 IC_RIGHT (dic)->operand.symOperand;
3207 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3208 remiCodeFromeBBlock (ebp, dic);
3209 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3210 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3214 /* do the same for the right operand */
3217 IS_ITEMP (IC_RIGHT (ic)) &&
3218 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3220 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3226 /* if this is a subtraction & the result
3227 is a true symbol in far space then don't pack */
3228 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3230 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3231 if (IN_FARSPACE (SPEC_OCLS (etype)))
3235 debugAopGet ("removing right:", IC_RIGHT (ic));
3237 /* found it we need to remove it from the
3239 for (sic = dic; sic != ic; sic = sic->next)
3240 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3242 IC_RIGHT (ic)->operand.symOperand =
3243 IC_RIGHT (dic)->operand.symOperand;
3244 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3246 remiCodeFromeBBlock (ebp, dic);
3247 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3248 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3255 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3258 /*-----------------------------------------------------------------*/
3259 /* packRegsForOneuse : - will reduce some registers for single Use */
3260 /*-----------------------------------------------------------------*/
3262 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3267 debugLog ("%s\n", __FUNCTION__);
3268 /* if returning a literal then do nothing */
3272 /* only upto 2 bytes since we cannot predict
3273 the usage of b, & acc */
3274 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3279 /* this routine will mark the a symbol as used in one
3280 instruction use only && if the definition is local
3281 (ie. within the basic block) && has only one definition &&
3282 that definition is either a return value from a
3283 function or does not contain any variables in
3285 uses = bitVectCopy (OP_USES (op));
3286 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3287 if (!bitVectIsZero (uses)) /* has other uses */
3290 /* if it has only one defintion */
3291 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3292 return NULL; /* has more than one definition */
3294 /* get that definition */
3296 hTabItemWithKey (iCodehTab,
3297 bitVectFirstBit (OP_DEFS (op)))))
3300 /* found the definition now check if it is local */
3301 if (dic->seq < ebp->fSeq ||
3302 dic->seq > ebp->lSeq)
3303 return NULL; /* non-local */
3305 /* now check if it is the return from
3307 if (dic->op == CALL || dic->op == PCALL)
3309 if (ic->op != SEND && ic->op != RETURN &&
3310 !POINTER_SET(ic) && !POINTER_GET(ic))
3312 OP_SYMBOL (op)->ruonly = 1;
3319 /* otherwise check that the definition does
3320 not contain any symbols in far space */
3321 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3322 isOperandInFarSpace (IC_RIGHT (dic)) ||
3323 IS_OP_RUONLY (IC_LEFT (ic)) ||
3324 IS_OP_RUONLY (IC_RIGHT (ic)))
3329 /* if pointer set then make sure the pointer
3331 if (POINTER_SET (dic) &&
3332 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3335 if (POINTER_GET (dic) &&
3336 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3341 /* also make sure the intervenening instructions
3342 don't have any thing in far space */
3343 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3346 /* if there is an intervening function call then no */
3347 if (dic->op == CALL || dic->op == PCALL)
3349 /* if pointer set then make sure the pointer
3351 if (POINTER_SET (dic) &&
3352 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3355 if (POINTER_GET (dic) &&
3356 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3359 /* if address of & the result is remat then okay */
3360 if (dic->op == ADDRESS_OF &&
3361 OP_SYMBOL (IC_RESULT (dic))->remat)
3364 /* if operand has size of three or more & this
3365 operation is a '*','/' or '%' then 'b' may
3367 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3368 getSize (operandType (op)) >= 3)
3371 /* if left or right or result is in far space */
3372 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3373 isOperandInFarSpace (IC_RIGHT (dic)) ||
3374 isOperandInFarSpace (IC_RESULT (dic)) ||
3375 IS_OP_RUONLY (IC_LEFT (dic)) ||
3376 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3377 IS_OP_RUONLY (IC_RESULT (dic)))
3383 OP_SYMBOL (op)->ruonly = 1;
3388 /*-----------------------------------------------------------------*/
3389 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3390 /*-----------------------------------------------------------------*/
3392 isBitwiseOptimizable (iCode * ic)
3394 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3395 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3397 debugLog ("%s\n", __FUNCTION__);
3398 /* bitwise operations are considered optimizable
3399 under the following conditions (Jean-Louis VERN)
3411 if (IS_LITERAL (rtype) ||
3412 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3418 /*-----------------------------------------------------------------*/
3419 /* packRegsForAccUse - pack registers for acc use */
3420 /*-----------------------------------------------------------------*/
3422 packRegsForAccUse (iCode * ic)
3426 debugLog ("%s\n", __FUNCTION__);
3428 /* result too large for WREG? */
3429 if (getSize (operandType (IC_RESULT (ic))) > 1)
3432 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3433 * is never used as an operand to an instruction that
3434 * cannot have WREG as an operand (e.g. BTFSx cannot
3435 * operate on WREG...
3436 * For now, store all results into proper registers. */
3440 /* if this is an aggregate, e.g. a one byte char array */
3441 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3444 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3446 /* if + or - then it has to be one byte result */
3447 if ((ic->op == '+' || ic->op == '-')
3448 && getSize (operandType (IC_RESULT (ic))) > 1)
3451 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3452 /* if shift operation make sure right side is not a literal */
3453 if (ic->op == RIGHT_OP &&
3454 (isOperandLiteral (IC_RIGHT (ic)) ||
3455 getSize (operandType (IC_RESULT (ic))) > 1))
3458 if (ic->op == LEFT_OP &&
3459 (isOperandLiteral (IC_RIGHT (ic)) ||
3460 getSize (operandType (IC_RESULT (ic))) > 1))
3463 if (IS_BITWISE_OP (ic) &&
3464 getSize (operandType (IC_RESULT (ic))) > 1)
3468 /* has only one definition */
3469 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3472 /* has only one use */
3473 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3476 /* and the usage immediately follows this iCode */
3477 if (!(uic = hTabItemWithKey (iCodehTab,
3478 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3481 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3482 if (ic->next != uic)
3485 /* if it is a conditional branch then we definitely can */
3489 if (uic->op == JUMPTABLE)
3492 /* if the usage is not is an assignment
3493 or an arithmetic / bitwise / shift operation then not */
3494 if (POINTER_SET (uic) &&
3495 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3498 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3499 if (uic->op != '=' &&
3500 !IS_ARITHMETIC_OP (uic) &&
3501 !IS_BITWISE_OP (uic) &&
3502 uic->op != LEFT_OP &&
3503 uic->op != RIGHT_OP)
3506 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3507 /* if used in ^ operation then make sure right is not a
3509 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3512 /* if shift operation make sure right side is not a literal */
3513 if (uic->op == RIGHT_OP &&
3514 (isOperandLiteral (IC_RIGHT (uic)) ||
3515 getSize (operandType (IC_RESULT (uic))) > 1))
3518 if (uic->op == LEFT_OP &&
3519 (isOperandLiteral (IC_RIGHT (uic)) ||
3520 getSize (operandType (IC_RESULT (uic))) > 1))
3523 /* make sure that the result of this icode is not on the
3524 stack, since acc is used to compute stack offset */
3525 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3526 OP_SYMBOL (IC_RESULT (uic))->onStack)
3529 /* if either one of them in far space then we cannot */
3530 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3531 isOperandInFarSpace (IC_LEFT (uic))) ||
3532 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3533 isOperandInFarSpace (IC_RIGHT (uic))))
3536 /* if the usage has only one operand then we can */
3537 if (IC_LEFT (uic) == NULL ||
3538 IC_RIGHT (uic) == NULL)
3541 /* make sure this is on the left side if not
3542 a '+' since '+' is commutative */
3543 if (ic->op != '+' &&
3544 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3547 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3548 /* if one of them is a literal then we can */
3549 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3550 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3551 (getSize (operandType (IC_RESULT (uic))) <= 1))
3553 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3557 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3558 /* if the other one is not on stack then we can */
3559 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3560 (IS_ITEMP (IC_RIGHT (uic)) ||
3561 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3562 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3565 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3566 (IS_ITEMP (IC_LEFT (uic)) ||
3567 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3568 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3574 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3575 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3579 /*-----------------------------------------------------------------*/
3580 /* packForPush - hueristics to reduce iCode for pushing */
3581 /*-----------------------------------------------------------------*/
3583 packForReceive (iCode * ic, eBBlock * ebp)
3587 debugLog ("%s\n", __FUNCTION__);
3588 debugAopGet (" result:", IC_RESULT (ic));
3589 debugAopGet (" left:", IC_LEFT (ic));
3590 debugAopGet (" right:", IC_RIGHT (ic));
3595 for (dic = ic->next; dic; dic = dic->next)
3600 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3601 debugLog (" used on left\n");
3602 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3603 debugLog (" used on right\n");
3604 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3605 debugLog (" used on result\n");
3607 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3608 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3613 debugLog (" hey we can remove this unnecessary assign\n");
3615 /*-----------------------------------------------------------------*/
3616 /* packForPush - hueristics to reduce iCode for pushing */
3617 /*-----------------------------------------------------------------*/
3619 packForPush (iCode * ic, eBBlock * ebp)
3623 debugLog ("%s\n", __FUNCTION__);
3624 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3627 /* must have only definition & one usage */
3628 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3629 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3632 /* find the definition */
3633 if (!(dic = hTabItemWithKey (iCodehTab,
3634 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3637 if (dic->op != '=' || POINTER_SET (dic))
3640 /* we now we know that it has one & only one def & use
3641 and the that the definition is an assignment */
3642 IC_LEFT (ic) = IC_RIGHT (dic);
3644 remiCodeFromeBBlock (ebp, dic);
3645 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3646 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3649 void printSymType(char * str, sym_link *sl)
3651 debugLog (" %s Symbol type: ",str);
3652 printTypeChain( sl, debugF);
3657 /*-----------------------------------------------------------------*/
3658 /* some debug code to print the symbol S_TYPE. Note that
3659 * the function checkSClass in src/SDCCsymt.c dinks with
3660 * the S_TYPE in ways the PIC port doesn't fully like...*/
3661 /*-----------------------------------------------------------------*/
3662 void isData(sym_link *sl)
3672 for ( ; sl; sl=sl->next) {
3674 switch (SPEC_SCLS(sl)) {
3676 case S_DATA: fprintf (of, "data "); break;
3677 case S_XDATA: fprintf (of, "xdata "); break;
3678 case S_SFR: fprintf (of, "sfr "); break;
3679 case S_SBIT: fprintf (of, "sbit "); break;
3680 case S_CODE: fprintf (of, "code "); break;
3681 case S_IDATA: fprintf (of, "idata "); break;
3682 case S_PDATA: fprintf (of, "pdata "); break;
3683 case S_LITERAL: fprintf (of, "literal "); break;
3684 case S_STACK: fprintf (of, "stack "); break;
3685 case S_XSTACK: fprintf (of, "xstack "); break;
3686 case S_BIT: fprintf (of, "bit "); break;
3687 case S_EEPROM: fprintf (of, "eeprom "); break;
3697 /*-----------------------------------------------------------------*/
3698 /* packRegisters - does some transformations to reduce register */
3700 /*-----------------------------------------------------------------*/
3702 packRegisters (eBBlock * ebp)
3707 debugLog ("%s\n", __FUNCTION__);
3713 /* look for assignments of the form */
3714 /* iTempNN = TRueSym (someoperation) SomeOperand */
3716 /* TrueSym := iTempNN:1 */
3717 for (ic = ebp->sch; ic; ic = ic->next)
3720 /* find assignment of the form TrueSym := iTempNN:1 */
3721 if (ic->op == '=' && !POINTER_SET (ic))
3722 change += packRegsForAssign (ic, ebp);
3726 if (POINTER_SET (ic))
3727 debugLog ("pointer is set\n");
3728 debugAopGet (" result:", IC_RESULT (ic));
3729 debugAopGet (" left:", IC_LEFT (ic));
3730 debugAopGet (" right:", IC_RIGHT (ic));
3739 for (ic = ebp->sch; ic; ic = ic->next) {
3741 if(IS_SYMOP ( IC_LEFT(ic))) {
3742 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3744 debugAopGet (" left:", IC_LEFT (ic));
3745 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3746 debugLog (" is a pointer\n");
3748 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3749 debugLog (" is volatile\n");
3753 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3756 if(IS_SYMOP ( IC_RIGHT(ic))) {
3757 debugAopGet (" right:", IC_RIGHT (ic));
3758 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3761 if(IS_SYMOP ( IC_RESULT(ic))) {
3762 debugAopGet (" result:", IC_RESULT (ic));
3763 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3766 if (POINTER_SET (ic))
3767 debugLog (" %d - Pointer set\n", __LINE__);
3770 /* Look for two subsequent iCodes with */
3772 /* _c = iTemp & op; */
3773 /* and replace them by */
3776 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3778 ic->prev->op == '=' &&
3779 IS_ITEMP (IC_LEFT (ic)) &&
3780 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3781 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3783 iCode* ic_prev = ic->prev;
3784 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3786 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3787 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3789 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3790 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3791 prev_result_sym->liveTo == ic->seq)
3793 prev_result_sym->liveTo = ic_prev->seq;
3796 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3798 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3800 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3802 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3803 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3804 remiCodeFromeBBlock (ebp, ic_prev);
3805 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3809 /* if this is an itemp & result of a address of a true sym
3810 then mark this as rematerialisable */
3811 if (ic->op == ADDRESS_OF &&
3812 IS_ITEMP (IC_RESULT (ic)) &&
3813 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3814 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3815 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3818 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3820 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3821 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3822 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3826 /* if straight assignment then carry remat flag if
3827 this is the only definition */
3828 if (ic->op == '=' &&
3829 !POINTER_SET (ic) &&
3830 IS_SYMOP (IC_RIGHT (ic)) &&
3831 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3832 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3834 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3836 OP_SYMBOL (IC_RESULT (ic))->remat =
3837 OP_SYMBOL (IC_RIGHT (ic))->remat;
3838 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3839 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3842 /* if this is a +/- operation with a rematerizable
3843 then mark this as rematerializable as well */
3844 if ((ic->op == '+' || ic->op == '-') &&
3845 (IS_SYMOP (IC_LEFT (ic)) &&
3846 IS_ITEMP (IC_RESULT (ic)) &&
3847 OP_SYMBOL (IC_LEFT (ic))->remat &&
3848 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3849 IS_OP_LITERAL (IC_RIGHT (ic))))
3851 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3853 operandLitValue (IC_RIGHT (ic));
3854 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3855 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3856 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3859 /* mark the pointer usages */
3860 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3862 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3863 debugLog (" marking as a pointer (set) =>");
3864 debugAopGet (" result:", IC_RESULT (ic));
3866 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3868 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3869 debugLog (" marking as a pointer (get) =>");
3870 debugAopGet (" left:", IC_LEFT (ic));
3875 /* if we are using a symbol on the stack
3876 then we should say pic14_ptrRegReq */
3877 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3878 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3879 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3880 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3881 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3882 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3885 if (IS_SYMOP (IC_LEFT (ic)))
3886 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3887 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3888 if (IS_SYMOP (IC_RIGHT (ic)))
3889 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3890 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3891 if (IS_SYMOP (IC_RESULT (ic)))
3892 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3893 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3896 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3900 /* if the condition of an if instruction
3901 is defined in the previous instruction then
3902 mark the itemp as a conditional */
3903 if ((IS_CONDITIONAL (ic) ||
3904 ((ic->op == BITWISEAND ||
3907 isBitwiseOptimizable (ic))) &&
3908 ic->next && ic->next->op == IFX &&
3909 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3910 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3913 debugLog (" %d\n", __LINE__);
3914 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3918 /* reduce for support function calls */
3919 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3920 packRegsForSupport (ic, ebp);
3922 /* if a parameter is passed, it's in W, so we may not
3923 need to place a copy in a register */
3924 if (ic->op == RECEIVE)
3925 packForReceive (ic, ebp);
3927 /* some cases the redundant moves can
3928 can be eliminated for return statements */
3929 if ((ic->op == RETURN || ic->op == SEND) &&
3930 !isOperandInFarSpace (IC_LEFT (ic)) &&
3932 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3934 /* if pointer set & left has a size more than
3935 one and right is not in far space */
3936 if (POINTER_SET (ic) &&
3937 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3938 IS_SYMOP(IC_RESULT(ic)) &&
3939 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3940 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3941 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3943 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3945 /* if pointer get */
3946 if (POINTER_GET (ic) &&
3947 !isOperandInFarSpace (IC_RESULT (ic)) &&
3948 IS_SYMOP(IC_LEFT(ic)) &&
3949 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3950 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3951 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3953 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3956 /* if this is cast for intergral promotion then
3957 check if only use of the definition of the
3958 operand being casted/ if yes then replace
3959 the result of that arithmetic operation with
3960 this result and get rid of the cast */
3961 if (ic->op == CAST) {
3963 sym_link *fromType = operandType (IC_RIGHT (ic));
3964 sym_link *toType = operandType (IC_LEFT (ic));
3966 debugLog (" %d - casting\n", __LINE__);
3968 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3969 getSize (fromType) != getSize (toType)) {
3972 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3975 if (IS_ARITHMETIC_OP (dic)) {
3977 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3978 IC_RESULT (dic) = IC_RESULT (ic);
3979 remiCodeFromeBBlock (ebp, ic);
3980 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3981 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3982 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3986 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3990 /* if the type from and type to are the same
3991 then if this is the only use then packit */
3992 if (compareType (operandType (IC_RIGHT (ic)),
3993 operandType (IC_LEFT (ic))) == 1) {
3995 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3998 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3999 IC_RESULT (dic) = IC_RESULT (ic);
4000 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4001 remiCodeFromeBBlock (ebp, ic);
4002 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4003 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4011 iTempNN := (some variable in farspace) V1
4016 if (ic->op == IPUSH)
4018 packForPush (ic, ebp);
4022 /* pack registers for accumulator use, when the
4023 result of an arithmetic or bit wise operation
4024 has only one use, that use is immediately following
4025 the defintion and the using iCode has only one
4026 operand or has two operands but one is literal &
4027 the result of that operation is not on stack then
4028 we can leave the result of this operation in acc:b
4030 if ((IS_ARITHMETIC_OP (ic)
4032 || IS_BITWISE_OP (ic)
4034 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4037 IS_ITEMP (IC_RESULT (ic)) &&
4038 getSize (operandType (IC_RESULT (ic))) <= 2)
4040 packRegsForAccUse (ic);
4046 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4050 if (!debug || !debugF)
4053 for (i = 0; i < count; i++)
4055 fprintf (debugF, "\n----------------------------------------------------------------\n");
4056 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4057 ebbs[i]->entryLabel->name,
4060 ebbs[i]->isLastInLoop);
4061 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4066 fprintf (debugF, "visited %d : hasFcall = %d\n",
4070 fprintf (debugF, "\ndefines bitVector :");
4071 bitVectDebugOn (ebbs[i]->defSet, debugF);
4072 fprintf (debugF, "\nlocal defines bitVector :");
4073 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4074 fprintf (debugF, "\npointers Set bitvector :");
4075 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4076 fprintf (debugF, "\nin pointers Set bitvector :");
4077 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4078 fprintf (debugF, "\ninDefs Set bitvector :");
4079 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4080 fprintf (debugF, "\noutDefs Set bitvector :");
4081 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4082 fprintf (debugF, "\nusesDefs Set bitvector :");
4083 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4084 fprintf (debugF, "\n----------------------------------------------------------------\n");
4085 printiCChain (ebbs[i]->sch, debugF);
4088 /*-----------------------------------------------------------------*/
4089 /* assignRegisters - assigns registers to each live range as need */
4090 /*-----------------------------------------------------------------*/
4092 pic14_assignRegisters (ebbIndex * ebbi)
4094 eBBlock ** ebbs = ebbi->bbOrder;
4095 int count = ebbi->count;
4099 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4100 debugLog ("ebbs before optimizing:\n");
4101 dumpEbbsToDebug (ebbs, count);
4103 setToNull ((void *) &_G.funcrUsed);
4104 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4107 /* change assignments this will remove some
4108 live ranges reducing some register pressure */
4109 for (i = 0; i < count; i++)
4110 packRegisters (ebbs[i]);
4117 debugLog("dir registers allocated so far:\n");
4118 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4121 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4122 reg = hTabNextItem(dynDirectRegNames, &hkey);
4127 if (options.dump_pack)
4128 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4130 /* first determine for each live range the number of
4131 registers & the type of registers required for each */
4134 /* and serially allocate registers */
4135 serialRegAssign (ebbs, count);
4137 /* if stack was extended then tell the user */
4140 /* werror(W_TOOMANY_SPILS,"stack", */
4141 /* _G.stackExtend,currFunc->name,""); */
4147 /* werror(W_TOOMANY_SPILS,"data space", */
4148 /* _G.dataExtend,currFunc->name,""); */
4152 /* after that create the register mask
4153 for each of the instruction */
4154 createRegMask (ebbs, count);
4156 /* redo that offsets for stacked automatic variables */
4157 redoStackOffsets ();
4159 if (options.dump_rassgn)
4160 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4162 /* now get back the chain */
4163 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4165 debugLog ("ebbs after optimizing:\n");
4166 dumpEbbsToDebug (ebbs, count);
4171 /* free up any _G.stackSpil locations allocated */
4172 applyToSet (_G.stackSpil, deallocStackSpil);
4174 setToNull ((void *) &_G.stackSpil);
4175 setToNull ((void *) &_G.spiltSet);
4176 /* mark all registers as free */
4177 //pic14_freeAllRegs ();
4179 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");