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 static 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);
360 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
365 // dReg->isMapped = 0;
367 dReg->accessBank = 0;
369 if(type == REG_SFR) {
371 dReg->address = rIdx;
379 dReg->reg_alias = NULL;
380 dReg->reglives.usedpFlows = newSet();
381 dReg->reglives.assignedpFlows = newSet();
384 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
389 /*-----------------------------------------------------------------*/
390 /* regWithIdx - Search through a set of registers that matches idx */
391 /*-----------------------------------------------------------------*/
393 regWithIdx (set *dRegs, int idx, int fixed)
397 for (dReg = setFirstItem(dRegs) ; dReg ;
398 dReg = setNextItem(dRegs)) {
400 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
408 /*-----------------------------------------------------------------*/
409 /* regFindFree - Search for a free register in a set of registers */
410 /*-----------------------------------------------------------------*/
412 regFindFree (set *dRegs)
416 for (dReg = setFirstItem(dRegs) ; dReg ;
417 dReg = setNextItem(dRegs)) {
419 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
420 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
429 /*-----------------------------------------------------------------*/
430 /* pic16_initStack - allocate registers for a pseudo stack */
431 /*-----------------------------------------------------------------*/
432 void pic16_initStack(int base_address, int size)
437 pic16_Gstack_base_addr = base_address;
438 //fprintf(stderr,"initStack");
440 for(i = 0; i<size; i++)
441 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
444 /*-----------------------------------------------------------------*
445 *-----------------------------------------------------------------*/
447 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
449 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
451 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
453 reg->wasUsed = 0; // we do not know if they are going to be used at all
454 reg->accessBank = 1; // implicit add access Bank
456 return addSet(&pic16_dynProcessorRegs, reg);
459 /*-----------------------------------------------------------------*
460 *-----------------------------------------------------------------*/
463 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
465 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
467 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
471 return addSet(&pic16_dynInternalRegs,reg);
476 /*-----------------------------------------------------------------*/
477 /* allocReg - allocates register of given type */
478 /*-----------------------------------------------------------------*/
480 allocReg (short type)
485 if(dynrIdx > pic16_nRegs)
491 /* try to reuse some unused registers */
492 reg = regFindFree( pic16_dynAllocRegs );
497 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
498 addSet(&pic16_dynAllocRegs, reg);
502 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
504 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
505 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
508 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
509 reg->isLocal = 1; /* this is a local frame register */
514 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
517 return (reg); // addSet(&pic16_dynAllocRegs,reg);
522 /*-----------------------------------------------------------------*/
523 /* pic16_dirregWithName - search for register by name */
524 /*-----------------------------------------------------------------*/
526 pic16_dirregWithName (char *name)
534 /* hash the name to get a key */
536 hkey = regname2key(name);
538 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
540 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
544 if(STRCASECMP(reg->name, name) == 0) {
548 reg = hTabNextItemWK (dynDirectRegNames);
552 return NULL; // name wasn't found in the hash table
555 static int IS_CONFIG_ADDRESS(int address)
558 return address >= 0x300000 && address <= 0x300000d;
561 /*-----------------------------------------------------------------*/
562 /* pic16_allocDirReg - allocates register of given type */
563 /*-----------------------------------------------------------------*/
565 pic16_allocDirReg (operand *op )
572 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
576 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
578 /* If the symbol is at a fixed address, then remove the leading underscore
579 * from the name. This is hack to allow the .asm include file named registers
580 * to match the .c declared register names */
582 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
585 /* The above hack is not necessery anymore, since .asm include files are not
586 * used by current implementation of the port -- VR 03-Jan-04 */
588 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
589 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
591 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
592 debugLog(" %d const char\n",__LINE__);
593 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
594 // fprintf(stderr, " %d const char\n",__LINE__);
595 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
598 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
599 if (IS_CODE ( OP_SYM_ETYPE(op)) )
600 debugLog(" %d code space\n",__LINE__);
602 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
603 debugLog(" %d integral\n",__LINE__);
604 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
605 debugLog(" %d literal\n",__LINE__);
606 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
607 debugLog(" %d specifier\n",__LINE__);
608 debugAopGet(NULL, op);
611 if (IS_CODE ( OP_SYM_ETYPE(op)) )
614 /* First, search the hash table to see if there is a register with this name */
615 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
616 reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
620 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
621 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
623 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
624 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
627 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
629 reg = pic16_dirregWithName(name);
635 /* if this is at an absolute address, then get the address. */
636 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
637 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
638 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
641 /* Register wasn't found in hash, so let's create
642 * a new one and put it in the hash table AND in the
643 * dynDirectRegNames set */
644 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
645 if(pic16_debug_verbose)
646 fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
647 OP_SYMBOL(op)->name);
650 if(!IS_CONFIG_ADDRESS(address)) {
651 //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
653 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
654 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
656 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
658 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
660 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
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)
1738 debugLog ("%s\n", __FUNCTION__);
1740 /* try for a ptr type */
1741 if ((reg = allocReg (REG_PTR)))
1744 /* try for gpr type */
1745 if ((reg = allocReg (REG_GPR)))
1748 /* we have to spil */
1749 if (!spilSomething (ic, ebp, sym))
1752 /* this looks like an infinite loop but
1753 in really selectSpil will abort */
1757 /*-----------------------------------------------------------------*/
1758 /* getRegGpr - will try for GPR if not spil */
1759 /*-----------------------------------------------------------------*/
1761 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1765 debugLog ("%s\n", __FUNCTION__);
1767 /* try for gpr type */
1768 if ((reg = allocReg (REG_GPR)))
1771 if (!pic16_ptrRegReq)
1772 if ((reg = allocReg (REG_PTR)))
1775 /* we have to spil */
1776 if (!spilSomething (ic, ebp, sym))
1779 /* this looks like an infinite loop but
1780 in really selectSpil will abort */
1784 /*-----------------------------------------------------------------*/
1785 /* symHasReg - symbol has a given register */
1786 /*-----------------------------------------------------------------*/
1788 symHasReg (symbol * sym, regs * reg)
1792 debugLog ("%s\n", __FUNCTION__);
1793 for (i = 0; i < sym->nRegs; i++)
1794 if (sym->regs[i] == reg)
1800 /*-----------------------------------------------------------------*/
1801 /* deassignLRs - check the live to and if they have registers & are */
1802 /* not spilt then free up the registers */
1803 /*-----------------------------------------------------------------*/
1805 deassignLRs (iCode * ic, eBBlock * ebp)
1811 debugLog ("%s\n", __FUNCTION__);
1812 for (sym = hTabFirstItem (liveRanges, &k); sym;
1813 sym = hTabNextItem (liveRanges, &k))
1816 symbol *psym = NULL;
1817 /* if it does not end here */
1818 if (sym->liveTo > ic->seq)
1821 /* if it was spilt on stack then we can
1822 mark the stack spil location as free */
1827 sym->usl.spillLoc->isFree = 1;
1833 if (!bitVectBitValue (_G.regAssigned, sym->key))
1836 /* special case check if this is an IFX &
1837 the privious one was a pop and the
1838 previous one was not spilt then keep track
1840 if (ic->op == IFX && ic->prev &&
1841 ic->prev->op == IPOP &&
1842 !ic->prev->parmPush &&
1843 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1844 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1850 bitVectUnSetBit (_G.regAssigned, sym->key);
1852 /* if the result of this one needs registers
1853 and does not have it then assign it right
1855 if (IC_RESULT (ic) &&
1856 !(SKIP_IC2 (ic) || /* not a special icode */
1857 ic->op == JUMPTABLE ||
1862 POINTER_SET (ic)) &&
1863 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1864 result->liveTo > ic->seq && /* and will live beyond this */
1865 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1866 result->regType == sym->regType && /* same register types */
1867 result->nRegs && /* which needs registers */
1868 !result->isspilt && /* and does not already have them */
1870 !bitVectBitValue (_G.regAssigned, result->key) &&
1871 /* the number of free regs + number of regs in this LR
1872 can accomodate the what result Needs */
1873 ((nfreeRegsType (result->regType) +
1874 sym->nRegs) >= result->nRegs)
1878 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1880 result->regs[i] = sym->regs[i];
1882 result->regs[i] = getRegGpr (ic, ebp, result);
1884 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1888 /* free the remaining */
1889 for (; i < sym->nRegs; i++)
1893 if (!symHasReg (psym, sym->regs[i]))
1894 freeReg (sym->regs[i]);
1897 freeReg (sym->regs[i]);
1904 /*-----------------------------------------------------------------*/
1905 /* reassignLR - reassign this to registers */
1906 /*-----------------------------------------------------------------*/
1908 reassignLR (operand * op)
1910 symbol *sym = OP_SYMBOL (op);
1913 debugLog ("%s\n", __FUNCTION__);
1914 /* not spilt any more */
1915 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1916 bitVectUnSetBit (_G.spiltSet, sym->key);
1918 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1922 for (i = 0; i < sym->nRegs; i++)
1923 sym->regs[i]->isFree = 0;
1926 /*-----------------------------------------------------------------*/
1927 /* willCauseSpill - determines if allocating will cause a spill */
1928 /*-----------------------------------------------------------------*/
1930 willCauseSpill (int nr, int rt)
1932 debugLog ("%s\n", __FUNCTION__);
1933 /* first check if there are any avlb registers
1934 of te type required */
1937 /* special case for pointer type
1938 if pointer type not avlb then
1939 check for type gpr */
1940 if (nFreeRegs (rt) >= nr)
1942 if (nFreeRegs (REG_GPR) >= nr)
1947 if (pic16_ptrRegReq)
1949 if (nFreeRegs (rt) >= nr)
1954 if (nFreeRegs (REG_PTR) +
1955 nFreeRegs (REG_GPR) >= nr)
1960 debugLog (" ... yep it will (cause a spill)\n");
1961 /* it will cause a spil */
1965 /*-----------------------------------------------------------------*/
1966 /* positionRegs - the allocator can allocate same registers to res- */
1967 /* ult and operand, if this happens make sure they are in the same */
1968 /* position as the operand otherwise chaos results */
1969 /*-----------------------------------------------------------------*/
1971 positionRegs (symbol * result, symbol * opsym, int lineno)
1973 int count = min (result->nRegs, opsym->nRegs);
1974 int i, j = 0, shared = 0;
1976 debugLog ("%s\n", __FUNCTION__);
1977 /* if the result has been spilt then cannot share */
1982 /* first make sure that they actually share */
1983 for (i = 0; i < count; i++)
1985 for (j = 0; j < count; j++)
1987 if (result->regs[i] == opsym->regs[j] && i != j)
1997 regs *tmp = result->regs[i];
1998 result->regs[i] = result->regs[j];
1999 result->regs[j] = tmp;
2004 /*-----------------------------------------------------------------*/
2005 /* serialRegAssign - serially allocate registers to the variables */
2006 /*-----------------------------------------------------------------*/
2008 serialRegAssign (eBBlock ** ebbs, int count)
2012 debugLog ("%s\n", __FUNCTION__);
2013 /* for all blocks */
2014 for (i = 0; i < count; i++)
2019 if (ebbs[i]->noPath &&
2020 (ebbs[i]->entryLabel != entryLabel &&
2021 ebbs[i]->entryLabel != returnLabel))
2024 /* of all instructions do */
2025 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2028 debugLog (" op: %s\n", decodeOp (ic->op));
2030 /* if this is an ipop that means some live
2031 range will have to be assigned again */
2033 reassignLR (IC_LEFT (ic));
2035 /* if result is present && is a true symbol */
2036 if (IC_RESULT (ic) && ic->op != IFX &&
2037 IS_TRUE_SYMOP (IC_RESULT (ic)))
2038 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2040 /* take away registers from live
2041 ranges that end at this instruction */
2042 deassignLRs (ic, ebbs[i]);
2044 /* some don't need registers */
2045 if (SKIP_IC2 (ic) ||
2046 ic->op == JUMPTABLE ||
2050 (IC_RESULT (ic) && POINTER_SET (ic)))
2053 /* now we need to allocate registers
2054 only for the result */
2057 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2063 /* if it does not need or is spilt
2064 or is already assigned to registers
2065 or will not live beyond this instructions */
2068 bitVectBitValue (_G.regAssigned, sym->key) ||
2069 sym->liveTo <= ic->seq)
2072 /* if some liverange has been spilt at the block level
2073 and this one live beyond this block then spil this
2075 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2080 /* if trying to allocate this will cause
2081 a spill and there is nothing to spill
2082 or this one is rematerializable then
2084 willCS = willCauseSpill (sym->nRegs, sym->regType);
2085 spillable = computeSpillable (ic);
2087 (willCS && bitVectIsZero (spillable)))
2095 /* if it has a spillocation & is used less than
2096 all other live ranges then spill this */
2098 if (sym->usl.spillLoc) {
2099 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2100 allLRs, ebbs[i], ic));
2101 if (leastUsed && leastUsed->used > sym->used) {
2106 /* if none of the liveRanges have a spillLocation then better
2107 to spill this one than anything else already assigned to registers */
2108 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2109 /* if this is local to this block then we might find a block spil */
2110 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2118 if (ic->op == RECEIVE)
2119 debugLog ("When I get clever, I'll optimize the receive logic\n");
2121 /* if we need ptr regs for the right side
2123 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2124 <= (unsigned) PTRSIZE)
2129 /* else we assign registers to it */
2130 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2132 debugLog (" %d - \n", __LINE__);
2134 bitVectDebugOn(_G.regAssigned, debugF);
2136 for (j = 0; j < sym->nRegs; j++)
2138 if (sym->regType == REG_PTR)
2139 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2141 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2143 /* if the allocation falied which means
2144 this was spilt then break */
2148 debugLog (" %d - \n", __LINE__);
2150 /* if it shares registers with operands make sure
2151 that they are in the same position */
2152 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2153 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2154 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2155 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2156 /* do the same for the right operand */
2157 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2158 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2159 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2160 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2162 debugLog (" %d - \n", __LINE__);
2165 debugLog (" %d - \n", __LINE__);
2175 /*-----------------------------------------------------------------*/
2176 /* rUmaskForOp :- returns register mask for an operand */
2177 /*-----------------------------------------------------------------*/
2179 rUmaskForOp (operand * op)
2185 debugLog ("%s\n", __FUNCTION__);
2186 /* only temporaries are assigned registers */
2190 sym = OP_SYMBOL (op);
2192 /* if spilt or no registers assigned to it
2194 if (sym->isspilt || !sym->nRegs)
2197 rumask = newBitVect (pic16_nRegs);
2199 for (j = 0; j < sym->nRegs; j++)
2201 rumask = bitVectSetBit (rumask,
2202 sym->regs[j]->rIdx);
2208 /*-----------------------------------------------------------------*/
2209 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2210 /*-----------------------------------------------------------------*/
2212 regsUsedIniCode (iCode * ic)
2214 bitVect *rmask = newBitVect (pic16_nRegs);
2216 debugLog ("%s\n", __FUNCTION__);
2217 /* do the special cases first */
2220 rmask = bitVectUnion (rmask,
2221 rUmaskForOp (IC_COND (ic)));
2225 /* for the jumptable */
2226 if (ic->op == JUMPTABLE)
2228 rmask = bitVectUnion (rmask,
2229 rUmaskForOp (IC_JTCOND (ic)));
2234 /* of all other cases */
2236 rmask = bitVectUnion (rmask,
2237 rUmaskForOp (IC_LEFT (ic)));
2241 rmask = bitVectUnion (rmask,
2242 rUmaskForOp (IC_RIGHT (ic)));
2245 rmask = bitVectUnion (rmask,
2246 rUmaskForOp (IC_RESULT (ic)));
2252 /*-----------------------------------------------------------------*/
2253 /* createRegMask - for each instruction will determine the regsUsed */
2254 /*-----------------------------------------------------------------*/
2256 createRegMask (eBBlock ** ebbs, int count)
2260 debugLog ("%s\n", __FUNCTION__);
2261 /* for all blocks */
2262 for (i = 0; i < count; i++)
2266 if (ebbs[i]->noPath &&
2267 (ebbs[i]->entryLabel != entryLabel &&
2268 ebbs[i]->entryLabel != returnLabel))
2271 /* for all instructions */
2272 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2277 if (SKIP_IC2 (ic) || !ic->rlive)
2280 /* first mark the registers used in this
2282 ic->rUsed = regsUsedIniCode (ic);
2283 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2285 /* now create the register mask for those
2286 registers that are in use : this is a
2287 super set of ic->rUsed */
2288 ic->rMask = newBitVect (pic16_nRegs + 1);
2290 /* for all live Ranges alive at this point */
2291 for (j = 1; j < ic->rlive->size; j++)
2296 /* if not alive then continue */
2297 if (!bitVectBitValue (ic->rlive, j))
2300 /* find the live range we are interested in */
2301 if (!(sym = hTabItemWithKey (liveRanges, j)))
2303 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2304 "createRegMask cannot find live range");
2308 /* if no register assigned to it */
2309 if (!sym->nRegs || sym->isspilt)
2312 /* for all the registers allocated to it */
2313 for (k = 0; k < sym->nRegs; k++)
2316 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2322 /*-----------------------------------------------------------------*/
2323 /* rematStr - returns the rematerialized string for a remat var */
2324 /*-----------------------------------------------------------------*/
2326 rematStr (symbol * sym)
2329 iCode *ic = sym->rematiCode;
2330 symbol *psym = NULL;
2332 debugLog ("%s\n", __FUNCTION__);
2334 //printf ("%s\n", s);
2336 /* if plus or minus print the right hand side */
2338 if (ic->op == '+' || ic->op == '-') {
2340 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2342 sprintf (s, "(%s %c 0x%04x)",
2343 OP_SYMBOL (IC_LEFT (ric))->rname,
2345 (int) operandLitValue (IC_RIGHT (ic)));
2348 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2350 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2351 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2356 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2357 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2359 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2364 /*-----------------------------------------------------------------*/
2365 /* rematStr - returns the rematerialized string for a remat var */
2366 /*-----------------------------------------------------------------*/
2368 rematStr (symbol * sym)
2371 iCode *ic = sym->rematiCode;
2373 debugLog ("%s\n", __FUNCTION__);
2378 /* if plus or minus print the right hand side */
2380 if (ic->op == '+' || ic->op == '-') {
2381 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2384 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2388 if (ic->op == '+' || ic->op == '-')
2390 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2391 sprintf (s, "(%s %c 0x%04x)",
2392 OP_SYMBOL (IC_LEFT (ric))->rname,
2394 (int) operandLitValue (IC_RIGHT (ic)));
2397 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2399 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2403 /* we reached the end */
2404 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2408 printf ("%s\n", buffer);
2413 /*-----------------------------------------------------------------*/
2414 /* regTypeNum - computes the type & number of registers required */
2415 /*-----------------------------------------------------------------*/
2423 debugLog ("%s\n", __FUNCTION__);
2424 /* for each live range do */
2425 for (sym = hTabFirstItem (liveRanges, &k); sym;
2426 sym = hTabNextItem (liveRanges, &k)) {
2428 debugLog (" %d - %s\n", __LINE__, sym->rname);
2429 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2431 /* if used zero times then no registers needed */
2432 if ((sym->liveTo - sym->liveFrom) == 0)
2436 /* if the live range is a temporary */
2439 debugLog (" %d - itemp register\n", __LINE__);
2441 /* if the type is marked as a conditional */
2442 if (sym->regType == REG_CND)
2445 /* if used in return only then we don't
2447 if (sym->ruonly || sym->accuse) {
2448 if (IS_AGGREGATE (sym->type) || sym->isptr)
2449 sym->type = aggrToPtr (sym->type, FALSE);
2450 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2455 /* if the symbol has only one definition &
2456 that definition is a get_pointer and the
2457 pointer we are getting is rematerializable and
2460 if (bitVectnBitsOn (sym->defs) == 1 &&
2461 (ic = hTabItemWithKey (iCodehTab,
2462 bitVectFirstBit (sym->defs))) &&
2465 !IS_BITVAR (sym->etype)) {
2468 debugLog (" %d - \n", __LINE__);
2470 /* if remat in data space */
2471 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2472 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2474 /* create a psuedo symbol & force a spil */
2475 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2476 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2477 psym->type = sym->type;
2478 psym->etype = sym->etype;
2479 strcpy (psym->rname, psym->name);
2481 sym->usl.spillLoc = psym;
2485 /* if in data space or idata space then try to
2486 allocate pointer register */
2490 /* if not then we require registers */
2491 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2492 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2493 getSize (sym->type));
2497 if(IS_PTR_CONST (sym->type)) {
2499 if(IS_CODEPTR (sym->type)) {
2501 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2505 if (sym->nRegs > 4) {
2506 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2507 printTypeChain (sym->type, stderr);
2508 fprintf (stderr, "\n");
2511 /* determine the type of register required */
2512 if (sym->nRegs == 1 &&
2513 IS_PTR (sym->type) &&
2515 sym->regType = REG_PTR;
2517 sym->regType = REG_GPR;
2520 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2524 /* for the first run we don't provide */
2525 /* registers for true symbols we will */
2526 /* see how things go */
2531 static DEFSETFUNC (markRegFree)
2533 ((regs *)item)->isFree = 1;
2538 DEFSETFUNC (pic16_deallocReg)
2540 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2541 ((regs *)item)->isFree = 1;
2542 ((regs *)item)->wasUsed = 0;
2546 /*-----------------------------------------------------------------*/
2547 /* freeAllRegs - mark all registers as free */
2548 /*-----------------------------------------------------------------*/
2550 pic16_freeAllRegs ()
2552 debugLog ("%s\n", __FUNCTION__);
2554 applyToSet(pic16_dynAllocRegs,markRegFree);
2555 applyToSet(pic16_dynStackRegs,markRegFree);
2558 /*-----------------------------------------------------------------*/
2559 /*-----------------------------------------------------------------*/
2561 pic16_deallocateAllRegs ()
2563 debugLog ("%s\n", __FUNCTION__);
2565 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2569 /*-----------------------------------------------------------------*/
2570 /* deallocStackSpil - this will set the stack pointer back */
2571 /*-----------------------------------------------------------------*/
2573 DEFSETFUNC (deallocStackSpil)
2577 debugLog ("%s\n", __FUNCTION__);
2582 /*-----------------------------------------------------------------*/
2583 /* farSpacePackable - returns the packable icode for far variables */
2584 /*-----------------------------------------------------------------*/
2586 farSpacePackable (iCode * ic)
2590 debugLog ("%s\n", __FUNCTION__);
2591 /* go thru till we find a definition for the
2592 symbol on the right */
2593 for (dic = ic->prev; dic; dic = dic->prev)
2596 /* if the definition is a call then no */
2597 if ((dic->op == CALL || dic->op == PCALL) &&
2598 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2603 /* if shift by unknown amount then not */
2604 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2605 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2608 /* if pointer get and size > 1 */
2609 if (POINTER_GET (dic) &&
2610 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2613 if (POINTER_SET (dic) &&
2614 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2617 /* if any three is a true symbol in far space */
2618 if (IC_RESULT (dic) &&
2619 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2620 isOperandInFarSpace (IC_RESULT (dic)))
2623 if (IC_RIGHT (dic) &&
2624 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2625 isOperandInFarSpace (IC_RIGHT (dic)) &&
2626 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2629 if (IC_LEFT (dic) &&
2630 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2631 isOperandInFarSpace (IC_LEFT (dic)) &&
2632 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2635 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2637 if ((dic->op == LEFT_OP ||
2638 dic->op == RIGHT_OP ||
2640 IS_OP_LITERAL (IC_RIGHT (dic)))
2650 /*-----------------------------------------------------------------*/
2651 /* packRegsForAssign - register reduction for assignment */
2652 /*-----------------------------------------------------------------*/
2654 packRegsForAssign (iCode * ic, eBBlock * ebp)
2659 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2660 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2661 debugAopGet (" result:", IC_RESULT (ic));
2662 debugAopGet (" left:", IC_LEFT (ic));
2663 debugAopGet (" right:", IC_RIGHT (ic));
2665 /* if this is at an absolute address, then get the address. */
2666 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2667 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2668 debugLog (" %d - found config word declaration\n", __LINE__);
2669 if(IS_VALOP(IC_RIGHT(ic))) {
2670 debugLog (" setting config word to %x\n",
2671 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2672 fprintf(stderr, " setting config word to %x\n",
2673 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2674 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2675 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2679 debugLog(" %d\n", __LINE__);
2681 /* remove the assignment from the iCode chain. */
2683 remiCodeFromeBBlock (ebp, ic);
2684 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2685 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2691 debugLog(" %d - actuall processing\n", __LINE__ );
2693 if (!IS_ITEMP (IC_RESULT (ic))) {
2694 pic16_allocDirReg(IC_RESULT (ic));
2695 debugLog (" %d - result is not temp\n", __LINE__);
2699 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2700 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2701 pic16_allocDirReg(IC_LEFT (ic));
2705 /* See BUGLOG0001 - VR */
2707 if (!IS_ITEMP (IC_RIGHT (ic))) {
2708 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2709 pic16_allocDirReg(IC_RIGHT (ic));
2714 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2715 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2717 debugLog (" %d - not packing - right side fails \n", __LINE__);
2721 /* if the true symbol is defined in far space or on stack
2722 then we should not since this will increase register pressure */
2723 if (isOperandInFarSpace (IC_RESULT (ic)))
2725 if ((dic = farSpacePackable (ic)))
2733 if(ic->op == CALL || ic->op == PCALL) {
2734 addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic)));
2735 debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name);
2740 /* find the definition of iTempNN scanning backwards if we find a
2741 a use of the true symbol before we find the definition then
2743 for (dic = ic->prev; dic; dic = dic->prev)
2746 /* if there is a function call and this is
2747 a parameter & not my parameter then don't pack it */
2748 if ((dic->op == CALL || dic->op == PCALL) &&
2749 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2750 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2752 debugLog (" %d - \n", __LINE__);
2761 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2764 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2765 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2766 debugAopGet(" result is ", IC_RESULT(dic));
2768 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2769 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2770 debugAopGet(" left is ", IC_LEFT(dic));
2772 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2773 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2774 debugAopGet(" right is ", IC_RIGHT(dic));
2778 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2779 IS_OP_VOLATILE (IC_RESULT (dic)))
2781 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2787 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2788 IS_OP_VOLATILE (IC_RIGHT(dic)))
2790 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2797 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2798 IS_OP_VOLATILE (IC_LEFT(dic)))
2800 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2806 if (IS_SYMOP (IC_RESULT (dic)) &&
2807 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2809 /* A previous result was assigned to the same register - we'll our definition */
2810 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2811 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2812 if (POINTER_SET (dic))
2818 if (IS_SYMOP (IC_RIGHT (dic)) &&
2819 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2820 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2822 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2827 if (IS_SYMOP (IC_LEFT (dic)) &&
2828 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2829 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2831 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2836 if (POINTER_SET (dic) &&
2837 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2839 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2847 return 0; /* did not find */
2849 /* if the result is on stack or iaccess then it must be
2850 the same atleast one of the operands */
2851 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2852 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2855 /* the operation has only one symbol
2856 operator then we can pack */
2857 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2858 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2861 if (!((IC_LEFT (dic) &&
2862 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2864 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2868 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2869 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2870 /* found the definition */
2871 /* replace the result with the result of */
2872 /* this assignment and remove this assignment */
2873 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2874 IC_RESULT (dic) = IC_RESULT (ic);
2876 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2878 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2880 /* delete from liverange table also
2881 delete from all the points inbetween and the new
2883 for (sic = dic; sic != ic; sic = sic->next)
2885 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2886 if (IS_ITEMP (IC_RESULT (dic)))
2887 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2890 remiCodeFromeBBlock (ebp, ic);
2891 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2893 debugLog(" %d\n", __LINE__ );
2894 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2895 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2901 /*-----------------------------------------------------------------*/
2902 /* findAssignToSym : scanning backwards looks for first assig found */
2903 /*-----------------------------------------------------------------*/
2905 findAssignToSym (operand * op, iCode * ic)
2909 debugLog ("%s\n", __FUNCTION__);
2910 for (dic = ic->prev; dic; dic = dic->prev)
2913 /* if definition by assignment */
2914 if (dic->op == '=' &&
2915 !POINTER_SET (dic) &&
2916 IC_RESULT (dic)->key == op->key
2917 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2921 /* we are interested only if defined in far space */
2922 /* or in stack space in case of + & - */
2924 /* if assigned to a non-symbol then return
2926 if (!IS_SYMOP (IC_RIGHT (dic)))
2929 /* if the symbol is in far space then
2931 if (isOperandInFarSpace (IC_RIGHT (dic)))
2934 /* for + & - operations make sure that
2935 if it is on the stack it is the same
2936 as one of the three operands */
2937 if ((ic->op == '+' || ic->op == '-') &&
2938 OP_SYMBOL (IC_RIGHT (dic))->onStack)
2941 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2942 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2943 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2951 /* if we find an usage then we cannot delete it */
2952 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2955 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2958 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2962 /* now make sure that the right side of dic
2963 is not defined between ic & dic */
2966 iCode *sic = dic->next;
2968 for (; sic != ic; sic = sic->next)
2969 if (IC_RESULT (sic) &&
2970 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2979 /*-----------------------------------------------------------------*/
2980 /* packRegsForSupport :- reduce some registers for support calls */
2981 /*-----------------------------------------------------------------*/
2983 packRegsForSupport (iCode * ic, eBBlock * ebp)
2987 debugLog ("%s\n", __FUNCTION__);
2988 /* for the left & right operand :- look to see if the
2989 left was assigned a true symbol in far space in that
2990 case replace them */
2991 if (IS_ITEMP (IC_LEFT (ic)) &&
2992 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2994 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3000 debugAopGet ("removing left:", IC_LEFT (ic));
3002 /* found it we need to remove it from the
3004 for (sic = dic; sic != ic; sic = sic->next)
3005 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3007 IC_LEFT (ic)->operand.symOperand =
3008 IC_RIGHT (dic)->operand.symOperand;
3009 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3010 remiCodeFromeBBlock (ebp, dic);
3011 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3012 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3016 /* do the same for the right operand */
3019 IS_ITEMP (IC_RIGHT (ic)) &&
3020 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3022 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3028 /* if this is a subtraction & the result
3029 is a true symbol in far space then don't pack */
3030 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3032 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3033 if (IN_FARSPACE (SPEC_OCLS (etype)))
3037 debugAopGet ("removing right:", IC_RIGHT (ic));
3039 /* found it we need to remove it from the
3041 for (sic = dic; sic != ic; sic = sic->next)
3042 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3044 IC_RIGHT (ic)->operand.symOperand =
3045 IC_RIGHT (dic)->operand.symOperand;
3046 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3048 remiCodeFromeBBlock (ebp, dic);
3049 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3050 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3057 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3060 /*-----------------------------------------------------------------*/
3061 /* packRegsForOneuse : - will reduce some registers for single Use */
3062 /*-----------------------------------------------------------------*/
3064 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3069 debugLog ("%s\n", __FUNCTION__);
3070 /* if returning a literal then do nothing */
3074 /* only upto 2 bytes since we cannot predict
3075 the usage of b, & acc */
3076 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3081 /* this routine will mark the a symbol as used in one
3082 instruction use only && if the definition is local
3083 (ie. within the basic block) && has only one definition &&
3084 that definition is either a return value from a
3085 function or does not contain any variables in
3087 uses = bitVectCopy (OP_USES (op));
3088 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3089 if (!bitVectIsZero (uses)) /* has other uses */
3092 /* if it has only one defintion */
3093 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3094 return NULL; /* has more than one definition */
3096 /* get that definition */
3098 hTabItemWithKey (iCodehTab,
3099 bitVectFirstBit (OP_DEFS (op)))))
3102 /* found the definition now check if it is local */
3103 if (dic->seq < ebp->fSeq ||
3104 dic->seq > ebp->lSeq)
3105 return NULL; /* non-local */
3107 /* now check if it is the return from
3109 if (dic->op == CALL || dic->op == PCALL)
3111 if (ic->op != SEND && ic->op != RETURN &&
3112 !POINTER_SET(ic) && !POINTER_GET(ic))
3114 OP_SYMBOL (op)->ruonly = 1;
3121 /* otherwise check that the definition does
3122 not contain any symbols in far space */
3123 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3124 isOperandInFarSpace (IC_RIGHT (dic)) ||
3125 IS_OP_RUONLY (IC_LEFT (ic)) ||
3126 IS_OP_RUONLY (IC_RIGHT (ic)))
3131 /* if pointer set then make sure the pointer
3133 if (POINTER_SET (dic) &&
3134 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3137 if (POINTER_GET (dic) &&
3138 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3143 /* also make sure the intervenening instructions
3144 don't have any thing in far space */
3145 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3148 /* if there is an intervening function call then no */
3149 if (dic->op == CALL || dic->op == PCALL)
3151 /* if pointer set then make sure the pointer
3153 if (POINTER_SET (dic) &&
3154 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3157 if (POINTER_GET (dic) &&
3158 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3161 /* if address of & the result is remat then okay */
3162 if (dic->op == ADDRESS_OF &&
3163 OP_SYMBOL (IC_RESULT (dic))->remat)
3166 /* if operand has size of three or more & this
3167 operation is a '*','/' or '%' then 'b' may
3169 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3170 getSize (operandType (op)) >= 3)
3173 /* if left or right or result is in far space */
3174 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3175 isOperandInFarSpace (IC_RIGHT (dic)) ||
3176 isOperandInFarSpace (IC_RESULT (dic)) ||
3177 IS_OP_RUONLY (IC_LEFT (dic)) ||
3178 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3179 IS_OP_RUONLY (IC_RESULT (dic)))
3185 OP_SYMBOL (op)->ruonly = 1;
3190 /*-----------------------------------------------------------------*/
3191 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3192 /*-----------------------------------------------------------------*/
3194 isBitwiseOptimizable (iCode * ic)
3196 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3197 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3199 debugLog ("%s\n", __FUNCTION__);
3200 /* bitwise operations are considered optimizable
3201 under the following conditions (Jean-Louis VERN)
3213 if (IS_LITERAL (rtype) ||
3214 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3220 /*-----------------------------------------------------------------*/
3221 /* packRegsForAccUse - pack registers for acc use */
3222 /*-----------------------------------------------------------------*/
3224 packRegsForAccUse (iCode * ic)
3228 debugLog ("%s\n", __FUNCTION__);
3230 /* if this is an aggregate, e.g. a one byte char array */
3231 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3234 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3236 /* if + or - then it has to be one byte result */
3237 if ((ic->op == '+' || ic->op == '-')
3238 && getSize (operandType (IC_RESULT (ic))) > 1)
3241 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3242 /* if shift operation make sure right side is not a literal */
3243 if (ic->op == RIGHT_OP &&
3244 (isOperandLiteral (IC_RIGHT (ic)) ||
3245 getSize (operandType (IC_RESULT (ic))) > 1))
3248 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3249 if (ic->op == LEFT_OP &&
3250 (isOperandLiteral (IC_RIGHT (ic)) ||
3251 getSize (operandType (IC_RESULT (ic))) > 1))
3254 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3255 if (IS_BITWISE_OP (ic) &&
3256 getSize (operandType (IC_RESULT (ic))) > 1)
3260 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3261 /* has only one definition */
3262 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3265 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3266 /* has only one use */
3267 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3270 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3271 /* and the usage immediately follows this iCode */
3272 if (!(uic = hTabItemWithKey (iCodehTab,
3273 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3276 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3277 if (ic->next != uic)
3280 /* if it is a conditional branch then we definitely can */
3284 if (uic->op == JUMPTABLE)
3287 /* if the usage is not is an assignment
3288 or an arithmetic / bitwise / shift operation then not */
3289 if (POINTER_SET (uic) &&
3290 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3293 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3294 if (uic->op != '=' &&
3295 !IS_ARITHMETIC_OP (uic) &&
3296 !IS_BITWISE_OP (uic) &&
3297 uic->op != LEFT_OP &&
3298 uic->op != RIGHT_OP)
3301 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3302 /* if used in ^ operation then make sure right is not a
3304 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3307 /* if shift operation make sure right side is not a literal */
3308 if (uic->op == RIGHT_OP &&
3309 (isOperandLiteral (IC_RIGHT (uic)) ||
3310 getSize (operandType (IC_RESULT (uic))) > 1))
3313 if (uic->op == LEFT_OP &&
3314 (isOperandLiteral (IC_RIGHT (uic)) ||
3315 getSize (operandType (IC_RESULT (uic))) > 1))
3318 /* make sure that the result of this icode is not on the
3319 stack, since acc is used to compute stack offset */
3320 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3321 OP_SYMBOL (IC_RESULT (uic))->onStack)
3324 /* if either one of them in far space then we cannot */
3325 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3326 isOperandInFarSpace (IC_LEFT (uic))) ||
3327 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3328 isOperandInFarSpace (IC_RIGHT (uic))))
3331 /* if the usage has only one operand then we can */
3332 if (IC_LEFT (uic) == NULL ||
3333 IC_RIGHT (uic) == NULL)
3336 /* make sure this is on the left side if not
3337 a '+' since '+' is commutative */
3338 if (ic->op != '+' &&
3339 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3342 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3343 /* if one of them is a literal then we can */
3344 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3345 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3346 (getSize (operandType (IC_RESULT (uic))) <= 1))
3348 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3352 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3353 /* if the other one is not on stack then we can */
3354 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3355 (IS_ITEMP (IC_RIGHT (uic)) ||
3356 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3357 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3360 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3361 (IS_ITEMP (IC_LEFT (uic)) ||
3362 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3363 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3369 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3370 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3375 /*-----------------------------------------------------------------*/
3376 /* packForPush - hueristics to reduce iCode for pushing */
3377 /*-----------------------------------------------------------------*/
3379 packForReceive (iCode * ic, eBBlock * ebp)
3383 debugLog ("%s\n", __FUNCTION__);
3384 debugAopGet (" result:", IC_RESULT (ic));
3385 debugAopGet (" left:", IC_LEFT (ic));
3386 debugAopGet (" right:", IC_RIGHT (ic));
3391 for (dic = ic->next; dic; dic = dic->next)
3396 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3397 debugLog (" used on left\n");
3398 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3399 debugLog (" used on right\n");
3400 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3401 debugLog (" used on result\n");
3403 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3404 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3409 debugLog (" hey we can remove this unnecessary assign\n");
3411 /*-----------------------------------------------------------------*/
3412 /* packForPush - hueristics to reduce iCode for pushing */
3413 /*-----------------------------------------------------------------*/
3415 packForPush (iCode * ic, eBBlock * ebp)
3419 debugLog ("%s\n", __FUNCTION__);
3420 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3423 /* must have only definition & one usage */
3424 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3425 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3428 /* find the definition */
3429 if (!(dic = hTabItemWithKey (iCodehTab,
3430 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3433 if (dic->op != '=' || POINTER_SET (dic))
3436 /* we now we know that it has one & only one def & use
3437 and the that the definition is an assignment */
3438 IC_LEFT (ic) = IC_RIGHT (dic);
3440 remiCodeFromeBBlock (ebp, dic);
3441 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3442 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3445 static void printSymType(char * str, sym_link *sl)
3447 if(!pic16_ralloc_debug)return;
3449 debugLog (" %s Symbol type: ",str);
3450 printTypeChain( sl, debugF);
3454 /*-----------------------------------------------------------------*/
3455 /* some debug code to print the symbol S_TYPE. Note that
3456 * the function checkSClass in src/SDCCsymt.c dinks with
3457 * the S_TYPE in ways the PIC port doesn't fully like...*/
3458 /*-----------------------------------------------------------------*/
3459 static void isData(sym_link *sl)
3463 if(!pic16_ralloc_debug)return;
3470 for ( ; sl; sl=sl->next) {
3472 switch (SPEC_SCLS(sl)) {
3473 case S_DATA: fprintf (of, "data "); break;
3474 case S_XDATA: fprintf (of, "xdata "); break;
3475 case S_SFR: fprintf (of, "sfr "); break;
3476 case S_SBIT: fprintf (of, "sbit "); break;
3477 case S_CODE: fprintf (of, "code "); break;
3478 case S_IDATA: fprintf (of, "idata "); break;
3479 case S_PDATA: fprintf (of, "pdata "); break;
3480 case S_LITERAL: fprintf (of, "literal "); break;
3481 case S_STACK: fprintf (of, "stack "); break;
3482 case S_XSTACK: fprintf (of, "xstack "); break;
3483 case S_BIT: fprintf (of, "bit "); break;
3484 case S_EEPROM: fprintf (of, "eeprom "); break;
3492 /*--------------------------------------------------------------------*/
3493 /* pic16_packRegisters - does some transformations to reduce */
3494 /* register pressure */
3496 /*--------------------------------------------------------------------*/
3498 pic16_packRegisters (eBBlock * ebp)
3503 debugLog ("%s\n", __FUNCTION__);
3509 /* look for assignments of the form */
3510 /* iTempNN = TRueSym (someoperation) SomeOperand */
3512 /* TrueSym := iTempNN:1 */
3513 for (ic = ebp->sch; ic; ic = ic->next)
3515 // debugLog("%d\n", __LINE__);
3516 /* find assignment of the form TrueSym := iTempNN:1 */
3517 /* see BUGLOG0001 for workaround with the CAST - VR */
3518 if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3519 change += packRegsForAssign (ic, ebp);
3523 if (POINTER_SET (ic))
3524 debugLog ("pointer is set\n");
3525 debugAopGet (" result:", IC_RESULT (ic));
3526 debugAopGet (" left:", IC_LEFT (ic));
3527 debugAopGet (" right:", IC_RIGHT (ic));
3536 for (ic = ebp->sch; ic; ic = ic->next) {
3538 if(IS_SYMOP ( IC_LEFT(ic))) {
3539 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3541 debugAopGet ("x left:", IC_LEFT (ic));
3543 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3545 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3547 debugLog (" is a pointer\n");
3549 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3550 debugLog (" is a ptr\n");
3552 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3553 debugLog (" is volatile\n");
3557 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3558 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3559 pic16_allocDirReg(IC_LEFT (ic));
3562 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3565 if(IS_SYMOP ( IC_RIGHT(ic))) {
3566 debugAopGet (" right:", IC_RIGHT (ic));
3567 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3570 if(IS_SYMOP ( IC_RESULT(ic))) {
3571 debugAopGet (" result:", IC_RESULT (ic));
3572 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3575 if (POINTER_SET (ic))
3576 debugLog (" %d - Pointer set\n", __LINE__);
3579 /* if this is an itemp & result of a address of a true sym
3580 then mark this as rematerialisable */
3581 if (ic->op == ADDRESS_OF &&
3582 IS_ITEMP (IC_RESULT (ic)) &&
3583 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3584 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3585 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3588 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3590 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3591 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3592 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3596 /* if straight assignment then carry remat flag if
3597 this is the only definition */
3598 if (ic->op == '=' &&
3599 !POINTER_SET (ic) &&
3600 IS_SYMOP (IC_RIGHT (ic)) &&
3601 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3602 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3604 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3606 OP_SYMBOL (IC_RESULT (ic))->remat =
3607 OP_SYMBOL (IC_RIGHT (ic))->remat;
3608 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3609 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3612 /* if this is a +/- operation with a rematerizable
3613 then mark this as rematerializable as well */
3614 if ((ic->op == '+' || ic->op == '-') &&
3615 (IS_SYMOP (IC_LEFT (ic)) &&
3616 IS_ITEMP (IC_RESULT (ic)) &&
3617 OP_SYMBOL (IC_LEFT (ic))->remat &&
3618 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3619 IS_OP_LITERAL (IC_RIGHT (ic))))
3621 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3623 operandLitValue (IC_RIGHT (ic));
3624 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3625 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3626 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3629 /* mark the pointer usages */
3630 if (POINTER_SET (ic))
3632 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3633 debugLog (" marking as a pointer (set) =>");
3634 debugAopGet (" result:", IC_RESULT (ic));
3636 if (POINTER_GET (ic))
3638 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3639 debugLog (" marking as a pointer (get) =>");
3640 debugAopGet (" left:", IC_LEFT (ic));
3643 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3647 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3648 /* if we are using a symbol on the stack
3649 then we should say pic16_ptrRegReq */
3650 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3651 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3652 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3653 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3654 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3655 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3659 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3660 if (IS_SYMOP (IC_LEFT (ic)))
3661 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3662 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3663 if (IS_SYMOP (IC_RIGHT (ic)))
3664 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3665 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3666 if (IS_SYMOP (IC_RESULT (ic)))
3667 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3668 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3671 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3675 /* if the condition of an if instruction
3676 is defined in the previous instruction then
3677 mark the itemp as a conditional */
3678 if ((IS_CONDITIONAL (ic) ||
3679 ((ic->op == BITWISEAND ||
3682 isBitwiseOptimizable (ic))) &&
3683 ic->next && ic->next->op == IFX &&
3684 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3685 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3688 debugLog (" %d\n", __LINE__);
3689 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3693 debugLog(" %d\n", __LINE__);
3695 /* reduce for support function calls */
3696 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3697 packRegsForSupport (ic, ebp);
3699 /* if a parameter is passed, it's in W, so we may not
3700 need to place a copy in a register */
3701 if (ic->op == RECEIVE)
3702 packForReceive (ic, ebp);
3704 /* some cases the redundant moves can
3705 can be eliminated for return statements */
3706 if ((ic->op == RETURN || ic->op == SEND) &&
3707 !isOperandInFarSpace (IC_LEFT (ic)) &&
3709 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3711 /* if pointer set & left has a size more than
3712 one and right is not in far space */
3713 if (POINTER_SET (ic) &&
3714 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3715 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3716 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3717 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3719 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3721 /* if pointer get */
3722 if (POINTER_GET (ic) &&
3723 !isOperandInFarSpace (IC_RESULT (ic)) &&
3724 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3725 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3726 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3728 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3729 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3731 /* if this is cast for intergral promotion then
3732 check if only use of the definition of the
3733 operand being casted/ if yes then replace
3734 the result of that arithmetic operation with
3735 this result and get rid of the cast */
3736 if (ic->op == CAST) {
3738 sym_link *fromType = operandType (IC_RIGHT (ic));
3739 sym_link *toType = operandType (IC_LEFT (ic));
3741 debugLog (" %d - casting\n", __LINE__);
3743 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3744 getSize (fromType) != getSize (toType)) {
3747 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3750 if (IS_ARITHMETIC_OP (dic)) {
3751 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3753 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3754 IC_RESULT (dic) = IC_RESULT (ic);
3755 remiCodeFromeBBlock (ebp, ic);
3756 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3757 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3758 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3762 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3766 /* if the type from and type to are the same
3767 then if this is the only use then packit */
3768 if (compareType (operandType (IC_RIGHT (ic)),
3769 operandType (IC_LEFT (ic))) == 1) {
3771 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3774 debugLog(" %d\n", __LINE__);
3776 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3777 IC_RESULT (dic) = IC_RESULT (ic);
3778 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3779 remiCodeFromeBBlock (ebp, ic);
3780 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3781 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3789 iTempNN := (some variable in farspace) V1
3794 if (ic->op == IPUSH)
3796 packForPush (ic, ebp);
3800 /* pack registers for accumulator use, when the
3801 result of an arithmetic or bit wise operation
3802 has only one use, that use is immediately following
3803 the defintion and the using iCode has only one
3804 operand or has two operands but one is literal &
3805 the result of that operation is not on stack then
3806 we can leave the result of this operation in acc:b
3808 if ((IS_ARITHMETIC_OP (ic)
3810 || IS_BITWISE_OP (ic)
3812 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3815 IS_ITEMP (IC_RESULT (ic)) &&
3816 getSize (operandType (IC_RESULT (ic))) <= 2)
3818 packRegsForAccUse (ic);
3824 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3828 if (!pic16_ralloc_debug || !debugF)
3831 for (i = 0; i < count; i++)
3833 fprintf (debugF, "\n----------------------------------------------------------------\n");
3834 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3835 ebbs[i]->entryLabel->name,
3838 ebbs[i]->isLastInLoop);
3839 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3844 fprintf (debugF, "visited %d : hasFcall = %d\n",
3848 fprintf (debugF, "\ndefines bitVector :");
3849 bitVectDebugOn (ebbs[i]->defSet, debugF);
3850 fprintf (debugF, "\nlocal defines bitVector :");
3851 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3852 fprintf (debugF, "\npointers Set bitvector :");
3853 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3854 fprintf (debugF, "\nin pointers Set bitvector :");
3855 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3856 fprintf (debugF, "\ninDefs Set bitvector :");
3857 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3858 fprintf (debugF, "\noutDefs Set bitvector :");
3859 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3860 fprintf (debugF, "\nusesDefs Set bitvector :");
3861 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3862 fprintf (debugF, "\n----------------------------------------------------------------\n");
3863 printiCChain (ebbs[i]->sch, debugF);
3866 /*-----------------------------------------------------------------*/
3867 /* pic16_assignRegisters - assigns registers to each live range as need */
3868 /*-----------------------------------------------------------------*/
3870 pic16_assignRegisters (eBBlock ** ebbs, int count)
3875 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3876 debugLog ("\nebbs before optimizing:\n");
3877 dumpEbbsToDebug (ebbs, count);
3879 setToNull ((void *) &_G.funcrUsed);
3880 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3883 /* change assignments this will remove some
3884 live ranges reducing some register pressure */
3885 for (i = 0; i < count; i++)
3886 pic16_packRegisters (ebbs[i]);
3893 debugLog("dir registers allocated so far:\n");
3894 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3897 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3898 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3899 reg = hTabNextItem(dynDirectRegNames, &hkey);
3904 /* liveranges probably changed by register packing
3905 so we compute them again */
3906 recomputeLiveRanges (ebbs, count);
3908 if (options.dump_pack)
3909 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3911 /* first determine for each live range the number of
3912 registers & the type of registers required for each */
3915 /* and serially allocate registers */
3916 serialRegAssign (ebbs, count);
3918 //pic16_freeAllRegs();
3920 /* if stack was extended then tell the user */
3923 /* werror(W_TOOMANY_SPILS,"stack", */
3924 /* _G.stackExtend,currFunc->name,""); */
3930 /* werror(W_TOOMANY_SPILS,"data space", */
3931 /* _G.dataExtend,currFunc->name,""); */
3935 /* after that create the register mask
3936 for each of the instruction */
3937 createRegMask (ebbs, count);
3939 /* redo that offsets for stacked automatic variables */
3940 redoStackOffsets ();
3942 if (options.dump_rassgn)
3943 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3945 /* now get back the chain */
3946 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3948 debugLog ("ebbs after optimizing:\n");
3949 dumpEbbsToDebug (ebbs, count);
3954 /* free up any _G.stackSpil locations allocated */
3955 applyToSet (_G.stackSpil, deallocStackSpil);
3957 setToNull ((void *) &_G.stackSpil);
3958 setToNull ((void *) &_G.spiltSet);
3959 /* mark all registers as free */
3960 pic16_freeAllRegs ();
3962 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");