1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
40 /*-----------------------------------------------------------------*/
41 /* At this point we start getting processor specific although */
42 /* some routines are non-processor specific & can be reused when */
43 /* targetting other processors. The decision for this will have */
44 /* to be made on a routine by routine basis */
45 /* routines used to pack registers are most definitely not reusable */
46 /* since the pack the registers depending strictly on the MCU */
47 /*-----------------------------------------------------------------*/
49 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
50 extern void genpic16Code (iCode *);
51 extern void pic16_assignConfigWordValue(int address, int value);
61 bitVect *funcrUsed; /* registers used in a function */
67 /* Shared with gen.c */
68 int pic16_ptrRegReq; /* one byte pointer register required */
71 set *pic16_dynAllocRegs=NULL;
72 set *pic16_dynStackRegs=NULL;
73 set *pic16_dynProcessorRegs=NULL;
74 set *pic16_dynDirectRegs=NULL;
75 set *pic16_dynDirectBitRegs=NULL;
76 set *pic16_dynInternalRegs=NULL;
78 static hTab *dynDirectRegNames= NULL;
79 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
81 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
82 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
83 set *pic16_equ_data=NULL; /* registers used by equates */
84 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
86 set *pic16_builtin_functions=NULL;
88 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
89 static int rDirectIdx=0;
91 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
93 int pic16_Gstack_base_addr=0; /* The starting address of registers that
94 * are used to pass and return parameters */
99 static void spillThis (symbol *);
100 int pic16_ralloc_debug = 0;
101 static FILE *debugF = NULL;
102 /*-----------------------------------------------------------------*/
103 /* debugLog - open a file for debugging information */
104 /*-----------------------------------------------------------------*/
105 //static void debugLog(char *inst,char *fmt, ...)
107 debugLog (char *fmt,...)
109 static int append = 0; // First time through, open the file without append.
112 //char *bufferP=buffer;
115 if (!pic16_ralloc_debug || !dstFileName)
121 /* create the file name */
122 strcpy (buffer, dstFileName);
123 strcat (buffer, ".d");
125 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
127 werror (E_FILE_OPEN_ERR, buffer);
130 append = 1; // Next time debubLog is called, we'll append the debug info
136 vsprintf (buffer, fmt, ap);
138 fprintf (debugF, "%s", buffer);
140 while (isspace(*bufferP)) bufferP++;
142 if (bufferP && *bufferP)
143 lineCurr = (lineCurr ?
144 connectLine(lineCurr,newLineNode(lb)) :
145 (lineHead = newLineNode(lb)));
146 lineCurr->isInline = _G.inLine;
147 lineCurr->isDebug = _G.debugLine;
156 if(!pic16_ralloc_debug)return;
159 fputc ('\n', debugF);
161 /*-----------------------------------------------------------------*/
162 /* debugLogClose - closes the debug log file (if opened) */
163 /*-----------------------------------------------------------------*/
173 #define AOP(op) op->aop
176 debugAopGet (char *str, operand * op)
178 if(!pic16_ralloc_debug)return NULL;
183 printOperand (op, debugF);
190 decodeOp (unsigned int op)
192 if (op < 128 && op > ' ') {
193 buffer[0] = (op & 0xff);
199 case IDENTIFIER: return "IDENTIFIER";
200 case TYPE_NAME: return "TYPE_NAME";
201 case CONSTANT: return "CONSTANT";
202 case STRING_LITERAL: return "STRING_LITERAL";
203 case SIZEOF: return "SIZEOF";
204 case PTR_OP: return "PTR_OP";
205 case INC_OP: return "INC_OP";
206 case DEC_OP: return "DEC_OP";
207 case LEFT_OP: return "LEFT_OP";
208 case RIGHT_OP: return "RIGHT_OP";
209 case LE_OP: return "LE_OP";
210 case GE_OP: return "GE_OP";
211 case EQ_OP: return "EQ_OP";
212 case NE_OP: return "NE_OP";
213 case AND_OP: return "AND_OP";
214 case OR_OP: return "OR_OP";
215 case MUL_ASSIGN: return "MUL_ASSIGN";
216 case DIV_ASSIGN: return "DIV_ASSIGN";
217 case MOD_ASSIGN: return "MOD_ASSIGN";
218 case ADD_ASSIGN: return "ADD_ASSIGN";
219 case SUB_ASSIGN: return "SUB_ASSIGN";
220 case LEFT_ASSIGN: return "LEFT_ASSIGN";
221 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
222 case AND_ASSIGN: return "AND_ASSIGN";
223 case XOR_ASSIGN: return "XOR_ASSIGN";
224 case OR_ASSIGN: return "OR_ASSIGN";
225 case TYPEDEF: return "TYPEDEF";
226 case EXTERN: return "EXTERN";
227 case STATIC: return "STATIC";
228 case AUTO: return "AUTO";
229 case REGISTER: return "REGISTER";
230 case CODE: return "CODE";
231 case EEPROM: return "EEPROM";
232 case INTERRUPT: return "INTERRUPT";
233 case SFR: return "SFR";
234 case AT: return "AT";
235 case SBIT: return "SBIT";
236 case REENTRANT: return "REENTRANT";
237 case USING: return "USING";
238 case XDATA: return "XDATA";
239 case DATA: return "DATA";
240 case IDATA: return "IDATA";
241 case PDATA: return "PDATA";
242 case VAR_ARGS: return "VAR_ARGS";
243 case CRITICAL: return "CRITICAL";
244 case NONBANKED: return "NONBANKED";
245 case BANKED: return "BANKED";
246 case CHAR: return "CHAR";
247 case SHORT: return "SHORT";
248 case INT: return "INT";
249 case LONG: return "LONG";
250 case SIGNED: return "SIGNED";
251 case UNSIGNED: return "UNSIGNED";
252 case FLOAT: return "FLOAT";
253 case DOUBLE: return "DOUBLE";
254 case CONST: return "CONST";
255 case VOLATILE: return "VOLATILE";
256 case VOID: return "VOID";
257 case BIT: return "BIT";
258 case STRUCT: return "STRUCT";
259 case UNION: return "UNION";
260 case ENUM: return "ENUM";
261 case ELIPSIS: return "ELIPSIS";
262 case RANGE: return "RANGE";
263 case FAR: return "FAR";
264 case CASE: return "CASE";
265 case DEFAULT: return "DEFAULT";
266 case IF: return "IF";
267 case ELSE: return "ELSE";
268 case SWITCH: return "SWITCH";
269 case WHILE: return "WHILE";
270 case DO: return "DO";
271 case FOR: return "FOR";
272 case GOTO: return "GOTO";
273 case CONTINUE: return "CONTINUE";
274 case BREAK: return "BREAK";
275 case RETURN: return "RETURN";
276 case INLINEASM: return "INLINEASM";
277 case IFX: return "IFX";
278 case ADDRESS_OF: return "ADDRESS_OF";
279 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
280 case SPIL: return "SPIL";
281 case UNSPIL: return "UNSPIL";
282 case GETHBIT: return "GETHBIT";
283 case BITWISEAND: return "BITWISEAND";
284 case UNARYMINUS: return "UNARYMINUS";
285 case IPUSH: return "IPUSH";
286 case IPOP: return "IPOP";
287 case PCALL: return "PCALL";
288 case ENDFUNCTION: return "ENDFUNCTION";
289 case JUMPTABLE: return "JUMPTABLE";
290 case RRC: return "RRC";
291 case RLC: return "RLC";
292 case CAST: return "CAST";
293 case CALL: return "CALL";
294 case PARAM: return "PARAM ";
295 case NULLOP: return "NULLOP";
296 case BLOCK: return "BLOCK";
297 case LABEL: return "LABEL";
298 case RECEIVE: return "RECEIVE";
299 case SEND: return "SEND";
301 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
305 /*-----------------------------------------------------------------*/
306 /*-----------------------------------------------------------------*/
308 debugLogRegType (short type)
310 if(!pic16_ralloc_debug)return NULL;
312 case REG_GPR: return "REG_GPR";
313 case REG_PTR: return "REG_PTR";
314 case REG_CND: return "REG_CND";
316 sprintf (buffer, "unknown reg type %d", type);
321 /*-----------------------------------------------------------------*/
322 /*-----------------------------------------------------------------*/
323 static int regname2key(char const *name)
332 key += (*name++) + 1;
336 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
340 /*-----------------------------------------------------------------*/
341 /* newReg - allocate and init memory for a new register */
342 /*-----------------------------------------------------------------*/
343 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
348 dReg = Safe_calloc(1,sizeof(regs));
350 dReg->pc_type = pc_type;
353 dReg->name = Safe_strdup(name);
355 sprintf(buffer,"r0x%02X", dReg->rIdx);
358 dReg->name = Safe_strdup(buffer);
365 // dReg->isMapped = 0;
368 if(type == REG_SFR) {
370 dReg->address = rIdx;
371 dReg->accessBank = 1;
375 dReg->accessBank = 0;
378 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
382 dReg->reg_alias = NULL;
383 dReg->reglives.usedpFlows = newSet();
384 dReg->reglives.assignedpFlows = newSet();
387 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
392 /*-----------------------------------------------------------------*/
393 /* regWithIdx - Search through a set of registers that matches idx */
394 /*-----------------------------------------------------------------*/
396 regWithIdx (set *dRegs, int idx, int fixed)
400 for (dReg = setFirstItem(dRegs) ; dReg ;
401 dReg = setNextItem(dRegs)) {
403 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
411 /*-----------------------------------------------------------------*/
412 /* regFindFree - Search for a free register in a set of registers */
413 /*-----------------------------------------------------------------*/
415 regFindFree (set *dRegs)
419 for (dReg = setFirstItem(dRegs) ; dReg ;
420 dReg = setNextItem(dRegs)) {
422 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
423 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
432 /*-----------------------------------------------------------------*/
433 /* pic16_initStack - allocate registers for a pseudo stack */
434 /*-----------------------------------------------------------------*/
435 void pic16_initStack(int base_address, int size)
440 pic16_Gstack_base_addr = base_address;
441 //fprintf(stderr,"initStack");
443 for(i = 0; i<size; i++)
444 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
447 /*-----------------------------------------------------------------*
448 *-----------------------------------------------------------------*/
450 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
452 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
454 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
456 reg->wasUsed = 0; // we do not know if they are going to be used at all
457 reg->accessBank = 1; // implicit add access Bank
459 return addSet(&pic16_dynProcessorRegs, reg);
462 /*-----------------------------------------------------------------*
463 *-----------------------------------------------------------------*/
466 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
468 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
470 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
474 return addSet(&pic16_dynInternalRegs,reg);
479 /*-----------------------------------------------------------------*/
480 /* allocReg - allocates register of given type */
481 /*-----------------------------------------------------------------*/
483 allocReg (short type)
488 if(dynrIdx > pic16_nRegs)
492 /* try to reuse some unused registers */
493 reg = regFindFree( pic16_dynAllocRegs );
496 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
497 addSet(&pic16_dynAllocRegs, reg);
501 // debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
503 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
504 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
507 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
508 reg->isLocal = 1; /* this is a local frame register */
512 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
514 return (reg); // addSet(&pic16_dynAllocRegs,reg);
519 /*-----------------------------------------------------------------*/
520 /* pic16_dirregWithName - search for register by name */
521 /*-----------------------------------------------------------------*/
523 pic16_dirregWithName (char *name)
531 /* hash the name to get a key */
533 hkey = regname2key(name);
535 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
537 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
541 if(STRCASECMP(reg->name, name) == 0) {
545 reg = hTabNextItemWK (dynDirectRegNames);
549 return NULL; // name wasn't found in the hash table
552 static int IS_CONFIG_ADDRESS(int address)
555 return address >= 0x300000 && address <= 0x300000d;
558 /*-----------------------------------------------------------------*/
559 /* pic16_allocDirReg - allocates register of given type */
560 /*-----------------------------------------------------------------*/
562 pic16_allocDirReg (operand *op )
568 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
572 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
574 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
575 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
578 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
579 debugLog(" %d const char\n",__LINE__);
580 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
581 // fprintf(stderr, " %d const char\n",__LINE__);
582 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
586 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
587 if (IS_CODE ( OP_SYM_ETYPE(op)) )
588 debugLog(" %d code space\n",__LINE__);
590 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
591 debugLog(" %d integral\n",__LINE__);
593 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
594 debugLog(" %d literal\n",__LINE__);
596 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
597 debugLog(" %d specifier\n",__LINE__);
599 debugAopGet(NULL, op);
602 if (IS_CODE ( OP_SYM_ETYPE(op)) )
605 /* First, search the hash table to see if there is a register with this name */
606 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
608 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
612 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
613 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
615 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
616 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
619 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
621 reg = pic16_dirregWithName(name);
626 int regtype = REG_GPR;
628 /* if this is at an absolute address, then get the address. */
629 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
630 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
631 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
634 /* Register wasn't found in hash, so let's create
635 * a new one and put it in the hash table AND in the
636 * dynDirectRegNames set */
637 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
638 if(pic16_debug_verbose)
639 fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
640 OP_SYMBOL(op)->name);
644 if(!IS_CONFIG_ADDRESS(address)) {
645 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
647 if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
649 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
650 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
652 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
654 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
655 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
656 // reg->type = REG_SFR;
659 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
660 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
661 addSet(&pic16_dynDirectBitRegs, reg);
664 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
665 checkAddReg(&pic16_dynDirectRegs, reg);
669 debugLog (" -- %s is declared at address 0x30000x\n",name);
670 fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
676 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
678 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
679 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
685 /*-----------------------------------------------------------------*/
686 /* pic16_allocRegByName - allocates register of given type */
687 /*-----------------------------------------------------------------*/
689 pic16_allocRegByName (char *name, int size)
695 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
699 /* First, search the hash table to see if there is a register with this name */
700 reg = pic16_dirregWithName(name);
704 /* Register wasn't found in hash, so let's create
705 * a new one and put it in the hash table AND in the
706 * dynDirectRegNames set */
707 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
708 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
710 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
711 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
713 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
714 addSet(&pic16_dynDirectRegs, reg);
720 /*-----------------------------------------------------------------*/
721 /* RegWithIdx - returns pointer to register with index number */
722 /*-----------------------------------------------------------------*/
723 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
728 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
733 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
735 debugLog ("Found a Dynamic Register!\n");
738 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
739 debugLog ("Found a Direct Register!\n");
745 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
746 debugLog ("Found a Stack Register!\n");
751 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
752 debugLog ("Found a Processor Register!\n");
766 /*-----------------------------------------------------------------*/
767 /* pic16_regWithIdx - returns pointer to register with index number*/
768 /*-----------------------------------------------------------------*/
770 pic16_regWithIdx (int idx)
774 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
777 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
780 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
786 /*-----------------------------------------------------------------*/
787 /* pic16_regWithIdx - returns pointer to register with index number */
788 /*-----------------------------------------------------------------*/
790 pic16_allocWithIdx (int idx)
795 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
797 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
799 debugLog ("Found a Dynamic Register!\n");
800 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
801 debugLog ("Found a Stack Register!\n");
802 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
803 debugLog ("Found a Processor Register!\n");
804 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
805 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
806 debugLog ("Found an Internal Register!\n");
809 debugLog ("Dynamic Register not found\n");
812 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
813 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
814 "regWithIdx not found");
824 /*-----------------------------------------------------------------*/
825 /*-----------------------------------------------------------------*/
827 pic16_findFreeReg(short type)
834 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
836 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
840 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
852 /*-----------------------------------------------------------------*/
853 /* freeReg - frees a register */
854 /*-----------------------------------------------------------------*/
858 debugLog ("%s\n", __FUNCTION__);
859 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
864 /*-----------------------------------------------------------------*/
865 /* nFreeRegs - returns number of free registers */
866 /*-----------------------------------------------------------------*/
874 /* although I fixed the register allocation/freeing scheme
875 * the for loop below doesn't give valid results. I do not
876 * know why yet. -- VR 10-Jan-2003 */
881 /* dynamically allocate as many as we need and worry about
882 * fitting them into a PIC later */
884 debugLog ("%s\n", __FUNCTION__);
886 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
887 if((reg->type == type) && reg->isFree)nfr++;
889 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
893 /*-----------------------------------------------------------------*/
894 /* nfreeRegsType - free registers with type */
895 /*-----------------------------------------------------------------*/
897 nfreeRegsType (int type)
900 debugLog ("%s\n", __FUNCTION__);
903 if ((nfr = nFreeRegs (type)) == 0)
904 return nFreeRegs (REG_GPR);
907 return nFreeRegs (type);
910 static void writeSetUsedRegs(FILE *of, set *dRegs)
915 for (dReg = setFirstItem(dRegs) ; dReg ;
916 dReg = setNextItem(dRegs)) {
919 fprintf (of, "\t%s\n",dReg->name);
925 extern void pic16_groupRegistersInSection(set *regset);
927 extern void pic16_dump_equates(FILE *of, set *equs);
928 //extern void pic16_dump_map(void);
929 extern void pic16_dump_section(FILE *of, set *section, int fix);
930 extern void pic16_dump_int_registers(FILE *of, set *section);
932 static void packBits(set *bregs)
937 regs *relocbitfield=NULL;
943 for (regset = bregs ; regset ;
944 regset = regset->next) {
947 breg->isBitField = 1;
948 //fprintf(stderr,"bit reg: %s\n",breg->name);
951 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
953 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
954 breg->rIdx = breg->address & 7;
958 sprintf (buffer, "fbitfield%02x", breg->address);
959 //fprintf(stderr,"new bit field\n");
960 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
961 bitfield->isBitField = 1;
962 bitfield->isFixed = 1;
963 bitfield->address = breg->address;
964 addSet(&pic16_dynDirectRegs,bitfield);
965 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
967 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
970 breg->reg_alias = bitfield;
974 if(!relocbitfield || bit_no >7) {
977 sprintf (buffer, "bitfield%d", byte_no);
978 //fprintf(stderr,"new relocatable bit field\n");
979 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
980 relocbitfield->isBitField = 1;
981 addSet(&pic16_dynDirectRegs,relocbitfield);
982 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
986 breg->reg_alias = relocbitfield;
987 breg->address = rDirectIdx; /* byte_no; */
988 breg->rIdx = bit_no++;
997 static void bitEQUs(FILE *of, set *bregs)
1002 //fprintf(stderr," %s\n",__FUNCTION__);
1003 for (breg = setFirstItem(bregs) ; breg ;
1004 breg = setNextItem(bregs)) {
1006 //fprintf(stderr,"bit reg: %s\n",breg->name);
1008 bytereg = breg->reg_alias;
1010 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1013 breg->rIdx & 0x0007);
1016 fprintf(stderr, "bit field is not assigned to a register\n");
1017 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1028 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1033 for (reg = setFirstItem(fregs) ; reg ;
1034 reg = setNextItem(fregs)) {
1036 if(!reg->isEmitted && reg->wasUsed) {
1038 if (reg->type != REG_SFR) {
1039 fprintf (of, "%s\tEQU\t0x%03x\n",
1045 fprintf (of, "%s\tEQU\t0x%03x\n",
1054 void pic16_writeUsedRegs(FILE *of)
1056 packBits(pic16_dynDirectBitRegs);
1058 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1059 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1060 pic16_groupRegistersInSection(pic16_dynStackRegs);
1061 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1062 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1063 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1067 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1068 pic16_assignFixedRegisters(pic16_dynStackRegs);
1069 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1070 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1072 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1073 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1074 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1075 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1076 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1079 // pic16_dump_map();
1080 // pic16_dump_cblock(of);
1083 pic16_dump_equates(of, pic16_equ_data);
1085 /* dump internal registers */
1086 pic16_dump_int_registers(of, pic16_int_regs);
1088 /* dump other variables */
1089 pic16_dump_section(of, pic16_rel_udata, 0);
1090 pic16_dump_section(of, pic16_fix_udata, 1);
1095 /*-----------------------------------------------------------------*/
1096 /* allDefsOutOfRange - all definitions are out of a range */
1097 /*-----------------------------------------------------------------*/
1099 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1103 debugLog ("%s\n", __FUNCTION__);
1107 for (i = 0; i < defs->size; i++)
1111 if (bitVectBitValue (defs, i) &&
1112 (ic = hTabItemWithKey (iCodehTab, i)) &&
1113 (ic->seq >= fseq && ic->seq <= toseq))
1123 /*-----------------------------------------------------------------*/
1124 /* computeSpillable - given a point find the spillable live ranges */
1125 /*-----------------------------------------------------------------*/
1127 computeSpillable (iCode * ic)
1131 debugLog ("%s\n", __FUNCTION__);
1132 /* spillable live ranges are those that are live at this
1133 point . the following categories need to be subtracted
1135 a) - those that are already spilt
1136 b) - if being used by this one
1137 c) - defined by this one */
1139 spillable = bitVectCopy (ic->rlive);
1141 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1143 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1144 bitVectUnSetBit (spillable, ic->defKey);
1145 spillable = bitVectIntersect (spillable, _G.regAssigned);
1150 /*-----------------------------------------------------------------*/
1151 /* noSpilLoc - return true if a variable has no spil location */
1152 /*-----------------------------------------------------------------*/
1154 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1156 debugLog ("%s\n", __FUNCTION__);
1157 return (sym->usl.spillLoc ? 0 : 1);
1160 /*-----------------------------------------------------------------*/
1161 /* hasSpilLoc - will return 1 if the symbol has spil location */
1162 /*-----------------------------------------------------------------*/
1164 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1166 debugLog ("%s\n", __FUNCTION__);
1167 return (sym->usl.spillLoc ? 1 : 0);
1170 /*-----------------------------------------------------------------*/
1171 /* directSpilLoc - will return 1 if the splilocation is in direct */
1172 /*-----------------------------------------------------------------*/
1174 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1176 debugLog ("%s\n", __FUNCTION__);
1177 if (sym->usl.spillLoc &&
1178 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1184 /*-----------------------------------------------------------------*/
1185 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1186 /* but is not used as a pointer */
1187 /*-----------------------------------------------------------------*/
1189 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1191 debugLog ("%s\n", __FUNCTION__);
1192 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1195 /*-----------------------------------------------------------------*/
1196 /* rematable - will return 1 if the remat flag is set */
1197 /*-----------------------------------------------------------------*/
1199 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1201 debugLog ("%s\n", __FUNCTION__);
1205 /*-----------------------------------------------------------------*/
1206 /* notUsedInRemaining - not used or defined in remain of the block */
1207 /*-----------------------------------------------------------------*/
1209 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1211 debugLog ("%s\n", __FUNCTION__);
1212 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1213 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1216 /*-----------------------------------------------------------------*/
1217 /* allLRs - return true for all */
1218 /*-----------------------------------------------------------------*/
1220 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1222 debugLog ("%s\n", __FUNCTION__);
1226 /*-----------------------------------------------------------------*/
1227 /* liveRangesWith - applies function to a given set of live range */
1228 /*-----------------------------------------------------------------*/
1230 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1231 eBBlock * ebp, iCode * ic)
1236 debugLog ("%s\n", __FUNCTION__);
1237 if (!lrs || !lrs->size)
1240 for (i = 1; i < lrs->size; i++)
1243 if (!bitVectBitValue (lrs, i))
1246 /* if we don't find it in the live range
1247 hash table we are in serious trouble */
1248 if (!(sym = hTabItemWithKey (liveRanges, i)))
1250 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1251 "liveRangesWith could not find liveRange");
1255 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1256 addSetHead (&rset, sym);
1263 /*-----------------------------------------------------------------*/
1264 /* leastUsedLR - given a set determines which is the least used */
1265 /*-----------------------------------------------------------------*/
1267 leastUsedLR (set * sset)
1269 symbol *sym = NULL, *lsym = NULL;
1271 debugLog ("%s\n", __FUNCTION__);
1272 sym = lsym = setFirstItem (sset);
1277 for (; lsym; lsym = setNextItem (sset))
1280 /* if usage is the same then prefer
1281 the spill the smaller of the two */
1282 if (lsym->used == sym->used)
1283 if (getSize (lsym->type) < getSize (sym->type))
1287 if (lsym->used < sym->used)
1292 setToNull ((void *) &sset);
1297 /*-----------------------------------------------------------------*/
1298 /* noOverLap - will iterate through the list looking for over lap */
1299 /*-----------------------------------------------------------------*/
1301 noOverLap (set * itmpStack, symbol * fsym)
1304 debugLog ("%s\n", __FUNCTION__);
1307 for (sym = setFirstItem (itmpStack); sym;
1308 sym = setNextItem (itmpStack))
1310 if (sym->liveTo > fsym->liveFrom)
1318 /*-----------------------------------------------------------------*/
1319 /* isFree - will return 1 if the a free spil location is found */
1320 /*-----------------------------------------------------------------*/
1325 V_ARG (symbol **, sloc);
1326 V_ARG (symbol *, fsym);
1328 debugLog ("%s\n", __FUNCTION__);
1329 /* if already found */
1333 /* if it is free && and the itmp assigned to
1334 this does not have any overlapping live ranges
1335 with the one currently being assigned and
1336 the size can be accomodated */
1338 noOverLap (sym->usl.itmpStack, fsym) &&
1339 getSize (sym->type) >= getSize (fsym->type))
1348 /*-----------------------------------------------------------------*/
1349 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1350 /*-----------------------------------------------------------------*/
1352 spillLRWithPtrReg (symbol * forSym)
1358 debugLog ("%s\n", __FUNCTION__);
1359 if (!_G.regAssigned ||
1360 bitVectIsZero (_G.regAssigned))
1363 r0 = pic16_regWithIdx (R0_IDX);
1364 r1 = pic16_regWithIdx (R1_IDX);
1366 /* for all live ranges */
1367 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1368 lrsym = hTabNextItem (liveRanges, &k))
1372 /* if no registers assigned to it or
1374 /* if it does not overlap with this then
1375 not need to spill it */
1377 if (lrsym->isspilt || !lrsym->nRegs ||
1378 (lrsym->liveTo < forSym->liveFrom))
1381 /* go thru the registers : if it is either
1382 r0 or r1 then spil it */
1383 for (j = 0; j < lrsym->nRegs; j++)
1384 if (lrsym->regs[j] == r0 ||
1385 lrsym->regs[j] == r1)
1394 /*-----------------------------------------------------------------*/
1395 /* createStackSpil - create a location on the stack to spil */
1396 /*-----------------------------------------------------------------*/
1398 createStackSpil (symbol * sym)
1400 symbol *sloc = NULL;
1401 int useXstack, model, noOverlay;
1403 char slocBuffer[30];
1404 debugLog ("%s\n", __FUNCTION__);
1406 /* first go try and find a free one that is already
1407 existing on the stack */
1408 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1410 /* found a free one : just update & return */
1411 sym->usl.spillLoc = sloc;
1414 addSetHead (&sloc->usl.itmpStack, sym);
1418 /* could not then have to create one , this is the hard part
1419 we need to allocate this on the stack : this is really a
1420 hack!! but cannot think of anything better at this time */
1422 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1424 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1425 __FILE__, __LINE__);
1429 sloc = newiTemp (slocBuffer);
1431 /* set the type to the spilling symbol */
1432 sloc->type = copyLinkChain (sym->type);
1433 sloc->etype = getSpec (sloc->type);
1434 SPEC_SCLS (sloc->etype) = S_DATA;
1435 SPEC_EXTR (sloc->etype) = 0;
1436 SPEC_STAT (sloc->etype) = 0;
1438 /* we don't allow it to be allocated`
1439 onto the external stack since : so we
1440 temporarily turn it off ; we also
1441 turn off memory model to prevent
1442 the spil from going to the external storage
1443 and turn off overlaying
1446 useXstack = options.useXstack;
1447 model = options.model;
1448 noOverlay = options.noOverlay;
1449 options.noOverlay = 1;
1450 options.model = options.useXstack = 0;
1454 options.useXstack = useXstack;
1455 options.model = model;
1456 options.noOverlay = noOverlay;
1457 sloc->isref = 1; /* to prevent compiler warning */
1459 /* if it is on the stack then update the stack */
1460 if (IN_STACK (sloc->etype))
1462 currFunc->stack += getSize (sloc->type);
1463 _G.stackExtend += getSize (sloc->type);
1466 _G.dataExtend += getSize (sloc->type);
1468 /* add it to the _G.stackSpil set */
1469 addSetHead (&_G.stackSpil, sloc);
1470 sym->usl.spillLoc = sloc;
1473 /* add it to the set of itempStack set
1474 of the spill location */
1475 addSetHead (&sloc->usl.itmpStack, sym);
1479 /*-----------------------------------------------------------------*/
1480 /* isSpiltOnStack - returns true if the spil location is on stack */
1481 /*-----------------------------------------------------------------*/
1483 isSpiltOnStack (symbol * sym)
1487 debugLog ("%s\n", __FUNCTION__);
1494 /* if (sym->_G.stackSpil) */
1497 if (!sym->usl.spillLoc)
1500 etype = getSpec (sym->usl.spillLoc->type);
1501 if (IN_STACK (etype))
1507 /*-----------------------------------------------------------------*/
1508 /* spillThis - spils a specific operand */
1509 /*-----------------------------------------------------------------*/
1511 spillThis (symbol * sym)
1514 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1516 /* if this is rematerializable or has a spillLocation
1517 we are okay, else we need to create a spillLocation
1519 if (!(sym->remat || sym->usl.spillLoc))
1520 createStackSpil (sym);
1523 /* mark it has spilt & put it in the spilt set */
1525 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1527 bitVectUnSetBit (_G.regAssigned, sym->key);
1529 for (i = 0; i < sym->nRegs; i++)
1533 freeReg (sym->regs[i]);
1534 sym->regs[i] = NULL;
1537 /* if spilt on stack then free up r0 & r1
1538 if they could have been assigned to some
1540 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1543 spillLRWithPtrReg (sym);
1546 if (sym->usl.spillLoc && !sym->remat)
1547 sym->usl.spillLoc->allocreq = 1;
1551 /*-----------------------------------------------------------------*/
1552 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1553 /*-----------------------------------------------------------------*/
1555 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1557 bitVect *lrcs = NULL;
1561 debugLog ("%s\n", __FUNCTION__);
1562 /* get the spillable live ranges */
1563 lrcs = computeSpillable (ic);
1565 /* get all live ranges that are rematerizable */
1566 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1569 /* return the least used of these */
1570 return leastUsedLR (selectS);
1573 /* get live ranges with spillLocations in direct space */
1574 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1576 sym = leastUsedLR (selectS);
1577 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1578 sym->usl.spillLoc->rname :
1579 sym->usl.spillLoc->name));
1581 /* mark it as allocation required */
1582 sym->usl.spillLoc->allocreq = 1;
1586 /* if the symbol is local to the block then */
1587 if (forSym->liveTo < ebp->lSeq)
1590 /* check if there are any live ranges allocated
1591 to registers that are not used in this block */
1592 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1594 sym = leastUsedLR (selectS);
1595 /* if this is not rematerializable */
1604 /* check if there are any live ranges that not
1605 used in the remainder of the block */
1606 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1608 sym = leastUsedLR (selectS);
1611 sym->remainSpil = 1;
1618 /* find live ranges with spillocation && not used as pointers */
1619 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1622 sym = leastUsedLR (selectS);
1623 /* mark this as allocation required */
1624 sym->usl.spillLoc->allocreq = 1;
1628 /* find live ranges with spillocation */
1629 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1632 sym = leastUsedLR (selectS);
1633 sym->usl.spillLoc->allocreq = 1;
1637 /* couldn't find then we need to create a spil
1638 location on the stack , for which one? the least
1640 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1643 /* return a created spil location */
1644 sym = createStackSpil (leastUsedLR (selectS));
1645 sym->usl.spillLoc->allocreq = 1;
1649 /* this is an extreme situation we will spill
1650 this one : happens very rarely but it does happen */
1656 /*-----------------------------------------------------------------*/
1657 /* spilSomething - spil some variable & mark registers as free */
1658 /*-----------------------------------------------------------------*/
1660 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1665 debugLog ("%s\n", __FUNCTION__);
1666 /* get something we can spil */
1667 ssym = selectSpil (ic, ebp, forSym);
1669 /* mark it as spilt */
1671 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1673 /* mark it as not register assigned &
1674 take it away from the set */
1675 bitVectUnSetBit (_G.regAssigned, ssym->key);
1677 /* mark the registers as free */
1678 for (i = 0; i < ssym->nRegs; i++)
1680 freeReg (ssym->regs[i]);
1682 /* if spilt on stack then free up r0 & r1
1683 if they could have been assigned to as gprs */
1684 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1687 spillLRWithPtrReg (ssym);
1690 /* if this was a block level spil then insert push & pop
1691 at the start & end of block respectively */
1692 if (ssym->blockSpil)
1694 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1695 /* add push to the start of the block */
1696 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1697 ebp->sch->next : ebp->sch));
1698 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1699 /* add pop to the end of the block */
1700 addiCodeToeBBlock (ebp, nic, NULL);
1703 /* if spilt because not used in the remainder of the
1704 block then add a push before this instruction and
1705 a pop at the end of the block */
1706 if (ssym->remainSpil)
1709 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1710 /* add push just before this instruction */
1711 addiCodeToeBBlock (ebp, nic, ic);
1713 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1714 /* add pop to the end of the block */
1715 addiCodeToeBBlock (ebp, nic, NULL);
1724 /*-----------------------------------------------------------------*/
1725 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1726 /*-----------------------------------------------------------------*/
1728 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1733 debugLog ("%s\n", __FUNCTION__);
1735 /* try for a ptr type */
1736 if ((reg = allocReg (REG_PTR)))
1739 /* try for gpr type */
1740 if ((reg = allocReg (REG_GPR)))
1743 /* we have to spil */
1744 if (!spilSomething (ic, ebp, sym))
1747 /* make sure partially assigned registers aren't reused */
1748 for (j=0; j<=sym->nRegs; j++)
1750 sym->regs[j]->isFree = 0;
1752 /* this looks like an infinite loop but
1753 in really selectSpil will abort */
1757 /*-----------------------------------------------------------------*/
1758 /* getRegGpr - will try for GPR if not spil */
1759 /*-----------------------------------------------------------------*/
1761 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1766 debugLog ("%s\n", __FUNCTION__);
1768 /* try for gpr type */
1769 if ((reg = allocReg (REG_GPR)))
1772 if (!pic16_ptrRegReq)
1773 if ((reg = allocReg (REG_PTR)))
1776 /* we have to spil */
1777 if (!spilSomething (ic, ebp, sym))
1780 /* make sure partially assigned registers aren't reused */
1781 for (j=0; j<=sym->nRegs; j++)
1783 sym->regs[j]->isFree = 0;
1785 /* this looks like an infinite loop but
1786 in really selectSpil will abort */
1790 /*-----------------------------------------------------------------*/
1791 /* symHasReg - symbol has a given register */
1792 /*-----------------------------------------------------------------*/
1794 symHasReg (symbol * sym, regs * reg)
1798 debugLog ("%s\n", __FUNCTION__);
1799 for (i = 0; i < sym->nRegs; i++)
1800 if (sym->regs[i] == reg)
1806 /*-----------------------------------------------------------------*/
1807 /* deassignLRs - check the live to and if they have registers & are */
1808 /* not spilt then free up the registers */
1809 /*-----------------------------------------------------------------*/
1811 deassignLRs (iCode * ic, eBBlock * ebp)
1817 debugLog ("%s\n", __FUNCTION__);
1818 for (sym = hTabFirstItem (liveRanges, &k); sym;
1819 sym = hTabNextItem (liveRanges, &k))
1822 symbol *psym = NULL;
1823 /* if it does not end here */
1824 if (sym->liveTo > ic->seq)
1827 /* if it was spilt on stack then we can
1828 mark the stack spil location as free */
1833 sym->usl.spillLoc->isFree = 1;
1839 if (!bitVectBitValue (_G.regAssigned, sym->key))
1842 /* special case check if this is an IFX &
1843 the privious one was a pop and the
1844 previous one was not spilt then keep track
1846 if (ic->op == IFX && ic->prev &&
1847 ic->prev->op == IPOP &&
1848 !ic->prev->parmPush &&
1849 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1850 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1856 bitVectUnSetBit (_G.regAssigned, sym->key);
1858 /* if the result of this one needs registers
1859 and does not have it then assign it right
1861 if (IC_RESULT (ic) &&
1862 !(SKIP_IC2 (ic) || /* not a special icode */
1863 ic->op == JUMPTABLE ||
1868 POINTER_SET (ic)) &&
1869 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1870 result->liveTo > ic->seq && /* and will live beyond this */
1871 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1872 result->regType == sym->regType && /* same register types */
1873 result->nRegs && /* which needs registers */
1874 !result->isspilt && /* and does not already have them */
1876 !bitVectBitValue (_G.regAssigned, result->key) &&
1877 /* the number of free regs + number of regs in this LR
1878 can accomodate the what result Needs */
1879 ((nfreeRegsType (result->regType) +
1880 sym->nRegs) >= result->nRegs)
1884 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1886 result->regs[i] = sym->regs[i];
1888 result->regs[i] = getRegGpr (ic, ebp, result);
1890 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1894 /* free the remaining */
1895 for (; i < sym->nRegs; i++)
1899 if (!symHasReg (psym, sym->regs[i]))
1900 freeReg (sym->regs[i]);
1903 freeReg (sym->regs[i]);
1910 /*-----------------------------------------------------------------*/
1911 /* reassignLR - reassign this to registers */
1912 /*-----------------------------------------------------------------*/
1914 reassignLR (operand * op)
1916 symbol *sym = OP_SYMBOL (op);
1919 debugLog ("%s\n", __FUNCTION__);
1920 /* not spilt any more */
1921 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1922 bitVectUnSetBit (_G.spiltSet, sym->key);
1924 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1928 for (i = 0; i < sym->nRegs; i++)
1929 sym->regs[i]->isFree = 0;
1932 /*-----------------------------------------------------------------*/
1933 /* willCauseSpill - determines if allocating will cause a spill */
1934 /*-----------------------------------------------------------------*/
1936 willCauseSpill (int nr, int rt)
1938 debugLog ("%s\n", __FUNCTION__);
1939 /* first check if there are any avlb registers
1940 of te type required */
1943 /* special case for pointer type
1944 if pointer type not avlb then
1945 check for type gpr */
1946 if (nFreeRegs (rt) >= nr)
1948 if (nFreeRegs (REG_GPR) >= nr)
1953 if (pic16_ptrRegReq)
1955 if (nFreeRegs (rt) >= nr)
1960 if (nFreeRegs (REG_PTR) +
1961 nFreeRegs (REG_GPR) >= nr)
1966 debugLog (" ... yep it will (cause a spill)\n");
1967 /* it will cause a spil */
1971 /*-----------------------------------------------------------------*/
1972 /* positionRegs - the allocator can allocate same registers to res- */
1973 /* ult and operand, if this happens make sure they are in the same */
1974 /* position as the operand otherwise chaos results */
1975 /*-----------------------------------------------------------------*/
1977 positionRegs (symbol * result, symbol * opsym, int lineno)
1979 int count = min (result->nRegs, opsym->nRegs);
1980 int i, j = 0, shared = 0;
1982 debugLog ("%s\n", __FUNCTION__);
1983 /* if the result has been spilt then cannot share */
1988 /* first make sure that they actually share */
1989 for (i = 0; i < count; i++)
1991 for (j = 0; j < count; j++)
1993 if (result->regs[i] == opsym->regs[j] && i != j)
2003 regs *tmp = result->regs[i];
2004 result->regs[i] = result->regs[j];
2005 result->regs[j] = tmp;
2010 /*------------------------------------------------------------------*/
2011 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2012 /* it should either have registers or have beed spilled. Otherwise, */
2013 /* there was an uninitialized variable, so just spill this to get */
2014 /* the operand in a valid state. */
2015 /*------------------------------------------------------------------*/
2017 verifyRegsAssigned (operand *op, iCode * ic)
2022 if (!IS_ITEMP (op)) return;
2024 sym = OP_SYMBOL (op);
2025 if (sym->isspilt) return;
2026 if (!sym->nRegs) return;
2027 if (sym->regs[0]) return;
2029 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2030 sym->prereqv ? sym->prereqv->name : sym->name);
2035 /*-----------------------------------------------------------------*/
2036 /* serialRegAssign - serially allocate registers to the variables */
2037 /*-----------------------------------------------------------------*/
2039 serialRegAssign (eBBlock ** ebbs, int count)
2043 debugLog ("%s\n", __FUNCTION__);
2044 /* for all blocks */
2045 for (i = 0; i < count; i++)
2050 if (ebbs[i]->noPath &&
2051 (ebbs[i]->entryLabel != entryLabel &&
2052 ebbs[i]->entryLabel != returnLabel))
2055 /* of all instructions do */
2056 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2059 debugLog (" op: %s\n", decodeOp (ic->op));
2061 /* if this is an ipop that means some live
2062 range will have to be assigned again */
2064 reassignLR (IC_LEFT (ic));
2066 /* if result is present && is a true symbol */
2067 if (IC_RESULT (ic) && ic->op != IFX &&
2068 IS_TRUE_SYMOP (IC_RESULT (ic)))
2069 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2071 /* take away registers from live
2072 ranges that end at this instruction */
2073 deassignLRs (ic, ebbs[i]);
2075 /* some don't need registers */
2076 if (SKIP_IC2 (ic) ||
2077 ic->op == JUMPTABLE ||
2081 (IC_RESULT (ic) && POINTER_SET (ic)))
2084 /* now we need to allocate registers
2085 only for the result */
2088 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2094 /* if it does not need or is spilt
2095 or is already assigned to registers
2096 or will not live beyond this instructions */
2099 bitVectBitValue (_G.regAssigned, sym->key) ||
2100 sym->liveTo <= ic->seq)
2103 /* if some liverange has been spilt at the block level
2104 and this one live beyond this block then spil this
2106 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2111 /* if trying to allocate this will cause
2112 a spill and there is nothing to spill
2113 or this one is rematerializable then
2115 willCS = willCauseSpill (sym->nRegs, sym->regType);
2116 spillable = computeSpillable (ic);
2118 (willCS && bitVectIsZero (spillable)))
2126 /* if it has a spillocation & is used less than
2127 all other live ranges then spill this */
2129 if (sym->usl.spillLoc) {
2130 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2131 allLRs, ebbs[i], ic));
2132 if (leastUsed && leastUsed->used > sym->used) {
2137 /* if none of the liveRanges have a spillLocation then better
2138 to spill this one than anything else already assigned to registers */
2139 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2140 /* if this is local to this block then we might find a block spil */
2141 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2149 if (ic->op == RECEIVE)
2150 debugLog ("When I get clever, I'll optimize the receive logic\n");
2152 /* if we need ptr regs for the right side
2154 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2155 <= (unsigned) PTRSIZE)
2160 /* else we assign registers to it */
2161 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2163 debugLog (" %d - \n", __LINE__);
2165 bitVectDebugOn(_G.regAssigned, debugF);
2167 for (j = 0; j < sym->nRegs; j++)
2169 if (sym->regType == REG_PTR)
2170 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2172 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2174 /* if the allocation falied which means
2175 this was spilt then break */
2179 debugLog (" %d - \n", __LINE__);
2181 /* if it shares registers with operands make sure
2182 that they are in the same position */
2183 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2184 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2185 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2186 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2187 /* do the same for the right operand */
2188 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2189 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2190 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2191 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2193 debugLog (" %d - \n", __LINE__);
2196 debugLog (" %d - \n", __LINE__);
2205 /* Check for and fix any problems with uninitialized operands */
2206 for (i = 0; i < count; i++)
2210 if (ebbs[i]->noPath &&
2211 (ebbs[i]->entryLabel != entryLabel &&
2212 ebbs[i]->entryLabel != returnLabel))
2215 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2222 verifyRegsAssigned (IC_COND (ic), ic);
2226 if (ic->op == JUMPTABLE)
2228 verifyRegsAssigned (IC_JTCOND (ic), ic);
2232 verifyRegsAssigned (IC_RESULT (ic), ic);
2233 verifyRegsAssigned (IC_LEFT (ic), ic);
2234 verifyRegsAssigned (IC_RIGHT (ic), ic);
2240 /*-----------------------------------------------------------------*/
2241 /* rUmaskForOp :- returns register mask for an operand */
2242 /*-----------------------------------------------------------------*/
2244 rUmaskForOp (operand * op)
2250 debugLog ("%s\n", __FUNCTION__);
2251 /* only temporaries are assigned registers */
2255 sym = OP_SYMBOL (op);
2257 /* if spilt or no registers assigned to it
2259 if (sym->isspilt || !sym->nRegs)
2262 rumask = newBitVect (pic16_nRegs);
2264 for (j = 0; j < sym->nRegs; j++)
2266 rumask = bitVectSetBit (rumask,
2267 sym->regs[j]->rIdx);
2273 /*-----------------------------------------------------------------*/
2274 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2275 /*-----------------------------------------------------------------*/
2277 regsUsedIniCode (iCode * ic)
2279 bitVect *rmask = newBitVect (pic16_nRegs);
2281 debugLog ("%s\n", __FUNCTION__);
2282 /* do the special cases first */
2285 rmask = bitVectUnion (rmask,
2286 rUmaskForOp (IC_COND (ic)));
2290 /* for the jumptable */
2291 if (ic->op == JUMPTABLE)
2293 rmask = bitVectUnion (rmask,
2294 rUmaskForOp (IC_JTCOND (ic)));
2299 /* of all other cases */
2301 rmask = bitVectUnion (rmask,
2302 rUmaskForOp (IC_LEFT (ic)));
2306 rmask = bitVectUnion (rmask,
2307 rUmaskForOp (IC_RIGHT (ic)));
2310 rmask = bitVectUnion (rmask,
2311 rUmaskForOp (IC_RESULT (ic)));
2317 /*-----------------------------------------------------------------*/
2318 /* createRegMask - for each instruction will determine the regsUsed */
2319 /*-----------------------------------------------------------------*/
2321 createRegMask (eBBlock ** ebbs, int count)
2325 debugLog ("%s\n", __FUNCTION__);
2326 /* for all blocks */
2327 for (i = 0; i < count; i++)
2331 if (ebbs[i]->noPath &&
2332 (ebbs[i]->entryLabel != entryLabel &&
2333 ebbs[i]->entryLabel != returnLabel))
2336 /* for all instructions */
2337 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2342 if (SKIP_IC2 (ic) || !ic->rlive)
2345 /* first mark the registers used in this
2347 ic->rUsed = regsUsedIniCode (ic);
2348 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2350 /* now create the register mask for those
2351 registers that are in use : this is a
2352 super set of ic->rUsed */
2353 ic->rMask = newBitVect (pic16_nRegs + 1);
2355 /* for all live Ranges alive at this point */
2356 for (j = 1; j < ic->rlive->size; j++)
2361 /* if not alive then continue */
2362 if (!bitVectBitValue (ic->rlive, j))
2365 /* find the live range we are interested in */
2366 if (!(sym = hTabItemWithKey (liveRanges, j)))
2368 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2369 "createRegMask cannot find live range");
2373 /* if no register assigned to it */
2374 if (!sym->nRegs || sym->isspilt)
2377 /* for all the registers allocated to it */
2378 for (k = 0; k < sym->nRegs; k++)
2381 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2387 /*-----------------------------------------------------------------*/
2388 /* rematStr - returns the rematerialized string for a remat var */
2389 /*-----------------------------------------------------------------*/
2391 rematStr (symbol * sym)
2394 iCode *ic = sym->rematiCode;
2395 symbol *psym = NULL;
2397 debugLog ("%s\n", __FUNCTION__);
2399 //printf ("%s\n", s);
2401 /* if plus or minus print the right hand side */
2403 if (ic->op == '+' || ic->op == '-') {
2405 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2407 sprintf (s, "(%s %c 0x%04x)",
2408 OP_SYMBOL (IC_LEFT (ric))->rname,
2410 (int) operandLitValue (IC_RIGHT (ic)));
2413 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2415 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2416 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2421 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2422 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2424 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2429 /*-----------------------------------------------------------------*/
2430 /* rematStr - returns the rematerialized string for a remat var */
2431 /*-----------------------------------------------------------------*/
2433 rematStr (symbol * sym)
2436 iCode *ic = sym->rematiCode;
2438 debugLog ("%s\n", __FUNCTION__);
2443 /* if plus or minus print the right hand side */
2445 if (ic->op == '+' || ic->op == '-') {
2446 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2449 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2453 if (ic->op == '+' || ic->op == '-')
2455 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2456 sprintf (s, "(%s %c 0x%04x)",
2457 OP_SYMBOL (IC_LEFT (ric))->rname,
2459 (int) operandLitValue (IC_RIGHT (ic)));
2462 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2464 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2468 /* we reached the end */
2469 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2473 printf ("%s\n", buffer);
2478 /*-----------------------------------------------------------------*/
2479 /* regTypeNum - computes the type & number of registers required */
2480 /*-----------------------------------------------------------------*/
2488 debugLog ("%s\n", __FUNCTION__);
2489 /* for each live range do */
2490 for (sym = hTabFirstItem (liveRanges, &k); sym;
2491 sym = hTabNextItem (liveRanges, &k)) {
2493 debugLog (" %d - %s\n", __LINE__, sym->rname);
2494 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2496 /* if used zero times then no registers needed */
2497 if ((sym->liveTo - sym->liveFrom) == 0)
2501 /* if the live range is a temporary */
2504 debugLog (" %d - itemp register\n", __LINE__);
2506 /* if the type is marked as a conditional */
2507 if (sym->regType == REG_CND)
2510 /* if used in return only then we don't
2512 if (sym->ruonly || sym->accuse) {
2513 if (IS_AGGREGATE (sym->type) || sym->isptr)
2514 sym->type = aggrToPtr (sym->type, FALSE);
2515 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2520 /* if the symbol has only one definition &
2521 that definition is a get_pointer and the
2522 pointer we are getting is rematerializable and
2525 if (bitVectnBitsOn (sym->defs) == 1 &&
2526 (ic = hTabItemWithKey (iCodehTab,
2527 bitVectFirstBit (sym->defs))) &&
2530 !IS_BITVAR (sym->etype)) {
2533 debugLog (" %d - \n", __LINE__);
2535 /* if remat in data space */
2536 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2537 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2539 /* create a psuedo symbol & force a spil */
2540 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2541 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2542 psym->type = sym->type;
2543 psym->etype = sym->etype;
2544 strcpy (psym->rname, psym->name);
2546 sym->usl.spillLoc = psym;
2550 /* if in data space or idata space then try to
2551 allocate pointer register */
2555 /* if not then we require registers */
2556 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2557 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2558 getSize (sym->type));
2562 if(IS_PTR_CONST (sym->type)) {
2564 if(IS_CODEPTR (sym->type)) {
2566 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2570 if (sym->nRegs > 4) {
2571 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2572 printTypeChain (sym->type, stderr);
2573 fprintf (stderr, "\n");
2576 /* determine the type of register required */
2577 if (sym->nRegs == 1 &&
2578 IS_PTR (sym->type) &&
2580 sym->regType = REG_PTR;
2582 sym->regType = REG_GPR;
2585 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2589 /* for the first run we don't provide */
2590 /* registers for true symbols we will */
2591 /* see how things go */
2596 static DEFSETFUNC (markRegFree)
2598 ((regs *)item)->isFree = 1;
2603 DEFSETFUNC (pic16_deallocReg)
2605 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2606 ((regs *)item)->isFree = 1;
2607 ((regs *)item)->wasUsed = 0;
2611 /*-----------------------------------------------------------------*/
2612 /* freeAllRegs - mark all registers as free */
2613 /*-----------------------------------------------------------------*/
2615 pic16_freeAllRegs ()
2617 debugLog ("%s\n", __FUNCTION__);
2619 applyToSet(pic16_dynAllocRegs,markRegFree);
2620 applyToSet(pic16_dynStackRegs,markRegFree);
2623 /*-----------------------------------------------------------------*/
2624 /*-----------------------------------------------------------------*/
2626 pic16_deallocateAllRegs ()
2628 debugLog ("%s\n", __FUNCTION__);
2630 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2634 /*-----------------------------------------------------------------*/
2635 /* deallocStackSpil - this will set the stack pointer back */
2636 /*-----------------------------------------------------------------*/
2638 DEFSETFUNC (deallocStackSpil)
2642 debugLog ("%s\n", __FUNCTION__);
2647 /*-----------------------------------------------------------------*/
2648 /* farSpacePackable - returns the packable icode for far variables */
2649 /*-----------------------------------------------------------------*/
2651 farSpacePackable (iCode * ic)
2655 debugLog ("%s\n", __FUNCTION__);
2656 /* go thru till we find a definition for the
2657 symbol on the right */
2658 for (dic = ic->prev; dic; dic = dic->prev)
2661 /* if the definition is a call then no */
2662 if ((dic->op == CALL || dic->op == PCALL) &&
2663 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2668 /* if shift by unknown amount then not */
2669 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2670 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2673 /* if pointer get and size > 1 */
2674 if (POINTER_GET (dic) &&
2675 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2678 if (POINTER_SET (dic) &&
2679 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2682 /* if any three is a true symbol in far space */
2683 if (IC_RESULT (dic) &&
2684 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2685 isOperandInFarSpace (IC_RESULT (dic)))
2688 if (IC_RIGHT (dic) &&
2689 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2690 isOperandInFarSpace (IC_RIGHT (dic)) &&
2691 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2694 if (IC_LEFT (dic) &&
2695 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2696 isOperandInFarSpace (IC_LEFT (dic)) &&
2697 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2700 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2702 if ((dic->op == LEFT_OP ||
2703 dic->op == RIGHT_OP ||
2705 IS_OP_LITERAL (IC_RIGHT (dic)))
2715 /*-----------------------------------------------------------------*/
2716 /* packRegsForAssign - register reduction for assignment */
2717 /*-----------------------------------------------------------------*/
2719 packRegsForAssign (iCode * ic, eBBlock * ebp)
2724 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2725 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2726 debugAopGet (" result:", IC_RESULT (ic));
2727 debugAopGet (" left:", IC_LEFT (ic));
2728 debugAopGet (" right:", IC_RIGHT (ic));
2730 /* if this is at an absolute address, then get the address. */
2731 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2732 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2733 debugLog (" %d - found config word declaration\n", __LINE__);
2734 if(IS_VALOP(IC_RIGHT(ic))) {
2735 debugLog (" setting config word to %x\n",
2736 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2737 fprintf(stderr, " setting config word to %x\n",
2738 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2739 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2740 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2744 debugLog(" %d\n", __LINE__);
2746 /* remove the assignment from the iCode chain. */
2748 remiCodeFromeBBlock (ebp, ic);
2749 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2750 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2756 debugLog(" %d - actuall processing\n", __LINE__ );
2758 if (!IS_ITEMP (IC_RESULT (ic))) {
2759 pic16_allocDirReg(IC_RESULT (ic));
2760 debugLog (" %d - result is not temp\n", __LINE__);
2764 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2765 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2766 pic16_allocDirReg(IC_LEFT (ic));
2770 /* See BUGLOG0001 - VR */
2772 if (!IS_ITEMP (IC_RIGHT (ic))) {
2773 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2774 pic16_allocDirReg(IC_RIGHT (ic));
2779 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2780 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2782 debugLog (" %d - not packing - right side fails \n", __LINE__);
2786 /* if the true symbol is defined in far space or on stack
2787 then we should not since this will increase register pressure */
2788 if (isOperandInFarSpace (IC_RESULT (ic)))
2790 if ((dic = farSpacePackable (ic)))
2797 /* find the definition of iTempNN scanning backwards if we find a
2798 a use of the true symbol before we find the definition then
2800 for (dic = ic->prev; dic; dic = dic->prev)
2803 /* if there is a function call and this is
2804 a parameter & not my parameter then don't pack it */
2805 if ((dic->op == CALL || dic->op == PCALL) &&
2806 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2807 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2809 debugLog (" %d - \n", __LINE__);
2818 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2821 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2822 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2823 debugAopGet(" result is ", IC_RESULT(dic));
2825 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2826 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2827 debugAopGet(" left is ", IC_LEFT(dic));
2829 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2830 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2831 debugAopGet(" right is ", IC_RIGHT(dic));
2835 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2836 IS_OP_VOLATILE (IC_RESULT (dic)))
2838 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2844 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2845 IS_OP_VOLATILE (IC_RIGHT(dic)))
2847 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2854 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2855 IS_OP_VOLATILE (IC_LEFT(dic)))
2857 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2865 if( IS_SYMOP( IC_RESULT(dic)) &&
2866 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2868 debugLog (" %d - result is bitfield\n", __LINE__);
2874 if (IS_SYMOP (IC_RESULT (dic)) &&
2875 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2877 /* A previous result was assigned to the same register - we'll our definition */
2878 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2879 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2880 if (POINTER_SET (dic))
2886 if (IS_SYMOP (IC_RIGHT (dic)) &&
2887 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2888 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2890 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2895 if (IS_SYMOP (IC_LEFT (dic)) &&
2896 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2897 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2899 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2904 if (POINTER_SET (dic) &&
2905 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2907 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2915 return 0; /* did not find */
2918 /* This code is taken from the hc08 port. Do not know
2919 * if it fits for pic16, but I leave it here just in case */
2921 /* if assignment then check that right is not a bit */
2922 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2923 sym_link *etype = operandType (IC_RIGHT (dic));
2925 if (IS_BITFIELD (etype)) {
2926 /* if result is a bit too then it's ok */
2927 etype = operandType (IC_RESULT (dic));
2928 if (!IS_BITFIELD (etype)) {
2929 debugLog(" %d bitfields\n");
2936 /* if the result is on stack or iaccess then it must be
2937 the same atleast one of the operands */
2938 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2939 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2942 /* the operation has only one symbol
2943 operator then we can pack */
2944 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2945 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2948 if (!((IC_LEFT (dic) &&
2949 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2951 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2955 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2956 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2957 /* found the definition */
2958 /* replace the result with the result of */
2959 /* this assignment and remove this assignment */
2960 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2961 IC_RESULT (dic) = IC_RESULT (ic);
2963 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2965 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2967 /* delete from liverange table also
2968 delete from all the points inbetween and the new
2970 for (sic = dic; sic != ic; sic = sic->next)
2972 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2973 if (IS_ITEMP (IC_RESULT (dic)))
2974 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2977 remiCodeFromeBBlock (ebp, ic);
2978 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2980 debugLog(" %d\n", __LINE__ );
2981 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2982 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2988 /*-----------------------------------------------------------------*/
2989 /* findAssignToSym : scanning backwards looks for first assig found */
2990 /*-----------------------------------------------------------------*/
2992 findAssignToSym (operand * op, iCode * ic)
2996 debugLog ("%s\n", __FUNCTION__);
2997 for (dic = ic->prev; dic; dic = dic->prev)
3000 /* if definition by assignment */
3001 if (dic->op == '=' &&
3002 !POINTER_SET (dic) &&
3003 IC_RESULT (dic)->key == op->key
3004 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3008 /* we are interested only if defined in far space */
3009 /* or in stack space in case of + & - */
3011 /* if assigned to a non-symbol then return
3013 if (!IS_SYMOP (IC_RIGHT (dic)))
3016 /* if the symbol is in far space then
3018 if (isOperandInFarSpace (IC_RIGHT (dic)))
3021 /* for + & - operations make sure that
3022 if it is on the stack it is the same
3023 as one of the three operands */
3024 if ((ic->op == '+' || ic->op == '-') &&
3025 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3028 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3029 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3030 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3038 /* if we find an usage then we cannot delete it */
3039 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3042 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3045 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3049 /* now make sure that the right side of dic
3050 is not defined between ic & dic */
3053 iCode *sic = dic->next;
3055 for (; sic != ic; sic = sic->next)
3056 if (IC_RESULT (sic) &&
3057 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3066 /*-----------------------------------------------------------------*/
3067 /* packRegsForSupport :- reduce some registers for support calls */
3068 /*-----------------------------------------------------------------*/
3070 packRegsForSupport (iCode * ic, eBBlock * ebp)
3074 debugLog ("%s\n", __FUNCTION__);
3075 /* for the left & right operand :- look to see if the
3076 left was assigned a true symbol in far space in that
3077 case replace them */
3078 if (IS_ITEMP (IC_LEFT (ic)) &&
3079 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3081 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3087 debugAopGet ("removing left:", IC_LEFT (ic));
3089 /* found it we need to remove it from the
3091 for (sic = dic; sic != ic; sic = sic->next)
3092 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3094 IC_LEFT (ic)->operand.symOperand =
3095 IC_RIGHT (dic)->operand.symOperand;
3096 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3097 remiCodeFromeBBlock (ebp, dic);
3098 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3099 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3103 /* do the same for the right operand */
3106 IS_ITEMP (IC_RIGHT (ic)) &&
3107 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3109 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3115 /* if this is a subtraction & the result
3116 is a true symbol in far space then don't pack */
3117 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3119 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3120 if (IN_FARSPACE (SPEC_OCLS (etype)))
3124 debugAopGet ("removing right:", IC_RIGHT (ic));
3126 /* found it we need to remove it from the
3128 for (sic = dic; sic != ic; sic = sic->next)
3129 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3131 IC_RIGHT (ic)->operand.symOperand =
3132 IC_RIGHT (dic)->operand.symOperand;
3133 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3135 remiCodeFromeBBlock (ebp, dic);
3136 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3137 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3144 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3147 /*-----------------------------------------------------------------*/
3148 /* packRegsForOneuse : - will reduce some registers for single Use */
3149 /*-----------------------------------------------------------------*/
3151 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3156 debugLog ("%s\n", __FUNCTION__);
3157 /* if returning a literal then do nothing */
3161 /* only upto 2 bytes since we cannot predict
3162 the usage of b, & acc */
3163 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3168 /* this routine will mark the a symbol as used in one
3169 instruction use only && if the definition is local
3170 (ie. within the basic block) && has only one definition &&
3171 that definition is either a return value from a
3172 function or does not contain any variables in
3174 uses = bitVectCopy (OP_USES (op));
3175 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3176 if (!bitVectIsZero (uses)) /* has other uses */
3179 /* if it has only one defintion */
3180 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3181 return NULL; /* has more than one definition */
3183 /* get that definition */
3185 hTabItemWithKey (iCodehTab,
3186 bitVectFirstBit (OP_DEFS (op)))))
3189 /* found the definition now check if it is local */
3190 if (dic->seq < ebp->fSeq ||
3191 dic->seq > ebp->lSeq)
3192 return NULL; /* non-local */
3194 /* now check if it is the return from
3196 if (dic->op == CALL || dic->op == PCALL)
3198 if (ic->op != SEND && ic->op != RETURN &&
3199 !POINTER_SET(ic) && !POINTER_GET(ic))
3201 OP_SYMBOL (op)->ruonly = 1;
3208 /* otherwise check that the definition does
3209 not contain any symbols in far space */
3210 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3211 isOperandInFarSpace (IC_RIGHT (dic)) ||
3212 IS_OP_RUONLY (IC_LEFT (ic)) ||
3213 IS_OP_RUONLY (IC_RIGHT (ic)))
3218 /* if pointer set then make sure the pointer
3220 if (POINTER_SET (dic) &&
3221 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3224 if (POINTER_GET (dic) &&
3225 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3230 /* also make sure the intervenening instructions
3231 don't have any thing in far space */
3232 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3235 /* if there is an intervening function call then no */
3236 if (dic->op == CALL || dic->op == PCALL)
3238 /* if pointer set then make sure the pointer
3240 if (POINTER_SET (dic) &&
3241 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3244 if (POINTER_GET (dic) &&
3245 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3248 /* if address of & the result is remat then okay */
3249 if (dic->op == ADDRESS_OF &&
3250 OP_SYMBOL (IC_RESULT (dic))->remat)
3253 /* if operand has size of three or more & this
3254 operation is a '*','/' or '%' then 'b' may
3256 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3257 getSize (operandType (op)) >= 3)
3260 /* if left or right or result is in far space */
3261 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3262 isOperandInFarSpace (IC_RIGHT (dic)) ||
3263 isOperandInFarSpace (IC_RESULT (dic)) ||
3264 IS_OP_RUONLY (IC_LEFT (dic)) ||
3265 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3266 IS_OP_RUONLY (IC_RESULT (dic)))
3272 OP_SYMBOL (op)->ruonly = 1;
3277 /*-----------------------------------------------------------------*/
3278 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3279 /*-----------------------------------------------------------------*/
3281 isBitwiseOptimizable (iCode * ic)
3283 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3284 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3286 debugLog ("%s\n", __FUNCTION__);
3287 /* bitwise operations are considered optimizable
3288 under the following conditions (Jean-Louis VERN)
3300 if (IS_LITERAL (rtype) ||
3301 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3307 /*-----------------------------------------------------------------*/
3308 /* packRegsForAccUse - pack registers for acc use */
3309 /*-----------------------------------------------------------------*/
3311 packRegsForAccUse (iCode * ic)
3315 debugLog ("%s\n", __FUNCTION__);
3317 /* if this is an aggregate, e.g. a one byte char array */
3318 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3321 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3323 /* if + or - then it has to be one byte result */
3324 if ((ic->op == '+' || ic->op == '-')
3325 && getSize (operandType (IC_RESULT (ic))) > 1)
3328 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3329 /* if shift operation make sure right side is not a literal */
3330 if (ic->op == RIGHT_OP &&
3331 (isOperandLiteral (IC_RIGHT (ic)) ||
3332 getSize (operandType (IC_RESULT (ic))) > 1))
3335 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3336 if (ic->op == LEFT_OP &&
3337 (isOperandLiteral (IC_RIGHT (ic)) ||
3338 getSize (operandType (IC_RESULT (ic))) > 1))
3341 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3342 if (IS_BITWISE_OP (ic) &&
3343 getSize (operandType (IC_RESULT (ic))) > 1)
3347 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3348 /* has only one definition */
3349 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3352 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3353 /* has only one use */
3354 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3357 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3358 /* and the usage immediately follows this iCode */
3359 if (!(uic = hTabItemWithKey (iCodehTab,
3360 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3363 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3364 if (ic->next != uic)
3367 /* if it is a conditional branch then we definitely can */
3371 if (uic->op == JUMPTABLE)
3374 /* if the usage is not is an assignment
3375 or an arithmetic / bitwise / shift operation then not */
3376 if (POINTER_SET (uic) &&
3377 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3380 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3381 if (uic->op != '=' &&
3382 !IS_ARITHMETIC_OP (uic) &&
3383 !IS_BITWISE_OP (uic) &&
3384 uic->op != LEFT_OP &&
3385 uic->op != RIGHT_OP)
3388 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3389 /* if used in ^ operation then make sure right is not a
3391 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3394 /* if shift operation make sure right side is not a literal */
3395 if (uic->op == RIGHT_OP &&
3396 (isOperandLiteral (IC_RIGHT (uic)) ||
3397 getSize (operandType (IC_RESULT (uic))) > 1))
3400 if (uic->op == LEFT_OP &&
3401 (isOperandLiteral (IC_RIGHT (uic)) ||
3402 getSize (operandType (IC_RESULT (uic))) > 1))
3405 /* make sure that the result of this icode is not on the
3406 stack, since acc is used to compute stack offset */
3407 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3408 OP_SYMBOL (IC_RESULT (uic))->onStack)
3411 /* if either one of them in far space then we cannot */
3412 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3413 isOperandInFarSpace (IC_LEFT (uic))) ||
3414 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3415 isOperandInFarSpace (IC_RIGHT (uic))))
3418 /* if the usage has only one operand then we can */
3419 if (IC_LEFT (uic) == NULL ||
3420 IC_RIGHT (uic) == NULL)
3423 /* make sure this is on the left side if not
3424 a '+' since '+' is commutative */
3425 if (ic->op != '+' &&
3426 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3430 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3431 /* if one of them is a literal then we can */
3432 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3433 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3434 (getSize (operandType (IC_RESULT (uic))) <= 1))
3436 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3441 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3442 /* if the other one is not on stack then we can */
3443 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3444 (IS_ITEMP (IC_RIGHT (uic)) ||
3445 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3446 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3449 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3450 (IS_ITEMP (IC_LEFT (uic)) ||
3451 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3452 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3458 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3459 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3464 /*-----------------------------------------------------------------*/
3465 /* packForPush - hueristics to reduce iCode for pushing */
3466 /*-----------------------------------------------------------------*/
3468 packForReceive (iCode * ic, eBBlock * ebp)
3472 debugLog ("%s\n", __FUNCTION__);
3473 debugAopGet (" result:", IC_RESULT (ic));
3474 debugAopGet (" left:", IC_LEFT (ic));
3475 debugAopGet (" right:", IC_RIGHT (ic));
3480 for (dic = ic->next; dic; dic = dic->next)
3485 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3486 debugLog (" used on left\n");
3487 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3488 debugLog (" used on right\n");
3489 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3490 debugLog (" used on result\n");
3492 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3493 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3498 debugLog (" hey we can remove this unnecessary assign\n");
3500 /*-----------------------------------------------------------------*/
3501 /* packForPush - hueristics to reduce iCode for pushing */
3502 /*-----------------------------------------------------------------*/
3504 packForPush (iCode * ic, eBBlock * ebp)
3508 debugLog ("%s\n", __FUNCTION__);
3509 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3512 /* must have only definition & one usage */
3513 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3514 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3517 /* find the definition */
3518 if (!(dic = hTabItemWithKey (iCodehTab,
3519 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3522 if (dic->op != '=' || POINTER_SET (dic))
3525 /* we now we know that it has one & only one def & use
3526 and the that the definition is an assignment */
3527 IC_LEFT (ic) = IC_RIGHT (dic);
3529 remiCodeFromeBBlock (ebp, dic);
3530 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3531 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3534 static void printSymType(char * str, sym_link *sl)
3536 if(!pic16_ralloc_debug)return;
3538 debugLog (" %s Symbol type: ",str);
3539 printTypeChain( sl, debugF);
3543 /*-----------------------------------------------------------------*/
3544 /* some debug code to print the symbol S_TYPE. Note that
3545 * the function checkSClass in src/SDCCsymt.c dinks with
3546 * the S_TYPE in ways the PIC port doesn't fully like...*/
3547 /*-----------------------------------------------------------------*/
3548 static void isData(sym_link *sl)
3552 if(!pic16_ralloc_debug)return;
3559 for ( ; sl; sl=sl->next) {
3561 switch (SPEC_SCLS(sl)) {
3562 case S_DATA: fprintf (of, "data "); break;
3563 case S_XDATA: fprintf (of, "xdata "); break;
3564 case S_SFR: fprintf (of, "sfr "); break;
3565 case S_SBIT: fprintf (of, "sbit "); break;
3566 case S_CODE: fprintf (of, "code "); break;
3567 case S_IDATA: fprintf (of, "idata "); break;
3568 case S_PDATA: fprintf (of, "pdata "); break;
3569 case S_LITERAL: fprintf (of, "literal "); break;
3570 case S_STACK: fprintf (of, "stack "); break;
3571 case S_XSTACK: fprintf (of, "xstack "); break;
3572 case S_BIT: fprintf (of, "bit "); break;
3573 case S_EEPROM: fprintf (of, "eeprom "); break;
3582 /* set if conditional to 1 to disable optimizations */
3584 #define NO_packRegsForAccUse
3586 #define NO_packRegsForSupport
3587 #define NO_packRegsForOneuse
3588 //#define NO_cast_peep
3590 /*--------------------------------------------------------------------*/
3591 /* pic16_packRegisters - does some transformations to reduce */
3592 /* register pressure */
3594 /*--------------------------------------------------------------------*/
3596 pic16_packRegisters (eBBlock * ebp)
3601 debugLog ("%s\n", __FUNCTION__);
3607 /* look for assignments of the form */
3608 /* iTempNN = TRueSym (someoperation) SomeOperand */
3610 /* TrueSym := iTempNN:1 */
3611 for (ic = ebp->sch; ic; ic = ic->next)
3613 // debugLog("%d\n", __LINE__);
3614 /* find assignment of the form TrueSym := iTempNN:1 */
3615 /* see BUGLOG0001 for workaround with the CAST - VR */
3616 if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3617 change += packRegsForAssign (ic, ebp);
3621 if (POINTER_SET (ic))
3622 debugLog ("pointer is set\n");
3623 debugAopGet (" result:", IC_RESULT (ic));
3624 debugAopGet (" left:", IC_LEFT (ic));
3625 debugAopGet (" right:", IC_RIGHT (ic));
3634 for (ic = ebp->sch; ic; ic = ic->next) {
3636 if(IS_SYMOP ( IC_LEFT(ic))) {
3637 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3639 debugAopGet ("x left:", IC_LEFT (ic));
3641 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3643 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3645 debugLog (" is a pointer\n");
3647 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3648 debugLog (" is a ptr\n");
3650 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3651 debugLog (" is volatile\n");
3655 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3656 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3657 pic16_allocDirReg(IC_LEFT (ic));
3660 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3663 if(IS_SYMOP ( IC_RIGHT(ic))) {
3664 debugAopGet (" right:", IC_RIGHT (ic));
3665 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3668 if(IS_SYMOP ( IC_RESULT(ic))) {
3669 debugAopGet (" result:", IC_RESULT (ic));
3670 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3673 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3674 debugAopGet (" right:", IC_RIGHT (ic));
3675 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3676 // pic16_allocDirReg(IC_RIGHT(ic));
3679 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3680 debugAopGet (" result:", IC_RESULT (ic));
3681 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3682 // pic16_allocDirReg(IC_RESULT(ic));
3686 if (POINTER_SET (ic))
3687 debugLog (" %d - Pointer set\n", __LINE__);
3690 /* if this is an itemp & result of a address of a true sym
3691 then mark this as rematerialisable */
3692 if (ic->op == ADDRESS_OF &&
3693 IS_ITEMP (IC_RESULT (ic)) &&
3694 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3695 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3696 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3699 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3701 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3702 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3703 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3707 /* if straight assignment then carry remat flag if
3708 this is the only definition */
3709 if (ic->op == '=' &&
3710 !POINTER_SET (ic) &&
3711 IS_SYMOP (IC_RIGHT (ic)) &&
3712 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3713 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3715 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3717 OP_SYMBOL (IC_RESULT (ic))->remat =
3718 OP_SYMBOL (IC_RIGHT (ic))->remat;
3719 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3720 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3723 /* if this is a +/- operation with a rematerizable
3724 then mark this as rematerializable as well */
3725 if ((ic->op == '+' || ic->op == '-') &&
3726 (IS_SYMOP (IC_LEFT (ic)) &&
3727 IS_ITEMP (IC_RESULT (ic)) &&
3728 OP_SYMBOL (IC_LEFT (ic))->remat &&
3729 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3730 IS_OP_LITERAL (IC_RIGHT (ic))))
3732 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3734 operandLitValue (IC_RIGHT (ic));
3735 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3736 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3737 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3740 /* mark the pointer usages */
3741 if (POINTER_SET (ic))
3743 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3744 debugLog (" marking as a pointer (set) =>");
3745 debugAopGet (" result:", IC_RESULT (ic));
3747 if (POINTER_GET (ic))
3749 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3750 debugLog (" marking as a pointer (get) =>");
3751 debugAopGet (" left:", IC_LEFT (ic));
3754 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3758 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3759 /* if we are using a symbol on the stack
3760 then we should say pic16_ptrRegReq */
3761 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3762 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3763 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3764 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3765 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3766 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3770 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3771 if (IS_SYMOP (IC_LEFT (ic)))
3772 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3773 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3774 if (IS_SYMOP (IC_RIGHT (ic)))
3775 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3776 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3777 if (IS_SYMOP (IC_RESULT (ic)))
3778 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3779 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3782 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3786 /* if the condition of an if instruction
3787 is defined in the previous instruction then
3788 mark the itemp as a conditional */
3789 if ((IS_CONDITIONAL (ic) ||
3790 ((ic->op == BITWISEAND ||
3793 isBitwiseOptimizable (ic))) &&
3794 ic->next && ic->next->op == IFX &&
3795 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3796 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3799 debugLog (" %d\n", __LINE__);
3800 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3804 debugLog(" %d\n", __LINE__);
3806 #ifndef NO_packRegsForSupport
3807 /* reduce for support function calls */
3808 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3809 packRegsForSupport (ic, ebp);
3812 /* if a parameter is passed, it's in W, so we may not
3813 need to place a copy in a register */
3814 if (ic->op == RECEIVE)
3815 packForReceive (ic, ebp);
3817 #ifndef NO_packRegsForOneuse
3818 /* some cases the redundant moves can
3819 can be eliminated for return statements */
3820 if ((ic->op == RETURN || ic->op == SEND) &&
3821 !isOperandInFarSpace (IC_LEFT (ic)) &&
3823 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3826 #ifndef NO_packRegsForOneuse
3827 /* if pointer set & left has a size more than
3828 one and right is not in far space */
3829 if (POINTER_SET (ic) &&
3830 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3831 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3832 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3833 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3835 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3838 #ifndef NO_packRegsForOneuse
3839 /* if pointer get */
3840 if (POINTER_GET (ic) &&
3841 !isOperandInFarSpace (IC_RESULT (ic)) &&
3842 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3843 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3844 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3846 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3847 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3850 #ifndef NO_cast_peep
3851 /* if this is cast for intergral promotion then
3852 check if only use of the definition of the
3853 operand being casted/ if yes then replace
3854 the result of that arithmetic operation with
3855 this result and get rid of the cast */
3856 if (ic->op == CAST) {
3858 sym_link *fromType = operandType (IC_RIGHT (ic));
3859 sym_link *toType = operandType (IC_LEFT (ic));
3861 debugLog (" %d - casting\n", __LINE__);
3863 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3864 getSize (fromType) != getSize (toType)) {
3867 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3870 if (IS_ARITHMETIC_OP (dic)) {
3871 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3873 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3874 IC_RESULT (dic) = IC_RESULT (ic);
3875 remiCodeFromeBBlock (ebp, ic);
3876 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3877 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3878 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3882 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3886 /* if the type from and type to are the same
3887 then if this is the only use then packit */
3888 if (compareType (operandType (IC_RIGHT (ic)),
3889 operandType (IC_LEFT (ic))) == 1) {
3891 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3894 debugLog(" %d\n", __LINE__);
3896 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3897 IC_RESULT (dic) = IC_RESULT (ic);
3898 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3899 remiCodeFromeBBlock (ebp, ic);
3900 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3901 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3909 iTempNN := (some variable in farspace) V1
3914 if (ic->op == IPUSH)
3916 packForPush (ic, ebp);
3920 #ifndef NO_packRegsForAccUse
3921 /* pack registers for accumulator use, when the
3922 result of an arithmetic or bit wise operation
3923 has only one use, that use is immediately following
3924 the defintion and the using iCode has only one
3925 operand or has two operands but one is literal &
3926 the result of that operation is not on stack then
3927 we can leave the result of this operation in acc:b
3929 if ((IS_ARITHMETIC_OP (ic)
3931 || IS_BITWISE_OP (ic)
3933 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3936 IS_ITEMP (IC_RESULT (ic)) &&
3937 getSize (operandType (IC_RESULT (ic))) <= 1)
3939 packRegsForAccUse (ic);
3946 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3950 if (!pic16_ralloc_debug || !debugF)
3953 for (i = 0; i < count; i++)
3955 fprintf (debugF, "\n----------------------------------------------------------------\n");
3956 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3957 ebbs[i]->entryLabel->name,
3960 ebbs[i]->isLastInLoop);
3961 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3966 fprintf (debugF, "visited %d : hasFcall = %d\n",
3970 fprintf (debugF, "\ndefines bitVector :");
3971 bitVectDebugOn (ebbs[i]->defSet, debugF);
3972 fprintf (debugF, "\nlocal defines bitVector :");
3973 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3974 fprintf (debugF, "\npointers Set bitvector :");
3975 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3976 fprintf (debugF, "\nin pointers Set bitvector :");
3977 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3978 fprintf (debugF, "\ninDefs Set bitvector :");
3979 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3980 fprintf (debugF, "\noutDefs Set bitvector :");
3981 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3982 fprintf (debugF, "\nusesDefs Set bitvector :");
3983 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3984 fprintf (debugF, "\n----------------------------------------------------------------\n");
3985 printiCChain (ebbs[i]->sch, debugF);
3988 /*-----------------------------------------------------------------*/
3989 /* pic16_assignRegisters - assigns registers to each live range as need */
3990 /*-----------------------------------------------------------------*/
3992 pic16_assignRegisters (eBBlock ** ebbs, int count)
3997 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3998 debugLog ("\nebbs before optimizing:\n");
3999 dumpEbbsToDebug (ebbs, count);
4001 setToNull ((void *) &_G.funcrUsed);
4002 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4005 /* change assignments this will remove some
4006 live ranges reducing some register pressure */
4007 for (i = 0; i < count; i++)
4008 pic16_packRegisters (ebbs[i]);
4015 debugLog("dir registers allocated so far:\n");
4016 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4019 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4020 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4021 reg = hTabNextItem(dynDirectRegNames, &hkey);
4026 /* liveranges probably changed by register packing
4027 so we compute them again */
4028 recomputeLiveRanges (ebbs, count);
4030 if (options.dump_pack)
4031 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4033 /* first determine for each live range the number of
4034 registers & the type of registers required for each */
4037 /* and serially allocate registers */
4038 serialRegAssign (ebbs, count);
4040 //pic16_freeAllRegs();
4042 /* if stack was extended then tell the user */
4045 /* werror(W_TOOMANY_SPILS,"stack", */
4046 /* _G.stackExtend,currFunc->name,""); */
4052 /* werror(W_TOOMANY_SPILS,"data space", */
4053 /* _G.dataExtend,currFunc->name,""); */
4057 /* after that create the register mask
4058 for each of the instruction */
4059 createRegMask (ebbs, count);
4061 /* redo that offsets for stacked automatic variables */
4062 redoStackOffsets ();
4064 if (options.dump_rassgn)
4065 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4067 /* now get back the chain */
4068 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4070 debugLog ("ebbs after optimizing:\n");
4071 dumpEbbsToDebug (ebbs, count);
4076 /* free up any _G.stackSpil locations allocated */
4077 applyToSet (_G.stackSpil, deallocStackSpil);
4079 setToNull ((void *) &_G.stackSpil);
4080 setToNull ((void *) &_G.spiltSet);
4081 /* mark all registers as free */
4082 pic16_freeAllRegs ();
4084 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");