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 static regs *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;
82 set *pic16_fix_udata=NULL;
83 set *pic16_equ_data=NULL;
85 set *pic16_builtin_functions=NULL;
87 static int dynrIdx=0x10; //0x20; // starting temporary register rIdx
88 static int rDirectIdx=0;
90 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
92 int pic16_Gstack_base_addr=0; /* The starting address of registers that
93 * are used to pass and return parameters */
98 static void spillThis (symbol *);
99 int pic16_ralloc_debug = 0;
100 static FILE *debugF = NULL;
101 /*-----------------------------------------------------------------*/
102 /* debugLog - open a file for debugging information */
103 /*-----------------------------------------------------------------*/
104 //static void debugLog(char *inst,char *fmt, ...)
106 debugLog (char *fmt,...)
108 static int append = 0; // First time through, open the file without append.
111 //char *bufferP=buffer;
114 if (!pic16_ralloc_debug || !dstFileName)
120 /* create the file name */
121 strcpy (buffer, dstFileName);
122 strcat (buffer, ".d");
124 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
126 werror (E_FILE_OPEN_ERR, buffer);
129 append = 1; // Next time debubLog is called, we'll append the debug info
135 vsprintf (buffer, fmt, ap);
137 fprintf (debugF, "%s", buffer);
139 while (isspace(*bufferP)) bufferP++;
141 if (bufferP && *bufferP)
142 lineCurr = (lineCurr ?
143 connectLine(lineCurr,newLineNode(lb)) :
144 (lineHead = newLineNode(lb)));
145 lineCurr->isInline = _G.inLine;
146 lineCurr->isDebug = _G.debugLine;
155 if(!pic16_ralloc_debug)return;
158 fputc ('\n', debugF);
160 /*-----------------------------------------------------------------*/
161 /* debugLogClose - closes the debug log file (if opened) */
162 /*-----------------------------------------------------------------*/
172 #define AOP(op) op->aop
175 debugAopGet (char *str, operand * op)
177 if(!pic16_ralloc_debug)return NULL;
182 printOperand (op, debugF);
189 decodeOp (unsigned int op)
191 if (op < 128 && op > ' ') {
192 buffer[0] = (op & 0xff);
198 case IDENTIFIER: return "IDENTIFIER";
199 case TYPE_NAME: return "TYPE_NAME";
200 case CONSTANT: return "CONSTANT";
201 case STRING_LITERAL: return "STRING_LITERAL";
202 case SIZEOF: return "SIZEOF";
203 case PTR_OP: return "PTR_OP";
204 case INC_OP: return "INC_OP";
205 case DEC_OP: return "DEC_OP";
206 case LEFT_OP: return "LEFT_OP";
207 case RIGHT_OP: return "RIGHT_OP";
208 case LE_OP: return "LE_OP";
209 case GE_OP: return "GE_OP";
210 case EQ_OP: return "EQ_OP";
211 case NE_OP: return "NE_OP";
212 case AND_OP: return "AND_OP";
213 case OR_OP: return "OR_OP";
214 case MUL_ASSIGN: return "MUL_ASSIGN";
215 case DIV_ASSIGN: return "DIV_ASSIGN";
216 case MOD_ASSIGN: return "MOD_ASSIGN";
217 case ADD_ASSIGN: return "ADD_ASSIGN";
218 case SUB_ASSIGN: return "SUB_ASSIGN";
219 case LEFT_ASSIGN: return "LEFT_ASSIGN";
220 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
221 case AND_ASSIGN: return "AND_ASSIGN";
222 case XOR_ASSIGN: return "XOR_ASSIGN";
223 case OR_ASSIGN: return "OR_ASSIGN";
224 case TYPEDEF: return "TYPEDEF";
225 case EXTERN: return "EXTERN";
226 case STATIC: return "STATIC";
227 case AUTO: return "AUTO";
228 case REGISTER: return "REGISTER";
229 case CODE: return "CODE";
230 case EEPROM: return "EEPROM";
231 case INTERRUPT: return "INTERRUPT";
232 case SFR: return "SFR";
233 case AT: return "AT";
234 case SBIT: return "SBIT";
235 case REENTRANT: return "REENTRANT";
236 case USING: return "USING";
237 case XDATA: return "XDATA";
238 case DATA: return "DATA";
239 case IDATA: return "IDATA";
240 case PDATA: return "PDATA";
241 case VAR_ARGS: return "VAR_ARGS";
242 case CRITICAL: return "CRITICAL";
243 case NONBANKED: return "NONBANKED";
244 case BANKED: return "BANKED";
245 case CHAR: return "CHAR";
246 case SHORT: return "SHORT";
247 case INT: return "INT";
248 case LONG: return "LONG";
249 case SIGNED: return "SIGNED";
250 case UNSIGNED: return "UNSIGNED";
251 case FLOAT: return "FLOAT";
252 case DOUBLE: return "DOUBLE";
253 case CONST: return "CONST";
254 case VOLATILE: return "VOLATILE";
255 case VOID: return "VOID";
256 case BIT: return "BIT";
257 case STRUCT: return "STRUCT";
258 case UNION: return "UNION";
259 case ENUM: return "ENUM";
260 case ELIPSIS: return "ELIPSIS";
261 case RANGE: return "RANGE";
262 case FAR: return "FAR";
263 case CASE: return "CASE";
264 case DEFAULT: return "DEFAULT";
265 case IF: return "IF";
266 case ELSE: return "ELSE";
267 case SWITCH: return "SWITCH";
268 case WHILE: return "WHILE";
269 case DO: return "DO";
270 case FOR: return "FOR";
271 case GOTO: return "GOTO";
272 case CONTINUE: return "CONTINUE";
273 case BREAK: return "BREAK";
274 case RETURN: return "RETURN";
275 case INLINEASM: return "INLINEASM";
276 case IFX: return "IFX";
277 case ADDRESS_OF: return "ADDRESS_OF";
278 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
279 case SPIL: return "SPIL";
280 case UNSPIL: return "UNSPIL";
281 case GETHBIT: return "GETHBIT";
282 case BITWISEAND: return "BITWISEAND";
283 case UNARYMINUS: return "UNARYMINUS";
284 case IPUSH: return "IPUSH";
285 case IPOP: return "IPOP";
286 case PCALL: return "PCALL";
287 case ENDFUNCTION: return "ENDFUNCTION";
288 case JUMPTABLE: return "JUMPTABLE";
289 case RRC: return "RRC";
290 case RLC: return "RLC";
291 case CAST: return "CAST";
292 case CALL: return "CALL";
293 case PARAM: return "PARAM ";
294 case NULLOP: return "NULLOP";
295 case BLOCK: return "BLOCK";
296 case LABEL: return "LABEL";
297 case RECEIVE: return "RECEIVE";
298 case SEND: return "SEND";
300 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
304 /*-----------------------------------------------------------------*/
305 /*-----------------------------------------------------------------*/
307 debugLogRegType (short type)
309 if(!pic16_ralloc_debug)return NULL;
311 case REG_GPR: return "REG_GPR";
312 case REG_PTR: return "REG_PTR";
313 case REG_CND: return "REG_CND";
315 sprintf (buffer, "unknown reg type %d", type);
320 /*-----------------------------------------------------------------*/
321 /*-----------------------------------------------------------------*/
322 static int regname2key(char const *name)
331 key += (*name++) + 1;
335 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
339 /*-----------------------------------------------------------------*/
340 /* newReg - allocate and init memory for a new register */
341 /*-----------------------------------------------------------------*/
342 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
347 dReg = Safe_calloc(1,sizeof(regs));
349 dReg->pc_type = pc_type;
352 dReg->name = Safe_strdup(name);
354 sprintf(buffer,"r0x%02X", dReg->rIdx);
357 dReg->name = Safe_strdup(buffer);
364 // dReg->isMapped = 0;
367 if(type == REG_SFR) {
369 dReg->address = rIdx;
370 dReg->accessBank = 1;
374 dReg->accessBank = 0;
377 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\n",dReg->name,rIdx, dReg->accessBank);
381 dReg->reg_alias = NULL;
382 dReg->reglives.usedpFlows = newSet();
383 dReg->reglives.assignedpFlows = newSet();
386 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
391 /*-----------------------------------------------------------------*/
392 /* regWithIdx - Search through a set of registers that matches idx */
393 /*-----------------------------------------------------------------*/
395 regWithIdx (set *dRegs, int idx, int fixed)
399 for (dReg = setFirstItem(dRegs) ; dReg ;
400 dReg = setNextItem(dRegs)) {
402 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
410 /*-----------------------------------------------------------------*/
411 /* regFindFree - Search for a free register in a set of registers */
412 /*-----------------------------------------------------------------*/
414 regFindFree (set *dRegs)
418 for (dReg = setFirstItem(dRegs) ; dReg ;
419 dReg = setNextItem(dRegs)) {
421 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
422 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
431 /*-----------------------------------------------------------------*/
432 /* pic16_initStack - allocate registers for a pseudo stack */
433 /*-----------------------------------------------------------------*/
434 void pic16_initStack(int base_address, int size)
439 pic16_Gstack_base_addr = base_address;
440 //fprintf(stderr,"initStack");
442 for(i = 0; i<size; i++)
443 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
446 /*-----------------------------------------------------------------*
447 *-----------------------------------------------------------------*/
449 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
451 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
453 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
455 reg->wasUsed = 0; // we do not know if they are going to be used at all
456 reg->accessBank = 1; // implicit add access Bank
458 return addSet(&pic16_dynProcessorRegs, reg);
461 /*-----------------------------------------------------------------*
462 *-----------------------------------------------------------------*/
465 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
467 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
469 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
473 return addSet(&pic16_dynInternalRegs,reg);
478 /*-----------------------------------------------------------------*/
479 /* allocReg - allocates register of given type */
480 /*-----------------------------------------------------------------*/
482 allocReg (short type)
487 if(dynrIdx > pic16_nRegs)
493 /* try to reuse some unused registers */
494 reg = regFindFree( pic16_dynAllocRegs );
499 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
500 addSet(&pic16_dynAllocRegs, reg);
504 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
506 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
507 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
510 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
511 reg->isLocal = 1; /* this is a local frame register */
516 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
519 return (reg); // addSet(&pic16_dynAllocRegs,reg);
524 /*-----------------------------------------------------------------*/
525 /* pic16_dirregWithName - search for register by name */
526 /*-----------------------------------------------------------------*/
528 pic16_dirregWithName (char *name)
536 /* hash the name to get a key */
538 hkey = regname2key(name);
540 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
542 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
546 if(STRCASECMP(reg->name, name) == 0) {
550 reg = hTabNextItemWK (dynDirectRegNames);
554 return NULL; // name wasn't found in the hash table
557 static int IS_CONFIG_ADDRESS(int address)
560 return address >= 0x300000 && address <= 0x300000d;
563 /*-----------------------------------------------------------------*/
564 /* pic16_allocDirReg - allocates register of given type */
565 /*-----------------------------------------------------------------*/
567 pic16_allocDirReg (operand *op )
573 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
577 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
579 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
580 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
583 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
584 debugLog(" %d const char\n",__LINE__);
585 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
586 // fprintf(stderr, " %d const char\n",__LINE__);
587 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
591 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
592 if (IS_CODE ( OP_SYM_ETYPE(op)) )
593 debugLog(" %d code space\n",__LINE__);
595 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
596 debugLog(" %d integral\n",__LINE__);
598 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
599 debugLog(" %d literal\n",__LINE__);
601 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
602 debugLog(" %d specifier\n",__LINE__);
604 debugAopGet(NULL, op);
607 if (IS_CODE ( OP_SYM_ETYPE(op)) )
610 /* First, search the hash table to see if there is a register with this name */
611 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
613 // reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
617 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
618 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
620 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
621 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
624 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
626 reg = pic16_dirregWithName(name);
631 int regtype = REG_GPR;
633 /* if this is at an absolute address, then get the address. */
634 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
635 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
636 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
639 /* Register wasn't found in hash, so let's create
640 * a new one and put it in the hash table AND in the
641 * dynDirectRegNames set */
642 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
643 if(pic16_debug_verbose)
644 fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
645 OP_SYMBOL(op)->name);
649 if(!IS_CONFIG_ADDRESS(address)) {
650 // fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
652 if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
654 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
655 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
657 // hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
659 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
660 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
661 // reg->type = REG_SFR;
664 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
665 addSet(&pic16_dynDirectBitRegs, reg);
668 addSet(&pic16_dynDirectRegs, reg);
671 debugLog (" -- %s is declared at address 0x30000x\n",name);
672 fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
678 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
680 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
681 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
687 /*-----------------------------------------------------------------*/
688 /* pic16_allocRegByName - allocates register of given type */
689 /*-----------------------------------------------------------------*/
691 pic16_allocRegByName (char *name, int size)
697 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
701 /* First, search the hash table to see if there is a register with this name */
702 reg = pic16_dirregWithName(name);
706 /* Register wasn't found in hash, so let's create
707 * a new one and put it in the hash table AND in the
708 * dynDirectRegNames set */
709 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
710 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
712 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
713 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
715 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
716 addSet(&pic16_dynDirectRegs, reg);
722 /*-----------------------------------------------------------------*/
723 /* RegWithIdx - returns pointer to register with index number */
724 /*-----------------------------------------------------------------*/
726 typeRegWithIdx (int idx, int type, int fixed)
731 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
736 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
738 debugLog ("Found a Dynamic Register!\n");
741 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
742 debugLog ("Found a Direct Register!\n");
748 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
749 debugLog ("Found a Stack Register!\n");
754 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
755 debugLog ("Found a Processor Register!\n");
769 /*-----------------------------------------------------------------*/
770 /* pic16_regWithIdx - returns pointer to register with index number*/
771 /*-----------------------------------------------------------------*/
773 pic16_regWithIdx (int idx)
777 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
780 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
783 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
789 /*-----------------------------------------------------------------*/
790 /* pic16_regWithIdx - returns pointer to register with index number */
791 /*-----------------------------------------------------------------*/
793 pic16_allocWithIdx (int idx)
798 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
800 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
802 debugLog ("Found a Dynamic Register!\n");
803 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
804 debugLog ("Found a Stack Register!\n");
805 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
806 debugLog ("Found a Processor Register!\n");
807 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
808 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
809 debugLog ("Found an Internal Register!\n");
812 debugLog ("Dynamic Register not found\n");
815 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
816 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
817 "regWithIdx not found");
827 /*-----------------------------------------------------------------*/
828 /*-----------------------------------------------------------------*/
830 pic16_findFreeReg(short type)
837 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
839 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
843 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
855 /*-----------------------------------------------------------------*/
856 /* freeReg - frees a register */
857 /*-----------------------------------------------------------------*/
861 debugLog ("%s\n", __FUNCTION__);
862 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
867 /*-----------------------------------------------------------------*/
868 /* nFreeRegs - returns number of free registers */
869 /*-----------------------------------------------------------------*/
877 /* although I fixed the register allocation/freeing scheme
878 * the for loop below doesn't give valid results. I do not
879 * know why yet. -- VR 10-Jan-2003 */
884 /* dynamically allocate as many as we need and worry about
885 * fitting them into a PIC later */
887 debugLog ("%s\n", __FUNCTION__);
889 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
890 if((reg->type == type) && reg->isFree)nfr++;
892 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
896 /*-----------------------------------------------------------------*/
897 /* nfreeRegsType - free registers with type */
898 /*-----------------------------------------------------------------*/
900 nfreeRegsType (int type)
903 debugLog ("%s\n", __FUNCTION__);
906 if ((nfr = nFreeRegs (type)) == 0)
907 return nFreeRegs (REG_GPR);
910 return nFreeRegs (type);
913 static void writeSetUsedRegs(FILE *of, set *dRegs)
918 for (dReg = setFirstItem(dRegs) ; dReg ;
919 dReg = setNextItem(dRegs)) {
922 fprintf (of, "\t%s\n",dReg->name);
928 extern void pic16_groupRegistersInSection(set *regset);
930 extern void pic16_dump_equates(FILE *of, set *equs);
931 //extern void pic16_dump_map(void);
932 extern void pic16_dump_section(FILE *of, set *section, int fix);
935 static void packBits(set *bregs)
940 regs *relocbitfield=NULL;
946 for (regset = bregs ; regset ;
947 regset = regset->next) {
950 breg->isBitField = 1;
951 //fprintf(stderr,"bit reg: %s\n",breg->name);
954 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
956 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
957 breg->rIdx = breg->address & 7;
961 sprintf (buffer, "fbitfield%02x", breg->address);
962 //fprintf(stderr,"new bit field\n");
963 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
964 bitfield->isBitField = 1;
965 bitfield->isFixed = 1;
966 bitfield->address = breg->address;
967 addSet(&pic16_dynDirectRegs,bitfield);
968 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
970 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
973 breg->reg_alias = bitfield;
977 if(!relocbitfield || bit_no >7) {
980 sprintf (buffer, "bitfield%d", byte_no);
981 //fprintf(stderr,"new relocatable bit field\n");
982 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
983 relocbitfield->isBitField = 1;
984 addSet(&pic16_dynDirectRegs,relocbitfield);
985 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
989 breg->reg_alias = relocbitfield;
990 breg->address = rDirectIdx; /* byte_no; */
991 breg->rIdx = bit_no++;
1000 static void bitEQUs(FILE *of, set *bregs)
1002 regs *breg,*bytereg;
1005 //fprintf(stderr," %s\n",__FUNCTION__);
1006 for (breg = setFirstItem(bregs) ; breg ;
1007 breg = setNextItem(bregs)) {
1009 //fprintf(stderr,"bit reg: %s\n",breg->name);
1011 bytereg = breg->reg_alias;
1013 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1016 breg->rIdx & 0x0007);
1019 fprintf(stderr, "bit field is not assigned to a register\n");
1020 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1031 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1036 for (reg = setFirstItem(fregs) ; reg ;
1037 reg = setNextItem(fregs)) {
1039 if(!reg->isEmitted && reg->wasUsed) {
1041 if (reg->type != REG_SFR) {
1042 fprintf (of, "%s\tEQU\t0x%03x\n",
1048 fprintf (of, "%s\tEQU\t0x%03x\n",
1057 void pic16_writeUsedRegs(FILE *of)
1059 packBits(pic16_dynDirectBitRegs);
1061 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1062 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1063 pic16_groupRegistersInSection(pic16_dynStackRegs);
1064 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1065 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1066 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1070 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1071 pic16_assignFixedRegisters(pic16_dynStackRegs);
1072 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1073 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1075 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1076 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1077 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1078 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1079 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1082 // pic16_dump_map();
1083 // pic16_dump_cblock(of);
1085 pic16_dump_equates(of, pic16_equ_data);
1087 pic16_dump_section(of, pic16_rel_udata, 0);
1088 pic16_dump_section(of, pic16_fix_udata, 1);
1091 bitEQUs(of,pic16_dynDirectBitRegs);
1092 aliasEQUs(of,pic16_dynAllocRegs,0);
1093 aliasEQUs(of,pic16_dynDirectRegs,0);
1094 aliasEQUs(of,pic16_dynStackRegs,0);
1095 aliasEQUs(of,pic16_dynProcessorRegs,1);
1101 /*-----------------------------------------------------------------*/
1102 /* allDefsOutOfRange - all definitions are out of a range */
1103 /*-----------------------------------------------------------------*/
1105 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1109 debugLog ("%s\n", __FUNCTION__);
1113 for (i = 0; i < defs->size; i++)
1117 if (bitVectBitValue (defs, i) &&
1118 (ic = hTabItemWithKey (iCodehTab, i)) &&
1119 (ic->seq >= fseq && ic->seq <= toseq))
1129 /*-----------------------------------------------------------------*/
1130 /* computeSpillable - given a point find the spillable live ranges */
1131 /*-----------------------------------------------------------------*/
1133 computeSpillable (iCode * ic)
1137 debugLog ("%s\n", __FUNCTION__);
1138 /* spillable live ranges are those that are live at this
1139 point . the following categories need to be subtracted
1141 a) - those that are already spilt
1142 b) - if being used by this one
1143 c) - defined by this one */
1145 spillable = bitVectCopy (ic->rlive);
1147 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1149 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1150 bitVectUnSetBit (spillable, ic->defKey);
1151 spillable = bitVectIntersect (spillable, _G.regAssigned);
1156 /*-----------------------------------------------------------------*/
1157 /* noSpilLoc - return true if a variable has no spil location */
1158 /*-----------------------------------------------------------------*/
1160 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1162 debugLog ("%s\n", __FUNCTION__);
1163 return (sym->usl.spillLoc ? 0 : 1);
1166 /*-----------------------------------------------------------------*/
1167 /* hasSpilLoc - will return 1 if the symbol has spil location */
1168 /*-----------------------------------------------------------------*/
1170 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1172 debugLog ("%s\n", __FUNCTION__);
1173 return (sym->usl.spillLoc ? 1 : 0);
1176 /*-----------------------------------------------------------------*/
1177 /* directSpilLoc - will return 1 if the splilocation is in direct */
1178 /*-----------------------------------------------------------------*/
1180 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1182 debugLog ("%s\n", __FUNCTION__);
1183 if (sym->usl.spillLoc &&
1184 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1190 /*-----------------------------------------------------------------*/
1191 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1192 /* but is not used as a pointer */
1193 /*-----------------------------------------------------------------*/
1195 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1197 debugLog ("%s\n", __FUNCTION__);
1198 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1201 /*-----------------------------------------------------------------*/
1202 /* rematable - will return 1 if the remat flag is set */
1203 /*-----------------------------------------------------------------*/
1205 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1207 debugLog ("%s\n", __FUNCTION__);
1211 /*-----------------------------------------------------------------*/
1212 /* notUsedInRemaining - not used or defined in remain of the block */
1213 /*-----------------------------------------------------------------*/
1215 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1217 debugLog ("%s\n", __FUNCTION__);
1218 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1219 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1222 /*-----------------------------------------------------------------*/
1223 /* allLRs - return true for all */
1224 /*-----------------------------------------------------------------*/
1226 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1228 debugLog ("%s\n", __FUNCTION__);
1232 /*-----------------------------------------------------------------*/
1233 /* liveRangesWith - applies function to a given set of live range */
1234 /*-----------------------------------------------------------------*/
1236 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1237 eBBlock * ebp, iCode * ic)
1242 debugLog ("%s\n", __FUNCTION__);
1243 if (!lrs || !lrs->size)
1246 for (i = 1; i < lrs->size; i++)
1249 if (!bitVectBitValue (lrs, i))
1252 /* if we don't find it in the live range
1253 hash table we are in serious trouble */
1254 if (!(sym = hTabItemWithKey (liveRanges, i)))
1256 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1257 "liveRangesWith could not find liveRange");
1261 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1262 addSetHead (&rset, sym);
1269 /*-----------------------------------------------------------------*/
1270 /* leastUsedLR - given a set determines which is the least used */
1271 /*-----------------------------------------------------------------*/
1273 leastUsedLR (set * sset)
1275 symbol *sym = NULL, *lsym = NULL;
1277 debugLog ("%s\n", __FUNCTION__);
1278 sym = lsym = setFirstItem (sset);
1283 for (; lsym; lsym = setNextItem (sset))
1286 /* if usage is the same then prefer
1287 the spill the smaller of the two */
1288 if (lsym->used == sym->used)
1289 if (getSize (lsym->type) < getSize (sym->type))
1293 if (lsym->used < sym->used)
1298 setToNull ((void *) &sset);
1303 /*-----------------------------------------------------------------*/
1304 /* noOverLap - will iterate through the list looking for over lap */
1305 /*-----------------------------------------------------------------*/
1307 noOverLap (set * itmpStack, symbol * fsym)
1310 debugLog ("%s\n", __FUNCTION__);
1313 for (sym = setFirstItem (itmpStack); sym;
1314 sym = setNextItem (itmpStack))
1316 if (sym->liveTo > fsym->liveFrom)
1324 /*-----------------------------------------------------------------*/
1325 /* isFree - will return 1 if the a free spil location is found */
1326 /*-----------------------------------------------------------------*/
1331 V_ARG (symbol **, sloc);
1332 V_ARG (symbol *, fsym);
1334 debugLog ("%s\n", __FUNCTION__);
1335 /* if already found */
1339 /* if it is free && and the itmp assigned to
1340 this does not have any overlapping live ranges
1341 with the one currently being assigned and
1342 the size can be accomodated */
1344 noOverLap (sym->usl.itmpStack, fsym) &&
1345 getSize (sym->type) >= getSize (fsym->type))
1354 /*-----------------------------------------------------------------*/
1355 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1356 /*-----------------------------------------------------------------*/
1358 spillLRWithPtrReg (symbol * forSym)
1364 debugLog ("%s\n", __FUNCTION__);
1365 if (!_G.regAssigned ||
1366 bitVectIsZero (_G.regAssigned))
1369 r0 = pic16_regWithIdx (R0_IDX);
1370 r1 = pic16_regWithIdx (R1_IDX);
1372 /* for all live ranges */
1373 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1374 lrsym = hTabNextItem (liveRanges, &k))
1378 /* if no registers assigned to it or
1380 /* if it does not overlap with this then
1381 not need to spill it */
1383 if (lrsym->isspilt || !lrsym->nRegs ||
1384 (lrsym->liveTo < forSym->liveFrom))
1387 /* go thru the registers : if it is either
1388 r0 or r1 then spil it */
1389 for (j = 0; j < lrsym->nRegs; j++)
1390 if (lrsym->regs[j] == r0 ||
1391 lrsym->regs[j] == r1)
1400 /*-----------------------------------------------------------------*/
1401 /* createStackSpil - create a location on the stack to spil */
1402 /*-----------------------------------------------------------------*/
1404 createStackSpil (symbol * sym)
1406 symbol *sloc = NULL;
1407 int useXstack, model, noOverlay;
1409 char slocBuffer[30];
1410 debugLog ("%s\n", __FUNCTION__);
1412 /* first go try and find a free one that is already
1413 existing on the stack */
1414 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1416 /* found a free one : just update & return */
1417 sym->usl.spillLoc = sloc;
1420 addSetHead (&sloc->usl.itmpStack, sym);
1424 /* could not then have to create one , this is the hard part
1425 we need to allocate this on the stack : this is really a
1426 hack!! but cannot think of anything better at this time */
1428 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1430 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1431 __FILE__, __LINE__);
1435 sloc = newiTemp (slocBuffer);
1437 /* set the type to the spilling symbol */
1438 sloc->type = copyLinkChain (sym->type);
1439 sloc->etype = getSpec (sloc->type);
1440 SPEC_SCLS (sloc->etype) = S_DATA;
1441 SPEC_EXTR (sloc->etype) = 0;
1442 SPEC_STAT (sloc->etype) = 0;
1444 /* we don't allow it to be allocated`
1445 onto the external stack since : so we
1446 temporarily turn it off ; we also
1447 turn off memory model to prevent
1448 the spil from going to the external storage
1449 and turn off overlaying
1452 useXstack = options.useXstack;
1453 model = options.model;
1454 noOverlay = options.noOverlay;
1455 options.noOverlay = 1;
1456 options.model = options.useXstack = 0;
1460 options.useXstack = useXstack;
1461 options.model = model;
1462 options.noOverlay = noOverlay;
1463 sloc->isref = 1; /* to prevent compiler warning */
1465 /* if it is on the stack then update the stack */
1466 if (IN_STACK (sloc->etype))
1468 currFunc->stack += getSize (sloc->type);
1469 _G.stackExtend += getSize (sloc->type);
1472 _G.dataExtend += getSize (sloc->type);
1474 /* add it to the _G.stackSpil set */
1475 addSetHead (&_G.stackSpil, sloc);
1476 sym->usl.spillLoc = sloc;
1479 /* add it to the set of itempStack set
1480 of the spill location */
1481 addSetHead (&sloc->usl.itmpStack, sym);
1485 /*-----------------------------------------------------------------*/
1486 /* isSpiltOnStack - returns true if the spil location is on stack */
1487 /*-----------------------------------------------------------------*/
1489 isSpiltOnStack (symbol * sym)
1493 debugLog ("%s\n", __FUNCTION__);
1500 /* if (sym->_G.stackSpil) */
1503 if (!sym->usl.spillLoc)
1506 etype = getSpec (sym->usl.spillLoc->type);
1507 if (IN_STACK (etype))
1513 /*-----------------------------------------------------------------*/
1514 /* spillThis - spils a specific operand */
1515 /*-----------------------------------------------------------------*/
1517 spillThis (symbol * sym)
1520 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1522 /* if this is rematerializable or has a spillLocation
1523 we are okay, else we need to create a spillLocation
1525 if (!(sym->remat || sym->usl.spillLoc))
1526 createStackSpil (sym);
1529 /* mark it has spilt & put it in the spilt set */
1531 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1533 bitVectUnSetBit (_G.regAssigned, sym->key);
1535 for (i = 0; i < sym->nRegs; i++)
1539 freeReg (sym->regs[i]);
1540 sym->regs[i] = NULL;
1543 /* if spilt on stack then free up r0 & r1
1544 if they could have been assigned to some
1546 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1549 spillLRWithPtrReg (sym);
1552 if (sym->usl.spillLoc && !sym->remat)
1553 sym->usl.spillLoc->allocreq = 1;
1557 /*-----------------------------------------------------------------*/
1558 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1559 /*-----------------------------------------------------------------*/
1561 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1563 bitVect *lrcs = NULL;
1567 debugLog ("%s\n", __FUNCTION__);
1568 /* get the spillable live ranges */
1569 lrcs = computeSpillable (ic);
1571 /* get all live ranges that are rematerizable */
1572 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1575 /* return the least used of these */
1576 return leastUsedLR (selectS);
1579 /* get live ranges with spillLocations in direct space */
1580 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1582 sym = leastUsedLR (selectS);
1583 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1584 sym->usl.spillLoc->rname :
1585 sym->usl.spillLoc->name));
1587 /* mark it as allocation required */
1588 sym->usl.spillLoc->allocreq = 1;
1592 /* if the symbol is local to the block then */
1593 if (forSym->liveTo < ebp->lSeq)
1596 /* check if there are any live ranges allocated
1597 to registers that are not used in this block */
1598 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1600 sym = leastUsedLR (selectS);
1601 /* if this is not rematerializable */
1610 /* check if there are any live ranges that not
1611 used in the remainder of the block */
1612 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1614 sym = leastUsedLR (selectS);
1617 sym->remainSpil = 1;
1624 /* find live ranges with spillocation && not used as pointers */
1625 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1628 sym = leastUsedLR (selectS);
1629 /* mark this as allocation required */
1630 sym->usl.spillLoc->allocreq = 1;
1634 /* find live ranges with spillocation */
1635 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1638 sym = leastUsedLR (selectS);
1639 sym->usl.spillLoc->allocreq = 1;
1643 /* couldn't find then we need to create a spil
1644 location on the stack , for which one? the least
1646 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1649 /* return a created spil location */
1650 sym = createStackSpil (leastUsedLR (selectS));
1651 sym->usl.spillLoc->allocreq = 1;
1655 /* this is an extreme situation we will spill
1656 this one : happens very rarely but it does happen */
1662 /*-----------------------------------------------------------------*/
1663 /* spilSomething - spil some variable & mark registers as free */
1664 /*-----------------------------------------------------------------*/
1666 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1671 debugLog ("%s\n", __FUNCTION__);
1672 /* get something we can spil */
1673 ssym = selectSpil (ic, ebp, forSym);
1675 /* mark it as spilt */
1677 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1679 /* mark it as not register assigned &
1680 take it away from the set */
1681 bitVectUnSetBit (_G.regAssigned, ssym->key);
1683 /* mark the registers as free */
1684 for (i = 0; i < ssym->nRegs; i++)
1686 freeReg (ssym->regs[i]);
1688 /* if spilt on stack then free up r0 & r1
1689 if they could have been assigned to as gprs */
1690 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1693 spillLRWithPtrReg (ssym);
1696 /* if this was a block level spil then insert push & pop
1697 at the start & end of block respectively */
1698 if (ssym->blockSpil)
1700 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1701 /* add push to the start of the block */
1702 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1703 ebp->sch->next : ebp->sch));
1704 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1705 /* add pop to the end of the block */
1706 addiCodeToeBBlock (ebp, nic, NULL);
1709 /* if spilt because not used in the remainder of the
1710 block then add a push before this instruction and
1711 a pop at the end of the block */
1712 if (ssym->remainSpil)
1715 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1716 /* add push just before this instruction */
1717 addiCodeToeBBlock (ebp, nic, ic);
1719 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1720 /* add pop to the end of the block */
1721 addiCodeToeBBlock (ebp, nic, NULL);
1730 /*-----------------------------------------------------------------*/
1731 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1732 /*-----------------------------------------------------------------*/
1734 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1739 debugLog ("%s\n", __FUNCTION__);
1741 /* try for a ptr type */
1742 if ((reg = allocReg (REG_PTR)))
1745 /* try for gpr type */
1746 if ((reg = allocReg (REG_GPR)))
1749 /* we have to spil */
1750 if (!spilSomething (ic, ebp, sym))
1753 /* make sure partially assigned registers aren't reused */
1754 for (j=0; j<=sym->nRegs; j++)
1756 sym->regs[j]->isFree = 0;
1758 /* this looks like an infinite loop but
1759 in really selectSpil will abort */
1763 /*-----------------------------------------------------------------*/
1764 /* getRegGpr - will try for GPR if not spil */
1765 /*-----------------------------------------------------------------*/
1767 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1772 debugLog ("%s\n", __FUNCTION__);
1774 /* try for gpr type */
1775 if ((reg = allocReg (REG_GPR)))
1778 if (!pic16_ptrRegReq)
1779 if ((reg = allocReg (REG_PTR)))
1782 /* we have to spil */
1783 if (!spilSomething (ic, ebp, sym))
1786 /* make sure partially assigned registers aren't reused */
1787 for (j=0; j<=sym->nRegs; j++)
1789 sym->regs[j]->isFree = 0;
1791 /* this looks like an infinite loop but
1792 in really selectSpil will abort */
1796 /*-----------------------------------------------------------------*/
1797 /* symHasReg - symbol has a given register */
1798 /*-----------------------------------------------------------------*/
1800 symHasReg (symbol * sym, regs * reg)
1804 debugLog ("%s\n", __FUNCTION__);
1805 for (i = 0; i < sym->nRegs; i++)
1806 if (sym->regs[i] == reg)
1812 /*-----------------------------------------------------------------*/
1813 /* deassignLRs - check the live to and if they have registers & are */
1814 /* not spilt then free up the registers */
1815 /*-----------------------------------------------------------------*/
1817 deassignLRs (iCode * ic, eBBlock * ebp)
1823 debugLog ("%s\n", __FUNCTION__);
1824 for (sym = hTabFirstItem (liveRanges, &k); sym;
1825 sym = hTabNextItem (liveRanges, &k))
1828 symbol *psym = NULL;
1829 /* if it does not end here */
1830 if (sym->liveTo > ic->seq)
1833 /* if it was spilt on stack then we can
1834 mark the stack spil location as free */
1839 sym->usl.spillLoc->isFree = 1;
1845 if (!bitVectBitValue (_G.regAssigned, sym->key))
1848 /* special case check if this is an IFX &
1849 the privious one was a pop and the
1850 previous one was not spilt then keep track
1852 if (ic->op == IFX && ic->prev &&
1853 ic->prev->op == IPOP &&
1854 !ic->prev->parmPush &&
1855 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1856 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1862 bitVectUnSetBit (_G.regAssigned, sym->key);
1864 /* if the result of this one needs registers
1865 and does not have it then assign it right
1867 if (IC_RESULT (ic) &&
1868 !(SKIP_IC2 (ic) || /* not a special icode */
1869 ic->op == JUMPTABLE ||
1874 POINTER_SET (ic)) &&
1875 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1876 result->liveTo > ic->seq && /* and will live beyond this */
1877 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1878 result->regType == sym->regType && /* same register types */
1879 result->nRegs && /* which needs registers */
1880 !result->isspilt && /* and does not already have them */
1882 !bitVectBitValue (_G.regAssigned, result->key) &&
1883 /* the number of free regs + number of regs in this LR
1884 can accomodate the what result Needs */
1885 ((nfreeRegsType (result->regType) +
1886 sym->nRegs) >= result->nRegs)
1890 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1892 result->regs[i] = sym->regs[i];
1894 result->regs[i] = getRegGpr (ic, ebp, result);
1896 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1900 /* free the remaining */
1901 for (; i < sym->nRegs; i++)
1905 if (!symHasReg (psym, sym->regs[i]))
1906 freeReg (sym->regs[i]);
1909 freeReg (sym->regs[i]);
1916 /*-----------------------------------------------------------------*/
1917 /* reassignLR - reassign this to registers */
1918 /*-----------------------------------------------------------------*/
1920 reassignLR (operand * op)
1922 symbol *sym = OP_SYMBOL (op);
1925 debugLog ("%s\n", __FUNCTION__);
1926 /* not spilt any more */
1927 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1928 bitVectUnSetBit (_G.spiltSet, sym->key);
1930 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1934 for (i = 0; i < sym->nRegs; i++)
1935 sym->regs[i]->isFree = 0;
1938 /*-----------------------------------------------------------------*/
1939 /* willCauseSpill - determines if allocating will cause a spill */
1940 /*-----------------------------------------------------------------*/
1942 willCauseSpill (int nr, int rt)
1944 debugLog ("%s\n", __FUNCTION__);
1945 /* first check if there are any avlb registers
1946 of te type required */
1949 /* special case for pointer type
1950 if pointer type not avlb then
1951 check for type gpr */
1952 if (nFreeRegs (rt) >= nr)
1954 if (nFreeRegs (REG_GPR) >= nr)
1959 if (pic16_ptrRegReq)
1961 if (nFreeRegs (rt) >= nr)
1966 if (nFreeRegs (REG_PTR) +
1967 nFreeRegs (REG_GPR) >= nr)
1972 debugLog (" ... yep it will (cause a spill)\n");
1973 /* it will cause a spil */
1977 /*-----------------------------------------------------------------*/
1978 /* positionRegs - the allocator can allocate same registers to res- */
1979 /* ult and operand, if this happens make sure they are in the same */
1980 /* position as the operand otherwise chaos results */
1981 /*-----------------------------------------------------------------*/
1983 positionRegs (symbol * result, symbol * opsym, int lineno)
1985 int count = min (result->nRegs, opsym->nRegs);
1986 int i, j = 0, shared = 0;
1988 debugLog ("%s\n", __FUNCTION__);
1989 /* if the result has been spilt then cannot share */
1994 /* first make sure that they actually share */
1995 for (i = 0; i < count; i++)
1997 for (j = 0; j < count; j++)
1999 if (result->regs[i] == opsym->regs[j] && i != j)
2009 regs *tmp = result->regs[i];
2010 result->regs[i] = result->regs[j];
2011 result->regs[j] = tmp;
2016 /*------------------------------------------------------------------*/
2017 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2018 /* it should either have registers or have beed spilled. Otherwise, */
2019 /* there was an uninitialized variable, so just spill this to get */
2020 /* the operand in a valid state. */
2021 /*------------------------------------------------------------------*/
2023 verifyRegsAssigned (operand *op, iCode * ic)
2028 if (!IS_ITEMP (op)) return;
2030 sym = OP_SYMBOL (op);
2031 if (sym->isspilt) return;
2032 if (!sym->nRegs) return;
2033 if (sym->regs[0]) return;
2035 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2036 sym->prereqv ? sym->prereqv->name : sym->name);
2041 /*-----------------------------------------------------------------*/
2042 /* serialRegAssign - serially allocate registers to the variables */
2043 /*-----------------------------------------------------------------*/
2045 serialRegAssign (eBBlock ** ebbs, int count)
2049 debugLog ("%s\n", __FUNCTION__);
2050 /* for all blocks */
2051 for (i = 0; i < count; i++)
2056 if (ebbs[i]->noPath &&
2057 (ebbs[i]->entryLabel != entryLabel &&
2058 ebbs[i]->entryLabel != returnLabel))
2061 /* of all instructions do */
2062 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2065 debugLog (" op: %s\n", decodeOp (ic->op));
2067 /* if this is an ipop that means some live
2068 range will have to be assigned again */
2070 reassignLR (IC_LEFT (ic));
2072 /* if result is present && is a true symbol */
2073 if (IC_RESULT (ic) && ic->op != IFX &&
2074 IS_TRUE_SYMOP (IC_RESULT (ic)))
2075 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2077 /* take away registers from live
2078 ranges that end at this instruction */
2079 deassignLRs (ic, ebbs[i]);
2081 /* some don't need registers */
2082 if (SKIP_IC2 (ic) ||
2083 ic->op == JUMPTABLE ||
2087 (IC_RESULT (ic) && POINTER_SET (ic)))
2090 /* now we need to allocate registers
2091 only for the result */
2094 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2100 /* if it does not need or is spilt
2101 or is already assigned to registers
2102 or will not live beyond this instructions */
2105 bitVectBitValue (_G.regAssigned, sym->key) ||
2106 sym->liveTo <= ic->seq)
2109 /* if some liverange has been spilt at the block level
2110 and this one live beyond this block then spil this
2112 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2117 /* if trying to allocate this will cause
2118 a spill and there is nothing to spill
2119 or this one is rematerializable then
2121 willCS = willCauseSpill (sym->nRegs, sym->regType);
2122 spillable = computeSpillable (ic);
2124 (willCS && bitVectIsZero (spillable)))
2132 /* if it has a spillocation & is used less than
2133 all other live ranges then spill this */
2135 if (sym->usl.spillLoc) {
2136 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2137 allLRs, ebbs[i], ic));
2138 if (leastUsed && leastUsed->used > sym->used) {
2143 /* if none of the liveRanges have a spillLocation then better
2144 to spill this one than anything else already assigned to registers */
2145 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2146 /* if this is local to this block then we might find a block spil */
2147 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2155 if (ic->op == RECEIVE)
2156 debugLog ("When I get clever, I'll optimize the receive logic\n");
2158 /* if we need ptr regs for the right side
2160 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2161 <= (unsigned) PTRSIZE)
2166 /* else we assign registers to it */
2167 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2169 debugLog (" %d - \n", __LINE__);
2171 bitVectDebugOn(_G.regAssigned, debugF);
2173 for (j = 0; j < sym->nRegs; j++)
2175 if (sym->regType == REG_PTR)
2176 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2178 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2180 /* if the allocation falied which means
2181 this was spilt then break */
2185 debugLog (" %d - \n", __LINE__);
2187 /* if it shares registers with operands make sure
2188 that they are in the same position */
2189 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2190 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2191 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2192 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2193 /* do the same for the right operand */
2194 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2195 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2196 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2197 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2199 debugLog (" %d - \n", __LINE__);
2202 debugLog (" %d - \n", __LINE__);
2211 /* Check for and fix any problems with uninitialized operands */
2212 for (i = 0; i < count; i++)
2216 if (ebbs[i]->noPath &&
2217 (ebbs[i]->entryLabel != entryLabel &&
2218 ebbs[i]->entryLabel != returnLabel))
2221 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2228 verifyRegsAssigned (IC_COND (ic), ic);
2232 if (ic->op == JUMPTABLE)
2234 verifyRegsAssigned (IC_JTCOND (ic), ic);
2238 verifyRegsAssigned (IC_RESULT (ic), ic);
2239 verifyRegsAssigned (IC_LEFT (ic), ic);
2240 verifyRegsAssigned (IC_RIGHT (ic), ic);
2246 /*-----------------------------------------------------------------*/
2247 /* rUmaskForOp :- returns register mask for an operand */
2248 /*-----------------------------------------------------------------*/
2250 rUmaskForOp (operand * op)
2256 debugLog ("%s\n", __FUNCTION__);
2257 /* only temporaries are assigned registers */
2261 sym = OP_SYMBOL (op);
2263 /* if spilt or no registers assigned to it
2265 if (sym->isspilt || !sym->nRegs)
2268 rumask = newBitVect (pic16_nRegs);
2270 for (j = 0; j < sym->nRegs; j++)
2272 rumask = bitVectSetBit (rumask,
2273 sym->regs[j]->rIdx);
2279 /*-----------------------------------------------------------------*/
2280 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2281 /*-----------------------------------------------------------------*/
2283 regsUsedIniCode (iCode * ic)
2285 bitVect *rmask = newBitVect (pic16_nRegs);
2287 debugLog ("%s\n", __FUNCTION__);
2288 /* do the special cases first */
2291 rmask = bitVectUnion (rmask,
2292 rUmaskForOp (IC_COND (ic)));
2296 /* for the jumptable */
2297 if (ic->op == JUMPTABLE)
2299 rmask = bitVectUnion (rmask,
2300 rUmaskForOp (IC_JTCOND (ic)));
2305 /* of all other cases */
2307 rmask = bitVectUnion (rmask,
2308 rUmaskForOp (IC_LEFT (ic)));
2312 rmask = bitVectUnion (rmask,
2313 rUmaskForOp (IC_RIGHT (ic)));
2316 rmask = bitVectUnion (rmask,
2317 rUmaskForOp (IC_RESULT (ic)));
2323 /*-----------------------------------------------------------------*/
2324 /* createRegMask - for each instruction will determine the regsUsed */
2325 /*-----------------------------------------------------------------*/
2327 createRegMask (eBBlock ** ebbs, int count)
2331 debugLog ("%s\n", __FUNCTION__);
2332 /* for all blocks */
2333 for (i = 0; i < count; i++)
2337 if (ebbs[i]->noPath &&
2338 (ebbs[i]->entryLabel != entryLabel &&
2339 ebbs[i]->entryLabel != returnLabel))
2342 /* for all instructions */
2343 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2348 if (SKIP_IC2 (ic) || !ic->rlive)
2351 /* first mark the registers used in this
2353 ic->rUsed = regsUsedIniCode (ic);
2354 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2356 /* now create the register mask for those
2357 registers that are in use : this is a
2358 super set of ic->rUsed */
2359 ic->rMask = newBitVect (pic16_nRegs + 1);
2361 /* for all live Ranges alive at this point */
2362 for (j = 1; j < ic->rlive->size; j++)
2367 /* if not alive then continue */
2368 if (!bitVectBitValue (ic->rlive, j))
2371 /* find the live range we are interested in */
2372 if (!(sym = hTabItemWithKey (liveRanges, j)))
2374 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2375 "createRegMask cannot find live range");
2379 /* if no register assigned to it */
2380 if (!sym->nRegs || sym->isspilt)
2383 /* for all the registers allocated to it */
2384 for (k = 0; k < sym->nRegs; k++)
2387 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2393 /*-----------------------------------------------------------------*/
2394 /* rematStr - returns the rematerialized string for a remat var */
2395 /*-----------------------------------------------------------------*/
2397 rematStr (symbol * sym)
2400 iCode *ic = sym->rematiCode;
2401 symbol *psym = NULL;
2403 debugLog ("%s\n", __FUNCTION__);
2405 //printf ("%s\n", s);
2407 /* if plus or minus print the right hand side */
2409 if (ic->op == '+' || ic->op == '-') {
2411 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2413 sprintf (s, "(%s %c 0x%04x)",
2414 OP_SYMBOL (IC_LEFT (ric))->rname,
2416 (int) operandLitValue (IC_RIGHT (ic)));
2419 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2421 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2422 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2427 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2428 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2430 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2435 /*-----------------------------------------------------------------*/
2436 /* rematStr - returns the rematerialized string for a remat var */
2437 /*-----------------------------------------------------------------*/
2439 rematStr (symbol * sym)
2442 iCode *ic = sym->rematiCode;
2444 debugLog ("%s\n", __FUNCTION__);
2449 /* if plus or minus print the right hand side */
2451 if (ic->op == '+' || ic->op == '-') {
2452 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2455 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2459 if (ic->op == '+' || ic->op == '-')
2461 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2462 sprintf (s, "(%s %c 0x%04x)",
2463 OP_SYMBOL (IC_LEFT (ric))->rname,
2465 (int) operandLitValue (IC_RIGHT (ic)));
2468 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2470 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2474 /* we reached the end */
2475 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2479 printf ("%s\n", buffer);
2484 /*-----------------------------------------------------------------*/
2485 /* regTypeNum - computes the type & number of registers required */
2486 /*-----------------------------------------------------------------*/
2494 debugLog ("%s\n", __FUNCTION__);
2495 /* for each live range do */
2496 for (sym = hTabFirstItem (liveRanges, &k); sym;
2497 sym = hTabNextItem (liveRanges, &k)) {
2499 debugLog (" %d - %s\n", __LINE__, sym->rname);
2500 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2502 /* if used zero times then no registers needed */
2503 if ((sym->liveTo - sym->liveFrom) == 0)
2507 /* if the live range is a temporary */
2510 debugLog (" %d - itemp register\n", __LINE__);
2512 /* if the type is marked as a conditional */
2513 if (sym->regType == REG_CND)
2516 /* if used in return only then we don't
2518 if (sym->ruonly || sym->accuse) {
2519 if (IS_AGGREGATE (sym->type) || sym->isptr)
2520 sym->type = aggrToPtr (sym->type, FALSE);
2521 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2526 /* if the symbol has only one definition &
2527 that definition is a get_pointer and the
2528 pointer we are getting is rematerializable and
2531 if (bitVectnBitsOn (sym->defs) == 1 &&
2532 (ic = hTabItemWithKey (iCodehTab,
2533 bitVectFirstBit (sym->defs))) &&
2536 !IS_BITVAR (sym->etype)) {
2539 debugLog (" %d - \n", __LINE__);
2541 /* if remat in data space */
2542 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2543 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2545 /* create a psuedo symbol & force a spil */
2546 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2547 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2548 psym->type = sym->type;
2549 psym->etype = sym->etype;
2550 strcpy (psym->rname, psym->name);
2552 sym->usl.spillLoc = psym;
2556 /* if in data space or idata space then try to
2557 allocate pointer register */
2561 /* if not then we require registers */
2562 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2563 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2564 getSize (sym->type));
2568 if(IS_PTR_CONST (sym->type)) {
2570 if(IS_CODEPTR (sym->type)) {
2572 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2576 if (sym->nRegs > 4) {
2577 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2578 printTypeChain (sym->type, stderr);
2579 fprintf (stderr, "\n");
2582 /* determine the type of register required */
2583 if (sym->nRegs == 1 &&
2584 IS_PTR (sym->type) &&
2586 sym->regType = REG_PTR;
2588 sym->regType = REG_GPR;
2591 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2595 /* for the first run we don't provide */
2596 /* registers for true symbols we will */
2597 /* see how things go */
2602 static DEFSETFUNC (markRegFree)
2604 ((regs *)item)->isFree = 1;
2609 DEFSETFUNC (pic16_deallocReg)
2611 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2612 ((regs *)item)->isFree = 1;
2613 ((regs *)item)->wasUsed = 0;
2617 /*-----------------------------------------------------------------*/
2618 /* freeAllRegs - mark all registers as free */
2619 /*-----------------------------------------------------------------*/
2621 pic16_freeAllRegs ()
2623 debugLog ("%s\n", __FUNCTION__);
2625 applyToSet(pic16_dynAllocRegs,markRegFree);
2626 applyToSet(pic16_dynStackRegs,markRegFree);
2629 /*-----------------------------------------------------------------*/
2630 /*-----------------------------------------------------------------*/
2632 pic16_deallocateAllRegs ()
2634 debugLog ("%s\n", __FUNCTION__);
2636 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2640 /*-----------------------------------------------------------------*/
2641 /* deallocStackSpil - this will set the stack pointer back */
2642 /*-----------------------------------------------------------------*/
2644 DEFSETFUNC (deallocStackSpil)
2648 debugLog ("%s\n", __FUNCTION__);
2653 /*-----------------------------------------------------------------*/
2654 /* farSpacePackable - returns the packable icode for far variables */
2655 /*-----------------------------------------------------------------*/
2657 farSpacePackable (iCode * ic)
2661 debugLog ("%s\n", __FUNCTION__);
2662 /* go thru till we find a definition for the
2663 symbol on the right */
2664 for (dic = ic->prev; dic; dic = dic->prev)
2667 /* if the definition is a call then no */
2668 if ((dic->op == CALL || dic->op == PCALL) &&
2669 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2674 /* if shift by unknown amount then not */
2675 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2676 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2679 /* if pointer get and size > 1 */
2680 if (POINTER_GET (dic) &&
2681 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2684 if (POINTER_SET (dic) &&
2685 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2688 /* if any three is a true symbol in far space */
2689 if (IC_RESULT (dic) &&
2690 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2691 isOperandInFarSpace (IC_RESULT (dic)))
2694 if (IC_RIGHT (dic) &&
2695 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2696 isOperandInFarSpace (IC_RIGHT (dic)) &&
2697 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2700 if (IC_LEFT (dic) &&
2701 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2702 isOperandInFarSpace (IC_LEFT (dic)) &&
2703 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2706 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2708 if ((dic->op == LEFT_OP ||
2709 dic->op == RIGHT_OP ||
2711 IS_OP_LITERAL (IC_RIGHT (dic)))
2721 /*-----------------------------------------------------------------*/
2722 /* packRegsForAssign - register reduction for assignment */
2723 /*-----------------------------------------------------------------*/
2725 packRegsForAssign (iCode * ic, eBBlock * ebp)
2730 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2731 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2732 debugAopGet (" result:", IC_RESULT (ic));
2733 debugAopGet (" left:", IC_LEFT (ic));
2734 debugAopGet (" right:", IC_RIGHT (ic));
2736 /* if this is at an absolute address, then get the address. */
2737 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2738 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2739 debugLog (" %d - found config word declaration\n", __LINE__);
2740 if(IS_VALOP(IC_RIGHT(ic))) {
2741 debugLog (" setting config word to %x\n",
2742 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2743 fprintf(stderr, " setting config word to %x\n",
2744 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2745 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2746 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2750 debugLog(" %d\n", __LINE__);
2752 /* remove the assignment from the iCode chain. */
2754 remiCodeFromeBBlock (ebp, ic);
2755 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2756 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2762 debugLog(" %d - actuall processing\n", __LINE__ );
2764 if (!IS_ITEMP (IC_RESULT (ic))) {
2765 pic16_allocDirReg(IC_RESULT (ic));
2766 debugLog (" %d - result is not temp\n", __LINE__);
2770 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2771 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2772 pic16_allocDirReg(IC_LEFT (ic));
2776 /* See BUGLOG0001 - VR */
2778 if (!IS_ITEMP (IC_RIGHT (ic))) {
2779 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2780 pic16_allocDirReg(IC_RIGHT (ic));
2785 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2786 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2788 debugLog (" %d - not packing - right side fails \n", __LINE__);
2792 /* if the true symbol is defined in far space or on stack
2793 then we should not since this will increase register pressure */
2794 if (isOperandInFarSpace (IC_RESULT (ic)))
2796 if ((dic = farSpacePackable (ic)))
2804 if(ic->op == CALL || ic->op == PCALL) {
2805 addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic)));
2806 debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name);
2811 /* find the definition of iTempNN scanning backwards if we find a
2812 a use of the true symbol before we find the definition then
2814 for (dic = ic->prev; dic; dic = dic->prev)
2817 /* if there is a function call and this is
2818 a parameter & not my parameter then don't pack it */
2819 if ((dic->op == CALL || dic->op == PCALL) &&
2820 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2821 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2823 debugLog (" %d - \n", __LINE__);
2832 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2835 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2836 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2837 debugAopGet(" result is ", IC_RESULT(dic));
2839 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2840 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2841 debugAopGet(" left is ", IC_LEFT(dic));
2843 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2844 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2845 debugAopGet(" right is ", IC_RIGHT(dic));
2849 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2850 IS_OP_VOLATILE (IC_RESULT (dic)))
2852 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2858 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2859 IS_OP_VOLATILE (IC_RIGHT(dic)))
2861 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2868 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2869 IS_OP_VOLATILE (IC_LEFT(dic)))
2871 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2877 if (IS_SYMOP (IC_RESULT (dic)) &&
2878 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2880 /* A previous result was assigned to the same register - we'll our definition */
2881 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2882 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2883 if (POINTER_SET (dic))
2889 if (IS_SYMOP (IC_RIGHT (dic)) &&
2890 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2891 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2893 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2898 if (IS_SYMOP (IC_LEFT (dic)) &&
2899 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2900 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2902 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2907 if (POINTER_SET (dic) &&
2908 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2910 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2918 return 0; /* did not find */
2920 /* if the result is on stack or iaccess then it must be
2921 the same atleast one of the operands */
2922 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2923 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2926 /* the operation has only one symbol
2927 operator then we can pack */
2928 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2929 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2932 if (!((IC_LEFT (dic) &&
2933 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2935 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2939 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2940 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2941 /* found the definition */
2942 /* replace the result with the result of */
2943 /* this assignment and remove this assignment */
2944 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2945 IC_RESULT (dic) = IC_RESULT (ic);
2947 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2949 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2951 /* delete from liverange table also
2952 delete from all the points inbetween and the new
2954 for (sic = dic; sic != ic; sic = sic->next)
2956 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2957 if (IS_ITEMP (IC_RESULT (dic)))
2958 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2961 remiCodeFromeBBlock (ebp, ic);
2962 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2964 debugLog(" %d\n", __LINE__ );
2965 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2966 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2972 /*-----------------------------------------------------------------*/
2973 /* findAssignToSym : scanning backwards looks for first assig found */
2974 /*-----------------------------------------------------------------*/
2976 findAssignToSym (operand * op, iCode * ic)
2980 debugLog ("%s\n", __FUNCTION__);
2981 for (dic = ic->prev; dic; dic = dic->prev)
2984 /* if definition by assignment */
2985 if (dic->op == '=' &&
2986 !POINTER_SET (dic) &&
2987 IC_RESULT (dic)->key == op->key
2988 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2992 /* we are interested only if defined in far space */
2993 /* or in stack space in case of + & - */
2995 /* if assigned to a non-symbol then return
2997 if (!IS_SYMOP (IC_RIGHT (dic)))
3000 /* if the symbol is in far space then
3002 if (isOperandInFarSpace (IC_RIGHT (dic)))
3005 /* for + & - operations make sure that
3006 if it is on the stack it is the same
3007 as one of the three operands */
3008 if ((ic->op == '+' || ic->op == '-') &&
3009 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3012 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3013 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3014 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3022 /* if we find an usage then we cannot delete it */
3023 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3026 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3029 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3033 /* now make sure that the right side of dic
3034 is not defined between ic & dic */
3037 iCode *sic = dic->next;
3039 for (; sic != ic; sic = sic->next)
3040 if (IC_RESULT (sic) &&
3041 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3050 /*-----------------------------------------------------------------*/
3051 /* packRegsForSupport :- reduce some registers for support calls */
3052 /*-----------------------------------------------------------------*/
3054 packRegsForSupport (iCode * ic, eBBlock * ebp)
3058 debugLog ("%s\n", __FUNCTION__);
3059 /* for the left & right operand :- look to see if the
3060 left was assigned a true symbol in far space in that
3061 case replace them */
3062 if (IS_ITEMP (IC_LEFT (ic)) &&
3063 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3065 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3071 debugAopGet ("removing left:", IC_LEFT (ic));
3073 /* found it we need to remove it from the
3075 for (sic = dic; sic != ic; sic = sic->next)
3076 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3078 IC_LEFT (ic)->operand.symOperand =
3079 IC_RIGHT (dic)->operand.symOperand;
3080 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3081 remiCodeFromeBBlock (ebp, dic);
3082 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3083 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3087 /* do the same for the right operand */
3090 IS_ITEMP (IC_RIGHT (ic)) &&
3091 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3093 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3099 /* if this is a subtraction & the result
3100 is a true symbol in far space then don't pack */
3101 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3103 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3104 if (IN_FARSPACE (SPEC_OCLS (etype)))
3108 debugAopGet ("removing right:", IC_RIGHT (ic));
3110 /* found it we need to remove it from the
3112 for (sic = dic; sic != ic; sic = sic->next)
3113 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3115 IC_RIGHT (ic)->operand.symOperand =
3116 IC_RIGHT (dic)->operand.symOperand;
3117 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3119 remiCodeFromeBBlock (ebp, dic);
3120 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3121 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3128 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3131 /*-----------------------------------------------------------------*/
3132 /* packRegsForOneuse : - will reduce some registers for single Use */
3133 /*-----------------------------------------------------------------*/
3135 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3140 debugLog ("%s\n", __FUNCTION__);
3141 /* if returning a literal then do nothing */
3145 /* only upto 2 bytes since we cannot predict
3146 the usage of b, & acc */
3147 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3152 /* this routine will mark the a symbol as used in one
3153 instruction use only && if the definition is local
3154 (ie. within the basic block) && has only one definition &&
3155 that definition is either a return value from a
3156 function or does not contain any variables in
3158 uses = bitVectCopy (OP_USES (op));
3159 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3160 if (!bitVectIsZero (uses)) /* has other uses */
3163 /* if it has only one defintion */
3164 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3165 return NULL; /* has more than one definition */
3167 /* get that definition */
3169 hTabItemWithKey (iCodehTab,
3170 bitVectFirstBit (OP_DEFS (op)))))
3173 /* found the definition now check if it is local */
3174 if (dic->seq < ebp->fSeq ||
3175 dic->seq > ebp->lSeq)
3176 return NULL; /* non-local */
3178 /* now check if it is the return from
3180 if (dic->op == CALL || dic->op == PCALL)
3182 if (ic->op != SEND && ic->op != RETURN &&
3183 !POINTER_SET(ic) && !POINTER_GET(ic))
3185 OP_SYMBOL (op)->ruonly = 1;
3192 /* otherwise check that the definition does
3193 not contain any symbols in far space */
3194 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3195 isOperandInFarSpace (IC_RIGHT (dic)) ||
3196 IS_OP_RUONLY (IC_LEFT (ic)) ||
3197 IS_OP_RUONLY (IC_RIGHT (ic)))
3202 /* if pointer set then make sure the pointer
3204 if (POINTER_SET (dic) &&
3205 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3208 if (POINTER_GET (dic) &&
3209 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3214 /* also make sure the intervenening instructions
3215 don't have any thing in far space */
3216 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3219 /* if there is an intervening function call then no */
3220 if (dic->op == CALL || dic->op == PCALL)
3222 /* if pointer set then make sure the pointer
3224 if (POINTER_SET (dic) &&
3225 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3228 if (POINTER_GET (dic) &&
3229 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3232 /* if address of & the result is remat then okay */
3233 if (dic->op == ADDRESS_OF &&
3234 OP_SYMBOL (IC_RESULT (dic))->remat)
3237 /* if operand has size of three or more & this
3238 operation is a '*','/' or '%' then 'b' may
3240 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3241 getSize (operandType (op)) >= 3)
3244 /* if left or right or result is in far space */
3245 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3246 isOperandInFarSpace (IC_RIGHT (dic)) ||
3247 isOperandInFarSpace (IC_RESULT (dic)) ||
3248 IS_OP_RUONLY (IC_LEFT (dic)) ||
3249 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3250 IS_OP_RUONLY (IC_RESULT (dic)))
3256 OP_SYMBOL (op)->ruonly = 1;
3261 /*-----------------------------------------------------------------*/
3262 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3263 /*-----------------------------------------------------------------*/
3265 isBitwiseOptimizable (iCode * ic)
3267 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3268 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3270 debugLog ("%s\n", __FUNCTION__);
3271 /* bitwise operations are considered optimizable
3272 under the following conditions (Jean-Louis VERN)
3284 if (IS_LITERAL (rtype) ||
3285 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3291 /*-----------------------------------------------------------------*/
3292 /* packRegsForAccUse - pack registers for acc use */
3293 /*-----------------------------------------------------------------*/
3295 packRegsForAccUse (iCode * ic)
3299 debugLog ("%s\n", __FUNCTION__);
3301 /* if this is an aggregate, e.g. a one byte char array */
3302 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3305 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3307 /* if + or - then it has to be one byte result */
3308 if ((ic->op == '+' || ic->op == '-')
3309 && getSize (operandType (IC_RESULT (ic))) > 1)
3312 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3313 /* if shift operation make sure right side is not a literal */
3314 if (ic->op == RIGHT_OP &&
3315 (isOperandLiteral (IC_RIGHT (ic)) ||
3316 getSize (operandType (IC_RESULT (ic))) > 1))
3319 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3320 if (ic->op == LEFT_OP &&
3321 (isOperandLiteral (IC_RIGHT (ic)) ||
3322 getSize (operandType (IC_RESULT (ic))) > 1))
3325 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3326 if (IS_BITWISE_OP (ic) &&
3327 getSize (operandType (IC_RESULT (ic))) > 1)
3331 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3332 /* has only one definition */
3333 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3336 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3337 /* has only one use */
3338 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3341 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3342 /* and the usage immediately follows this iCode */
3343 if (!(uic = hTabItemWithKey (iCodehTab,
3344 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3347 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3348 if (ic->next != uic)
3351 /* if it is a conditional branch then we definitely can */
3355 if (uic->op == JUMPTABLE)
3358 /* if the usage is not is an assignment
3359 or an arithmetic / bitwise / shift operation then not */
3360 if (POINTER_SET (uic) &&
3361 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3364 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3365 if (uic->op != '=' &&
3366 !IS_ARITHMETIC_OP (uic) &&
3367 !IS_BITWISE_OP (uic) &&
3368 uic->op != LEFT_OP &&
3369 uic->op != RIGHT_OP)
3372 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3373 /* if used in ^ operation then make sure right is not a
3375 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3378 /* if shift operation make sure right side is not a literal */
3379 if (uic->op == RIGHT_OP &&
3380 (isOperandLiteral (IC_RIGHT (uic)) ||
3381 getSize (operandType (IC_RESULT (uic))) > 1))
3384 if (uic->op == LEFT_OP &&
3385 (isOperandLiteral (IC_RIGHT (uic)) ||
3386 getSize (operandType (IC_RESULT (uic))) > 1))
3389 /* make sure that the result of this icode is not on the
3390 stack, since acc is used to compute stack offset */
3391 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3392 OP_SYMBOL (IC_RESULT (uic))->onStack)
3395 /* if either one of them in far space then we cannot */
3396 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3397 isOperandInFarSpace (IC_LEFT (uic))) ||
3398 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3399 isOperandInFarSpace (IC_RIGHT (uic))))
3402 /* if the usage has only one operand then we can */
3403 if (IC_LEFT (uic) == NULL ||
3404 IC_RIGHT (uic) == NULL)
3407 /* make sure this is on the left side if not
3408 a '+' since '+' is commutative */
3409 if (ic->op != '+' &&
3410 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3413 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3414 /* if one of them is a literal then we can */
3415 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3416 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3417 (getSize (operandType (IC_RESULT (uic))) <= 1))
3419 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3423 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3424 /* if the other one is not on stack then we can */
3425 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3426 (IS_ITEMP (IC_RIGHT (uic)) ||
3427 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3428 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3431 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3432 (IS_ITEMP (IC_LEFT (uic)) ||
3433 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3434 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3440 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3441 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3446 /*-----------------------------------------------------------------*/
3447 /* packForPush - hueristics to reduce iCode for pushing */
3448 /*-----------------------------------------------------------------*/
3450 packForReceive (iCode * ic, eBBlock * ebp)
3454 debugLog ("%s\n", __FUNCTION__);
3455 debugAopGet (" result:", IC_RESULT (ic));
3456 debugAopGet (" left:", IC_LEFT (ic));
3457 debugAopGet (" right:", IC_RIGHT (ic));
3462 for (dic = ic->next; dic; dic = dic->next)
3467 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3468 debugLog (" used on left\n");
3469 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3470 debugLog (" used on right\n");
3471 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3472 debugLog (" used on result\n");
3474 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3475 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3480 debugLog (" hey we can remove this unnecessary assign\n");
3482 /*-----------------------------------------------------------------*/
3483 /* packForPush - hueristics to reduce iCode for pushing */
3484 /*-----------------------------------------------------------------*/
3486 packForPush (iCode * ic, eBBlock * ebp)
3490 debugLog ("%s\n", __FUNCTION__);
3491 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3494 /* must have only definition & one usage */
3495 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3496 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3499 /* find the definition */
3500 if (!(dic = hTabItemWithKey (iCodehTab,
3501 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3504 if (dic->op != '=' || POINTER_SET (dic))
3507 /* we now we know that it has one & only one def & use
3508 and the that the definition is an assignment */
3509 IC_LEFT (ic) = IC_RIGHT (dic);
3511 remiCodeFromeBBlock (ebp, dic);
3512 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3513 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3516 static void printSymType(char * str, sym_link *sl)
3518 if(!pic16_ralloc_debug)return;
3520 debugLog (" %s Symbol type: ",str);
3521 printTypeChain( sl, debugF);
3525 /*-----------------------------------------------------------------*/
3526 /* some debug code to print the symbol S_TYPE. Note that
3527 * the function checkSClass in src/SDCCsymt.c dinks with
3528 * the S_TYPE in ways the PIC port doesn't fully like...*/
3529 /*-----------------------------------------------------------------*/
3530 static void isData(sym_link *sl)
3534 if(!pic16_ralloc_debug)return;
3541 for ( ; sl; sl=sl->next) {
3543 switch (SPEC_SCLS(sl)) {
3544 case S_DATA: fprintf (of, "data "); break;
3545 case S_XDATA: fprintf (of, "xdata "); break;
3546 case S_SFR: fprintf (of, "sfr "); break;
3547 case S_SBIT: fprintf (of, "sbit "); break;
3548 case S_CODE: fprintf (of, "code "); break;
3549 case S_IDATA: fprintf (of, "idata "); break;
3550 case S_PDATA: fprintf (of, "pdata "); break;
3551 case S_LITERAL: fprintf (of, "literal "); break;
3552 case S_STACK: fprintf (of, "stack "); break;
3553 case S_XSTACK: fprintf (of, "xstack "); break;
3554 case S_BIT: fprintf (of, "bit "); break;
3555 case S_EEPROM: fprintf (of, "eeprom "); break;
3563 #define NO_packRegsForSupport 1
3564 #define NO_packRegsForAccUse 1
3565 #define NO_packRegsForOneuse 1
3566 #define NO_cast_peep 1
3568 /*--------------------------------------------------------------------*/
3569 /* pic16_packRegisters - does some transformations to reduce */
3570 /* register pressure */
3572 /*--------------------------------------------------------------------*/
3574 pic16_packRegisters (eBBlock * ebp)
3579 debugLog ("%s\n", __FUNCTION__);
3585 /* look for assignments of the form */
3586 /* iTempNN = TRueSym (someoperation) SomeOperand */
3588 /* TrueSym := iTempNN:1 */
3589 for (ic = ebp->sch; ic; ic = ic->next)
3591 // debugLog("%d\n", __LINE__);
3592 /* find assignment of the form TrueSym := iTempNN:1 */
3593 /* see BUGLOG0001 for workaround with the CAST - VR */
3594 if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3595 change += packRegsForAssign (ic, ebp);
3599 if (POINTER_SET (ic))
3600 debugLog ("pointer is set\n");
3601 debugAopGet (" result:", IC_RESULT (ic));
3602 debugAopGet (" left:", IC_LEFT (ic));
3603 debugAopGet (" right:", IC_RIGHT (ic));
3612 for (ic = ebp->sch; ic; ic = ic->next) {
3614 if(IS_SYMOP ( IC_LEFT(ic))) {
3615 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3617 debugAopGet ("x left:", IC_LEFT (ic));
3619 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3621 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3623 debugLog (" is a pointer\n");
3625 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3626 debugLog (" is a ptr\n");
3628 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3629 debugLog (" is volatile\n");
3633 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3634 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3635 pic16_allocDirReg(IC_LEFT (ic));
3638 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3641 if(IS_SYMOP ( IC_RIGHT(ic))) {
3642 debugAopGet (" right:", IC_RIGHT (ic));
3643 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3646 if(IS_SYMOP ( IC_RESULT(ic))) {
3647 debugAopGet (" result:", IC_RESULT (ic));
3648 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3651 if (POINTER_SET (ic))
3652 debugLog (" %d - Pointer set\n", __LINE__);
3655 /* if this is an itemp & result of a address of a true sym
3656 then mark this as rematerialisable */
3657 if (ic->op == ADDRESS_OF &&
3658 IS_ITEMP (IC_RESULT (ic)) &&
3659 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3660 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3661 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3664 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3666 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3667 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3668 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3672 /* if straight assignment then carry remat flag if
3673 this is the only definition */
3674 if (ic->op == '=' &&
3675 !POINTER_SET (ic) &&
3676 IS_SYMOP (IC_RIGHT (ic)) &&
3677 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3678 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3680 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3682 OP_SYMBOL (IC_RESULT (ic))->remat =
3683 OP_SYMBOL (IC_RIGHT (ic))->remat;
3684 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3685 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3688 /* if this is a +/- operation with a rematerizable
3689 then mark this as rematerializable as well */
3690 if ((ic->op == '+' || ic->op == '-') &&
3691 (IS_SYMOP (IC_LEFT (ic)) &&
3692 IS_ITEMP (IC_RESULT (ic)) &&
3693 OP_SYMBOL (IC_LEFT (ic))->remat &&
3694 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3695 IS_OP_LITERAL (IC_RIGHT (ic))))
3697 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3699 operandLitValue (IC_RIGHT (ic));
3700 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3701 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3702 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3705 /* mark the pointer usages */
3706 if (POINTER_SET (ic))
3708 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3709 debugLog (" marking as a pointer (set) =>");
3710 debugAopGet (" result:", IC_RESULT (ic));
3712 if (POINTER_GET (ic))
3714 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3715 debugLog (" marking as a pointer (get) =>");
3716 debugAopGet (" left:", IC_LEFT (ic));
3719 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3723 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3724 /* if we are using a symbol on the stack
3725 then we should say pic16_ptrRegReq */
3726 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3727 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3728 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3729 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3730 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3731 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3735 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3736 if (IS_SYMOP (IC_LEFT (ic)))
3737 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3738 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3739 if (IS_SYMOP (IC_RIGHT (ic)))
3740 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3741 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3742 if (IS_SYMOP (IC_RESULT (ic)))
3743 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3744 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3747 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3751 /* if the condition of an if instruction
3752 is defined in the previous instruction then
3753 mark the itemp as a conditional */
3754 if ((IS_CONDITIONAL (ic) ||
3755 ((ic->op == BITWISEAND ||
3758 isBitwiseOptimizable (ic))) &&
3759 ic->next && ic->next->op == IFX &&
3760 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3761 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3764 debugLog (" %d\n", __LINE__);
3765 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3769 debugLog(" %d\n", __LINE__);
3771 #if NO_packRegsForSupport
3772 /* reduce for support function calls */
3773 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3774 packRegsForSupport (ic, ebp);
3777 /* if a parameter is passed, it's in W, so we may not
3778 need to place a copy in a register */
3779 if (ic->op == RECEIVE)
3780 packForReceive (ic, ebp);
3782 #if NO_packRegsForOneuse
3783 /* some cases the redundant moves can
3784 can be eliminated for return statements */
3785 if ((ic->op == RETURN || ic->op == SEND) &&
3786 !isOperandInFarSpace (IC_LEFT (ic)) &&
3788 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3791 #if NO_packRegsForOneuse
3792 /* if pointer set & left has a size more than
3793 one and right is not in far space */
3794 if (POINTER_SET (ic) &&
3795 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3796 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3797 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3798 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3800 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3803 #if NO_packRegsForOneuse
3804 /* if pointer get */
3805 if (POINTER_GET (ic) &&
3806 !isOperandInFarSpace (IC_RESULT (ic)) &&
3807 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3808 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3809 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3811 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3812 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3816 /* if this is cast for intergral promotion then
3817 check if only use of the definition of the
3818 operand being casted/ if yes then replace
3819 the result of that arithmetic operation with
3820 this result and get rid of the cast */
3821 if (ic->op == CAST) {
3823 sym_link *fromType = operandType (IC_RIGHT (ic));
3824 sym_link *toType = operandType (IC_LEFT (ic));
3826 debugLog (" %d - casting\n", __LINE__);
3828 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3829 getSize (fromType) != getSize (toType)) {
3832 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3835 if (IS_ARITHMETIC_OP (dic)) {
3836 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3838 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3839 IC_RESULT (dic) = IC_RESULT (ic);
3840 remiCodeFromeBBlock (ebp, ic);
3841 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3842 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3843 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3847 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3851 /* if the type from and type to are the same
3852 then if this is the only use then packit */
3853 if (compareType (operandType (IC_RIGHT (ic)),
3854 operandType (IC_LEFT (ic))) == 1) {
3856 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3859 debugLog(" %d\n", __LINE__);
3861 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3862 IC_RESULT (dic) = IC_RESULT (ic);
3863 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3864 remiCodeFromeBBlock (ebp, ic);
3865 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3866 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3874 iTempNN := (some variable in farspace) V1
3879 if (ic->op == IPUSH)
3881 packForPush (ic, ebp);
3885 #if NO_packRegsForAccUse
3886 /* pack registers for accumulator use, when the
3887 result of an arithmetic or bit wise operation
3888 has only one use, that use is immediately following
3889 the defintion and the using iCode has only one
3890 operand or has two operands but one is literal &
3891 the result of that operation is not on stack then
3892 we can leave the result of this operation in acc:b
3894 if ((IS_ARITHMETIC_OP (ic)
3896 || IS_BITWISE_OP (ic)
3898 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3901 IS_ITEMP (IC_RESULT (ic)) &&
3902 getSize (operandType (IC_RESULT (ic))) <= 2)
3904 packRegsForAccUse (ic);
3911 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3915 if (!pic16_ralloc_debug || !debugF)
3918 for (i = 0; i < count; i++)
3920 fprintf (debugF, "\n----------------------------------------------------------------\n");
3921 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3922 ebbs[i]->entryLabel->name,
3925 ebbs[i]->isLastInLoop);
3926 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3931 fprintf (debugF, "visited %d : hasFcall = %d\n",
3935 fprintf (debugF, "\ndefines bitVector :");
3936 bitVectDebugOn (ebbs[i]->defSet, debugF);
3937 fprintf (debugF, "\nlocal defines bitVector :");
3938 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3939 fprintf (debugF, "\npointers Set bitvector :");
3940 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3941 fprintf (debugF, "\nin pointers Set bitvector :");
3942 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3943 fprintf (debugF, "\ninDefs Set bitvector :");
3944 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3945 fprintf (debugF, "\noutDefs Set bitvector :");
3946 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3947 fprintf (debugF, "\nusesDefs Set bitvector :");
3948 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3949 fprintf (debugF, "\n----------------------------------------------------------------\n");
3950 printiCChain (ebbs[i]->sch, debugF);
3953 /*-----------------------------------------------------------------*/
3954 /* pic16_assignRegisters - assigns registers to each live range as need */
3955 /*-----------------------------------------------------------------*/
3957 pic16_assignRegisters (eBBlock ** ebbs, int count)
3962 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3963 debugLog ("\nebbs before optimizing:\n");
3964 dumpEbbsToDebug (ebbs, count);
3966 setToNull ((void *) &_G.funcrUsed);
3967 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3970 /* change assignments this will remove some
3971 live ranges reducing some register pressure */
3972 for (i = 0; i < count; i++)
3973 pic16_packRegisters (ebbs[i]);
3980 debugLog("dir registers allocated so far:\n");
3981 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3984 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3985 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3986 reg = hTabNextItem(dynDirectRegNames, &hkey);
3991 /* liveranges probably changed by register packing
3992 so we compute them again */
3993 recomputeLiveRanges (ebbs, count);
3995 if (options.dump_pack)
3996 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3998 /* first determine for each live range the number of
3999 registers & the type of registers required for each */
4002 /* and serially allocate registers */
4003 serialRegAssign (ebbs, count);
4005 //pic16_freeAllRegs();
4007 /* if stack was extended then tell the user */
4010 /* werror(W_TOOMANY_SPILS,"stack", */
4011 /* _G.stackExtend,currFunc->name,""); */
4017 /* werror(W_TOOMANY_SPILS,"data space", */
4018 /* _G.dataExtend,currFunc->name,""); */
4022 /* after that create the register mask
4023 for each of the instruction */
4024 createRegMask (ebbs, count);
4026 /* redo that offsets for stacked automatic variables */
4027 redoStackOffsets ();
4029 if (options.dump_rassgn)
4030 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4032 /* now get back the chain */
4033 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4035 debugLog ("ebbs after optimizing:\n");
4036 dumpEbbsToDebug (ebbs, count);
4041 /* free up any _G.stackSpil locations allocated */
4042 applyToSet (_G.stackSpil, deallocStackSpil);
4044 setToNull ((void *) &_G.stackSpil);
4045 setToNull ((void *) &_G.spiltSet);
4046 /* mark all registers as free */
4047 pic16_freeAllRegs ();
4049 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");