1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
34 #define FENTRY2 1 ? (void)0 : printf
36 /* this should go in SDCCicode.h, but it doesn't. */
37 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
39 /*-----------------------------------------------------------------*/
40 /* At this point we start getting processor specific although */
41 /* some routines are non-processor specific & can be reused when */
42 /* targetting other processors. The decision for this will have */
43 /* to be made on a routine by routine basis */
44 /* routines used to pack registers are most definitely not reusable */
45 /* since the pack the registers depending strictly on the MCU */
46 /*-----------------------------------------------------------------*/
48 extern void genpic14Code (iCode *);
49 extern void pic14_assignConfigWordValue(int address, int value);
59 bitVect *funcrUsed; /* registers used in a function */
65 /* Shared with gen.c */
66 int pic14_ptrRegReq; /* one byte pointer register required */
69 set *dynAllocRegs=NULL;
70 set *dynStackRegs=NULL;
71 set *dynProcessorRegs=NULL;
72 set *dynDirectRegs=NULL;
73 set *dynDirectBitRegs=NULL;
74 set *dynInternalRegs=NULL;
76 static hTab *dynDirectRegNames= NULL;
77 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
79 static int dynrIdx = 0x1000;
81 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
83 int Gstack_base_addr=0; /* The starting address of registers that
84 * are used to pass and return parameters */
90 static void spillThis (symbol *);
92 static FILE *debugF = NULL;
93 /*-----------------------------------------------------------------*/
94 /* debugLog - open a file for debugging information */
95 /*-----------------------------------------------------------------*/
96 //static void debugLog(char *inst,char *fmt, ...)
98 debugLog (char *fmt,...)
100 static int append = 0; // First time through, open the file without append.
103 //char *bufferP=buffer;
106 if (!debug || !dstFileName)
112 /* create the file name */
113 strcpy (buffer, dstFileName);
114 strcat (buffer, ".d");
116 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
118 werror (E_FILE_OPEN_ERR, buffer);
121 append = 1; // Next time debubLog is called, we'll append the debug info
127 vsprintf (buffer, fmt, ap);
129 fprintf (debugF, "%s", buffer);
130 //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
132 while (isspace((unsigned char)*bufferP)) bufferP++;
134 if (bufferP && *bufferP)
135 lineCurr = (lineCurr ?
136 connectLine(lineCurr,newLineNode(lb)) :
137 (lineHead = newLineNode(lb)));
138 lineCurr->isInline = _G.inLine;
139 lineCurr->isDebug = _G.debugLine;
149 fputc ('\n', debugF);
151 /*-----------------------------------------------------------------*/
152 /* debugLogClose - closes the debug log file (if opened) */
153 /*-----------------------------------------------------------------*/
163 #define AOP(op) op->aop
166 debugAopGet (char *str, operand * op)
171 printOperand (op, debugF);
179 decodeOp (unsigned int op)
182 if (op < 128 && op > ' ')
184 buffer[0] = (op & 0xff);
191 case IDENTIFIER: return "IDENTIFIER";
192 case TYPE_NAME: return "TYPE_NAME";
193 case CONSTANT: return "CONSTANT";
194 case STRING_LITERAL: return "STRING_LITERAL";
195 case SIZEOF: return "SIZEOF";
196 case PTR_OP: return "PTR_OP";
197 case INC_OP: return "INC_OP";
198 case DEC_OP: return "DEC_OP";
199 case LEFT_OP: return "LEFT_OP";
200 case RIGHT_OP: return "RIGHT_OP";
201 case LE_OP: return "LE_OP";
202 case GE_OP: return "GE_OP";
203 case EQ_OP: return "EQ_OP";
204 case NE_OP: return "NE_OP";
205 case AND_OP: return "AND_OP";
206 case OR_OP: return "OR_OP";
207 case MUL_ASSIGN: return "MUL_ASSIGN";
208 case DIV_ASSIGN: return "DIV_ASSIGN";
209 case MOD_ASSIGN: return "MOD_ASSIGN";
210 case ADD_ASSIGN: return "ADD_ASSIGN";
211 case SUB_ASSIGN: return "SUB_ASSIGN";
212 case LEFT_ASSIGN: return "LEFT_ASSIGN";
213 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
214 case AND_ASSIGN: return "AND_ASSIGN";
215 case XOR_ASSIGN: return "XOR_ASSIGN";
216 case OR_ASSIGN: return "OR_ASSIGN";
217 case TYPEDEF: return "TYPEDEF";
218 case EXTERN: return "EXTERN";
219 case STATIC: return "STATIC";
220 case AUTO: return "AUTO";
221 case REGISTER: return "REGISTER";
222 case CODE: return "CODE";
223 case EEPROM: return "EEPROM";
224 case INTERRUPT: return "INTERRUPT";
225 case SFR: return "SFR";
226 case AT: return "AT";
227 case SBIT: return "SBIT";
228 case REENTRANT: return "REENTRANT";
229 case USING: return "USING";
230 case XDATA: return "XDATA";
231 case DATA: return "DATA";
232 case IDATA: return "IDATA";
233 case PDATA: return "PDATA";
234 case VAR_ARGS: return "VAR_ARGS";
235 case CRITICAL: return "CRITICAL";
236 case NONBANKED: return "NONBANKED";
237 case BANKED: return "BANKED";
238 case CHAR: return "CHAR";
239 case SHORT: return "SHORT";
240 case INT: return "INT";
241 case LONG: return "LONG";
242 case SIGNED: return "SIGNED";
243 case UNSIGNED: return "UNSIGNED";
244 case FLOAT: return "FLOAT";
245 case DOUBLE: return "DOUBLE";
246 case CONST: return "CONST";
247 case VOLATILE: return "VOLATILE";
248 case VOID: return "VOID";
249 case BIT: return "BIT";
250 case STRUCT: return "STRUCT";
251 case UNION: return "UNION";
252 case ENUM: return "ENUM";
253 case RANGE: return "RANGE";
254 case FAR: return "FAR";
255 case CASE: return "CASE";
256 case DEFAULT: return "DEFAULT";
257 case IF: return "IF";
258 case ELSE: return "ELSE";
259 case SWITCH: return "SWITCH";
260 case WHILE: return "WHILE";
261 case DO: return "DO";
262 case FOR: return "FOR";
263 case GOTO: return "GOTO";
264 case CONTINUE: return "CONTINUE";
265 case BREAK: return "BREAK";
266 case RETURN: return "RETURN";
267 case INLINEASM: return "INLINEASM";
268 case IFX: return "IFX";
269 case ADDRESS_OF: return "ADDRESS_OF";
270 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
271 case SPIL: return "SPIL";
272 case UNSPIL: return "UNSPIL";
273 case GETHBIT: return "GETHBIT";
274 case BITWISEAND: return "BITWISEAND";
275 case UNARYMINUS: return "UNARYMINUS";
276 case IPUSH: return "IPUSH";
277 case IPOP: return "IPOP";
278 case PCALL: return "PCALL";
279 case ENDFUNCTION: return "ENDFUNCTION";
280 case JUMPTABLE: return "JUMPTABLE";
281 case RRC: return "RRC";
282 case RLC: return "RLC";
283 case CAST: return "CAST";
284 case CALL: return "CALL";
285 case PARAM: return "PARAM ";
286 case NULLOP: return "NULLOP";
287 case BLOCK: return "BLOCK";
288 case LABEL: return "LABEL";
289 case RECEIVE: return "RECEIVE";
290 case SEND: return "SEND";
292 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
295 /*-----------------------------------------------------------------*/
296 /*-----------------------------------------------------------------*/
298 debugLogRegType (short type)
303 case REG_GPR: return "REG_GPR";
304 case REG_PTR: return "REG_PTR";
305 case REG_CND: return "REG_CND";
308 sprintf (buffer, "unknown reg type %d", type);
312 /*-----------------------------------------------------------------*/
313 /*-----------------------------------------------------------------*/
314 static int regname2key(char const *name)
323 key += (*name++) + 1;
327 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
331 static regs *regWithIdx (set *dRegs, int idx, int fixed);
332 /*-----------------------------------------------------------------*/
333 /* newReg - allocate and init memory for a new register */
334 /*-----------------------------------------------------------------*/
335 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
338 regs *dReg, *reg_alias;
340 /* check whether a matching register already exists */
341 dReg = dirregWithName( name );
343 //printf( "%s: already present: %s\n", __FUNCTION__, name );
347 // check whether a register at that location exists
348 reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
349 if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
351 // create a new register
352 dReg = Safe_calloc(1,sizeof(regs));
354 dReg->pc_type = pc_type;
357 dReg->name = Safe_strdup(name);
359 sprintf(buffer,"r0x%02X", dReg->rIdx);
360 dReg->name = Safe_strdup(buffer);
376 dReg->reg_alias = reg_alias;
377 dReg->reglives.usedpFlows = newSet();
378 dReg->reglives.assignedpFlows = newSet();
379 if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
380 debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
385 /*-----------------------------------------------------------------*/
386 /* regWithIdx - Search through a set of registers that matches idx */
387 /*-----------------------------------------------------------------*/
389 regWithIdx (set *dRegs, int idx, int fixed)
393 for (dReg = setFirstItem(dRegs) ; dReg ;
394 dReg = setNextItem(dRegs)) {
396 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
397 while (dReg->reg_alias) dReg = dReg->reg_alias;
405 /*-----------------------------------------------------------------*/
406 /* regWithName - Search through a set of registers that matches name */
407 /*-----------------------------------------------------------------*/
409 regWithName (set *dRegs, const char *name)
413 for (dReg = setFirstItem(dRegs) ; dReg ;
414 dReg = setNextItem(dRegs)) {
416 if((strcmp(name,dReg->name)==0)) {
424 /*-----------------------------------------------------------------*/
425 /* regWithName - Search for a registers that matches name */
426 /*-----------------------------------------------------------------*/
428 regFindWithName (const char *name)
432 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
433 debugLog ("Found a Direct Register!\n");
436 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
437 debugLog ("Found a Direct Bit Register!\n");
441 if (*name=='_') name++; // Step passed '_'
443 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
444 debugLog ("Found a Dynamic Register!\n");
447 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
448 debugLog ("Found a Processor Register!\n");
451 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
452 debugLog ("Found an Internal Register!\n");
455 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
456 debugLog ("Found an Stack Register!\n");
463 /*-----------------------------------------------------------------*/
464 /* regFindFree - Search for a free register in a set of registers */
465 /*-----------------------------------------------------------------*/
467 regFindFree (set *dRegs)
471 for (dReg = setFirstItem(dRegs) ; dReg ;
472 dReg = setNextItem(dRegs)) {
480 /*-----------------------------------------------------------------*/
481 /* initStack - allocate registers for a pseudo stack */
482 /*-----------------------------------------------------------------*/
483 void initStack(int base_address, int size, int shared)
489 pic = pic14_getPIC();
490 Gstack_base_addr = base_address;
492 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
494 for(i = 0; i<size; i++) {
497 SNPRINTF(&buffer[0], 16, "STK%02d", i);
498 // multi-bank device, sharebank prohibited by user
499 r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
504 addSet(&dynStackRegs,r);
508 /*-----------------------------------------------------------------*
509 *-----------------------------------------------------------------*/
511 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
514 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
515 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
518 /*-----------------------------------------------------------------*
519 *-----------------------------------------------------------------*/
522 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
524 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
526 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
529 return addSet(&dynInternalRegs,reg);
534 /*-----------------------------------------------------------------*/
535 /* allocReg - allocates register of given type */
536 /*-----------------------------------------------------------------*/
538 allocReg (short type)
542 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
543 //fprintf(stderr,"allocReg\n");
545 reg = pic14_findFreeReg (type);
553 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
558 /*-----------------------------------------------------------------*/
559 /* dirregWithName - search for register by name */
560 /*-----------------------------------------------------------------*/
562 dirregWithName (char *name)
570 /* hash the name to get a key */
572 hkey = regname2key(name);
574 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
578 if(STRCASECMP(reg->name, name) == 0) {
579 // handle registers with multiple names
580 while (reg->reg_alias) reg = reg->reg_alias;
584 reg = hTabNextItemWK (dynDirectRegNames);
588 return NULL; // name wasn't found in the hash table
591 int IS_CONFIG_ADDRESS(int address)
594 return ((address == 0x2007) || (address == 0x2008));
597 /*-----------------------------------------------------------------*/
598 /* allocNewDirReg - allocates a new register of given type */
599 /*-----------------------------------------------------------------*/
601 allocNewDirReg (sym_link *symlnk,const char *name)
605 sym_link *spec = getSpec (symlnk);
607 /* if this is at an absolute address, then get the address. */
608 if (SPEC_ABSA (spec) ) {
609 address = SPEC_ADDR (spec);
610 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
613 /* Register wasn't found in hash, so let's create
614 * a new one and put it in the hash table AND in the
615 * dynDirectRegNames set */
616 if (IS_CONFIG_ADDRESS(address)) {
617 debugLog (" -- %s is declared at address 0x2007\n",name);
622 if (IS_BITVAR (spec))
629 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
630 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
632 if (SPEC_ABSA (spec) ) {
636 if (IS_BITVAR (spec)) {
637 addSet(&dynDirectBitRegs, reg);
640 addSet(&dynDirectRegs, reg);
642 if (!IS_STATIC (spec)) {
645 if (IS_EXTERN (spec)) {
651 if (address && reg) {
653 reg->address = address;
654 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
660 /*-----------------------------------------------------------------*/
661 /* allocDirReg - allocates register of given type */
662 /*-----------------------------------------------------------------*/
664 allocDirReg (operand *op )
671 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
675 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
677 /* If the symbol is at a fixed address, then remove the leading underscore
678 * from the name. This is hack to allow the .asm include file named registers
679 * to match the .c declared register names */
681 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
684 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
686 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
687 debugLog(" %d const char\n",__LINE__);
688 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
691 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
692 if (IS_CODE ( OP_SYM_ETYPE(op)) )
693 debugLog(" %d code space\n",__LINE__);
695 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
696 debugLog(" %d integral\n",__LINE__);
697 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
698 debugLog(" %d literal\n",__LINE__);
699 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
700 debugLog(" %d specifier\n",__LINE__);
701 debugAopGet(NULL, op);
704 if (IS_CODE ( OP_SYM_ETYPE(op)) )
707 /* First, search the hash table to see if there is a register with this name */
708 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
709 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
712 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
713 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
715 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
716 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
719 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
721 reg = dirregWithName(name);
728 /* if this is at an absolute address, then get the address. */
729 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
730 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
731 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
734 /* Register wasn't found in hash, so let's create
735 * a new one and put it in the hash table AND in the
736 * dynDirectRegNames set */
737 if(!IS_CONFIG_ADDRESS(address)) {
738 //fprintf(stderr,"allocating new reg %s\n",name);
740 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
741 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
743 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
745 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
747 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
751 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
752 addSet(&dynDirectBitRegs, reg);
755 addSet(&dynDirectRegs, reg);
757 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
760 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
766 debugLog (" -- %s is declared at address 0x2007\n",name);
771 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
773 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
774 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
779 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
781 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
782 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
785 allocNewDirReg (OP_SYM_TYPE(op),name);
792 /*-----------------------------------------------------------------*/
793 /* allocRegByName - allocates register with given name */
794 /*-----------------------------------------------------------------*/
796 allocRegByName (char *name, int size)
802 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
806 /* First, search the hash table to see if there is a register with this name */
807 reg = dirregWithName(name);
813 /* Register wasn't found in hash, so let's create
814 * a new one and put it in the hash table AND in the
815 * dynDirectRegNames set */
816 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
817 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
818 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
819 if (strcmp(reg->name+1,sym->name)==0) {
820 unsigned a = SPEC_ADDR(sym->etype);
824 if (!IS_STATIC (sym->etype)) {
827 if (IS_EXTERN (sym->etype)) {
830 if (IS_BITVAR (sym->etype))
837 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
838 if (strcmp(reg->name+1,sym->name)==0) {
839 unsigned a = SPEC_ADDR(sym->etype);
841 if (!IS_STATIC (sym->etype)) {
844 if (IS_EXTERN (sym->etype)) {
847 if (IS_BITVAR (sym->etype))
855 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
857 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
858 if (reg->isBitField) {
859 addSet(&dynDirectBitRegs, reg);
861 addSet(&dynDirectRegs, reg);
867 /*-----------------------------------------------------------------*/
868 /* RegWithIdx - returns pointer to register with index number */
869 /*-----------------------------------------------------------------*/
871 typeRegWithIdx (int idx, int type, int fixed)
876 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
881 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
883 debugLog ("Found a Dynamic Register!\n");
886 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
887 debugLog ("Found a Direct Register!\n");
893 if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
894 debugLog ("Found a Stack Register!\n");
897 if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
898 debugLog ("Found a Stack Register!\n");
902 werror (E_STACK_OUT, "Register");
903 /* return an existing register just to avoid the SDCC crash */
904 return regWithIdx ( dynStackRegs, 0x7f, 0);
908 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
909 debugLog ("Found a Processor Register!\n");
923 /*-----------------------------------------------------------------*/
924 /* pic14_regWithIdx - returns pointer to register with index number*/
925 /*-----------------------------------------------------------------*/
927 pic14_regWithIdx (int idx)
931 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
934 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
940 /*-----------------------------------------------------------------*/
941 /* pic14_regWithIdx - returns pointer to register with index number */
942 /*-----------------------------------------------------------------*/
944 pic14_allocWithIdx (int idx)
949 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
951 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
953 debugLog ("Found a Dynamic Register!\n");
954 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
955 debugLog ("Found a Stack Register!\n");
956 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
957 debugLog ("Found a Processor Register!\n");
958 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
959 debugLog ("Found an Internal Register!\n");
960 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
961 debugLog ("Found an Internal Register!\n");
964 debugLog ("Dynamic Register not found\n");
967 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
968 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
969 "regWithIdx not found");
979 /*-----------------------------------------------------------------*/
980 /*-----------------------------------------------------------------*/
982 pic14_findFreeReg(short type)
989 if((dReg = regFindFree(dynAllocRegs)) != NULL)
991 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
995 if((dReg = regFindFree(dynStackRegs)) != NULL)
1007 /*-----------------------------------------------------------------*/
1008 /* freeReg - frees a register */
1009 /*-----------------------------------------------------------------*/
1011 freeReg (regs * reg)
1013 debugLog ("%s\n", __FUNCTION__);
1018 /*-----------------------------------------------------------------*/
1019 /* nFreeRegs - returns number of free registers */
1020 /*-----------------------------------------------------------------*/
1022 nFreeRegs (int type)
1024 /* dynamically allocate as many as we need and worry about
1025 * fitting them into a PIC later */
1032 debugLog ("%s\n", __FUNCTION__);
1033 for (i = 0; i < pic14_nRegs; i++)
1034 if (regspic14[i].isFree && regspic14[i].type == type)
1040 /*-----------------------------------------------------------------*/
1041 /* nfreeRegsType - free registers with type */
1042 /*-----------------------------------------------------------------*/
1044 nfreeRegsType (int type)
1047 debugLog ("%s\n", __FUNCTION__);
1048 if (type == REG_PTR)
1050 if ((nfr = nFreeRegs (type)) == 0)
1051 return nFreeRegs (REG_GPR);
1054 return nFreeRegs (type);
1057 void writeSetUsedRegs(FILE *of, set *dRegs)
1062 for (dReg = setFirstItem(dRegs) ; dReg ;
1063 dReg = setNextItem(dRegs)) {
1066 fprintf (of, "\t%s\n",dReg->name);
1070 extern void dump_map(void);
1072 void packBits(set *bregs)
1076 regs *bitfield=NULL;
1077 regs *relocbitfield=NULL;
1083 for (regset = bregs ; regset ;
1084 regset = regset->next) {
1086 breg = regset->item;
1087 breg->isBitField = 1;
1088 //fprintf(stderr,"bit reg: %s\n",breg->name);
1091 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1093 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1094 breg->rIdx = breg->address & 7;
1095 breg->address >>= 3;
1098 //sprintf (buffer, "fbitfield%02x", breg->address);
1099 sprintf (buffer, "0x%02x", breg->address);
1100 //fprintf(stderr,"new bit field\n");
1101 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1102 bitfield->isBitField = 1;
1103 bitfield->isFixed = 1;
1104 bitfield->address = breg->address;
1105 //addSet(&dynDirectRegs,bitfield);
1106 addSet(&dynInternalRegs,bitfield);
1107 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1109 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1112 breg->reg_alias = bitfield;
1116 if(!relocbitfield || bit_no >7) {
1119 sprintf (buffer, "bitfield%d", byte_no);
1120 //fprintf(stderr,"new relocatable bit field\n");
1121 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
1122 relocbitfield->isBitField = 1;
1123 //addSet(&dynDirectRegs,relocbitfield);
1124 addSet(&dynInternalRegs,relocbitfield);
1125 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1129 breg->reg_alias = relocbitfield;
1130 breg->address = dynrIdx; /* byte_no; */
1131 breg->rIdx = bit_no++;
1139 void bitEQUs(FILE *of, set *bregs)
1141 regs *breg,*bytereg;
1144 //fprintf(stderr," %s\n",__FUNCTION__);
1145 for (breg = setFirstItem(bregs) ; breg ;
1146 breg = setNextItem(bregs)) {
1148 //fprintf(stderr,"bit reg: %s\n",breg->name);
1150 bytereg = breg->reg_alias;
1152 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1155 breg->rIdx & 0x0007);
1158 //fprintf(stderr, "bit field is not assigned to a register\n");
1159 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1170 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1175 for (reg = setFirstItem(fregs) ; reg ;
1176 reg = setNextItem(fregs)) {
1178 //if(!reg->isEmitted && reg->wasUsed) {
1181 fprintf (of, "%s\tEQU\t0x%03x\n",
1185 fprintf (of, "%s\tEQU\t0x%03x\n",
1193 void writeUsedRegs(FILE *of)
1196 packBits(dynDirectBitRegs);
1200 bitEQUs(of,dynDirectBitRegs);
1203 /*-----------------------------------------------------------------*/
1204 /* computeSpillable - given a point find the spillable live ranges */
1205 /*-----------------------------------------------------------------*/
1207 computeSpillable (iCode * ic)
1211 debugLog ("%s\n", __FUNCTION__);
1212 /* spillable live ranges are those that are live at this
1213 point . the following categories need to be subtracted
1215 a) - those that are already spilt
1216 b) - if being used by this one
1217 c) - defined by this one */
1219 spillable = bitVectCopy (ic->rlive);
1221 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1223 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1224 bitVectUnSetBit (spillable, ic->defKey);
1225 spillable = bitVectIntersect (spillable, _G.regAssigned);
1230 /*-----------------------------------------------------------------*/
1231 /* noSpilLoc - return true if a variable has no spil location */
1232 /*-----------------------------------------------------------------*/
1234 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1236 debugLog ("%s\n", __FUNCTION__);
1237 return (sym->usl.spillLoc ? 0 : 1);
1240 /*-----------------------------------------------------------------*/
1241 /* hasSpilLoc - will return 1 if the symbol has spil location */
1242 /*-----------------------------------------------------------------*/
1244 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1246 debugLog ("%s\n", __FUNCTION__);
1247 return (sym->usl.spillLoc ? 1 : 0);
1250 /*-----------------------------------------------------------------*/
1251 /* directSpilLoc - will return 1 if the splilocation is in direct */
1252 /*-----------------------------------------------------------------*/
1254 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1256 debugLog ("%s\n", __FUNCTION__);
1257 if (sym->usl.spillLoc &&
1258 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1264 /*-----------------------------------------------------------------*/
1265 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1266 /* but is not used as a pointer */
1267 /*-----------------------------------------------------------------*/
1269 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1271 debugLog ("%s\n", __FUNCTION__);
1272 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1275 /*-----------------------------------------------------------------*/
1276 /* rematable - will return 1 if the remat flag is set */
1277 /*-----------------------------------------------------------------*/
1279 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1281 debugLog ("%s\n", __FUNCTION__);
1285 /*-----------------------------------------------------------------*/
1286 /* notUsedInRemaining - not used or defined in remain of the block */
1287 /*-----------------------------------------------------------------*/
1289 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1291 debugLog ("%s\n", __FUNCTION__);
1292 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1293 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1296 /*-----------------------------------------------------------------*/
1297 /* allLRs - return true for all */
1298 /*-----------------------------------------------------------------*/
1300 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1302 debugLog ("%s\n", __FUNCTION__);
1306 /*-----------------------------------------------------------------*/
1307 /* liveRangesWith - applies function to a given set of live range */
1308 /*-----------------------------------------------------------------*/
1310 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1311 eBBlock * ebp, iCode * ic)
1316 debugLog ("%s\n", __FUNCTION__);
1317 if (!lrs || !lrs->size)
1320 for (i = 1; i < lrs->size; i++)
1323 if (!bitVectBitValue (lrs, i))
1326 /* if we don't find it in the live range
1327 hash table we are in serious trouble */
1328 if (!(sym = hTabItemWithKey (liveRanges, i)))
1330 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1331 "liveRangesWith could not find liveRange");
1335 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1336 addSetHead (&rset, sym);
1343 /*-----------------------------------------------------------------*/
1344 /* leastUsedLR - given a set determines which is the least used */
1345 /*-----------------------------------------------------------------*/
1347 leastUsedLR (set * sset)
1349 symbol *sym = NULL, *lsym = NULL;
1351 debugLog ("%s\n", __FUNCTION__);
1352 sym = lsym = setFirstItem (sset);
1357 for (; lsym; lsym = setNextItem (sset))
1360 /* if usage is the same then prefer
1361 the spill the smaller of the two */
1362 if (lsym->used == sym->used)
1363 if (getSize (lsym->type) < getSize (sym->type))
1367 if (lsym->used < sym->used)
1372 setToNull ((void *) &sset);
1377 /*-----------------------------------------------------------------*/
1378 /* noOverLap - will iterate through the list looking for over lap */
1379 /*-----------------------------------------------------------------*/
1381 noOverLap (set * itmpStack, symbol * fsym)
1384 debugLog ("%s\n", __FUNCTION__);
1387 for (sym = setFirstItem (itmpStack); sym;
1388 sym = setNextItem (itmpStack))
1390 if (sym->liveTo > fsym->liveFrom)
1398 /*-----------------------------------------------------------------*/
1399 /* isFree - will return 1 if the a free spil location is found */
1400 /*-----------------------------------------------------------------*/
1405 V_ARG (symbol **, sloc);
1406 V_ARG (symbol *, fsym);
1408 debugLog ("%s\n", __FUNCTION__);
1409 /* if already found */
1413 /* if it is free && and the itmp assigned to
1414 this does not have any overlapping live ranges
1415 with the one currently being assigned and
1416 the size can be accomodated */
1418 noOverLap (sym->usl.itmpStack, fsym) &&
1419 getSize (sym->type) >= getSize (fsym->type))
1428 /*-----------------------------------------------------------------*/
1429 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1430 /*-----------------------------------------------------------------*/
1432 spillLRWithPtrReg (symbol * forSym)
1438 debugLog ("%s\n", __FUNCTION__);
1439 if (!_G.regAssigned ||
1440 bitVectIsZero (_G.regAssigned))
1443 r0 = pic14_regWithIdx (R0_IDX);
1444 r1 = pic14_regWithIdx (R1_IDX);
1446 /* for all live ranges */
1447 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1448 lrsym = hTabNextItem (liveRanges, &k))
1452 /* if no registers assigned to it or
1454 /* if it does not overlap with this then
1455 not need to spill it */
1457 if (lrsym->isspilt || !lrsym->nRegs ||
1458 (lrsym->liveTo < forSym->liveFrom))
1461 /* go thru the registers : if it is either
1462 r0 or r1 then spil it */
1463 for (j = 0; j < lrsym->nRegs; j++)
1464 if (lrsym->regs[j] == r0 ||
1465 lrsym->regs[j] == r1)
1474 /*-----------------------------------------------------------------*/
1475 /* createStackSpil - create a location on the stack to spil */
1476 /*-----------------------------------------------------------------*/
1478 createStackSpil (symbol * sym)
1480 symbol *sloc = NULL;
1481 int useXstack, model, noOverlay;
1483 char slocBuffer[30];
1484 debugLog ("%s\n", __FUNCTION__);
1488 /* first go try and find a free one that is already
1489 existing on the stack */
1490 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1492 /* found a free one : just update & return */
1493 sym->usl.spillLoc = sloc;
1496 addSetHead (&sloc->usl.itmpStack, sym);
1500 /* could not then have to create one , this is the hard part
1501 we need to allocate this on the stack : this is really a
1502 hack!! but cannot think of anything better at this time */
1504 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1506 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1507 __FILE__, __LINE__);
1511 sloc = newiTemp (slocBuffer);
1513 /* set the type to the spilling symbol */
1514 sloc->type = copyLinkChain (sym->type);
1515 sloc->etype = getSpec (sloc->type);
1516 SPEC_SCLS (sloc->etype) = S_DATA;
1517 SPEC_EXTR (sloc->etype) = 0;
1518 SPEC_STAT (sloc->etype) = 0;
1520 /* we don't allow it to be allocated`
1521 onto the external stack since : so we
1522 temporarily turn it off ; we also
1523 turn off memory model to prevent
1524 the spil from going to the external storage
1525 and turn off overlaying
1528 useXstack = options.useXstack;
1529 model = options.model;
1530 noOverlay = options.noOverlay;
1531 options.noOverlay = 1;
1532 options.model = options.useXstack = 0;
1536 options.useXstack = useXstack;
1537 options.model = model;
1538 options.noOverlay = noOverlay;
1539 sloc->isref = 1; /* to prevent compiler warning */
1541 /* if it is on the stack then update the stack */
1542 if (IN_STACK (sloc->etype))
1544 currFunc->stack += getSize (sloc->type);
1545 _G.stackExtend += getSize (sloc->type);
1548 _G.dataExtend += getSize (sloc->type);
1550 /* add it to the _G.stackSpil set */
1551 addSetHead (&_G.stackSpil, sloc);
1552 sym->usl.spillLoc = sloc;
1555 /* add it to the set of itempStack set
1556 of the spill location */
1557 addSetHead (&sloc->usl.itmpStack, sym);
1561 /*-----------------------------------------------------------------*/
1562 /* isSpiltOnStack - returns true if the spil location is on stack */
1563 /*-----------------------------------------------------------------*/
1565 isSpiltOnStack (symbol * sym)
1569 debugLog ("%s\n", __FUNCTION__);
1578 /* if (sym->_G.stackSpil) */
1581 if (!sym->usl.spillLoc)
1584 etype = getSpec (sym->usl.spillLoc->type);
1585 if (IN_STACK (etype))
1591 /*-----------------------------------------------------------------*/
1592 /* spillThis - spils a specific operand */
1593 /*-----------------------------------------------------------------*/
1595 spillThis (symbol * sym)
1598 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1599 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1601 /* if this is rematerializable or has a spillLocation
1602 we are okay, else we need to create a spillLocation
1604 if (!(sym->remat || sym->usl.spillLoc))
1605 createStackSpil (sym);
1608 /* mark it has spilt & put it in the spilt set */
1610 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1612 bitVectUnSetBit (_G.regAssigned, sym->key);
1614 for (i = 0; i < sym->nRegs; i++)
1618 freeReg (sym->regs[i]);
1619 sym->regs[i] = NULL;
1623 /* if spilt on stack then free up r0 & r1
1624 if they could have been assigned to some
1626 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1629 spillLRWithPtrReg (sym);
1632 if (sym->usl.spillLoc && !sym->remat)
1633 sym->usl.spillLoc->allocreq = 1;
1638 /*-----------------------------------------------------------------*/
1639 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1640 /*-----------------------------------------------------------------*/
1642 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1644 bitVect *lrcs = NULL;
1648 debugLog ("%s\n", __FUNCTION__);
1650 /* get the spillable live ranges */
1651 lrcs = computeSpillable (ic);
1654 /* get all live ranges that are rematerizable */
1655 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1657 /* return the least used of these */
1658 return leastUsedLR (selectS);
1661 /* get live ranges with spillLocations in direct space */
1662 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1664 sym = leastUsedLR (selectS);
1665 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1666 sym->usl.spillLoc->rname :
1667 sym->usl.spillLoc->name));
1669 /* mark it as allocation required */
1670 sym->usl.spillLoc->allocreq = 1;
1674 /* if the symbol is local to the block then */
1675 if (forSym->liveTo < ebp->lSeq)
1678 /* check if there are any live ranges allocated
1679 to registers that are not used in this block */
1680 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1682 sym = leastUsedLR (selectS);
1683 /* if this is not rematerializable */
1692 /* check if there are any live ranges that not
1693 used in the remainder of the block */
1694 if (!_G.blockSpil &&
1695 !isiCodeInFunctionCall (ic) &&
1696 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1698 sym = leastUsedLR (selectS);
1701 sym->remainSpil = 1;
1708 /* find live ranges with spillocation && not used as pointers */
1709 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1712 sym = leastUsedLR (selectS);
1713 /* mark this as allocation required */
1714 sym->usl.spillLoc->allocreq = 1;
1718 /* find live ranges with spillocation */
1719 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1722 sym = leastUsedLR (selectS);
1723 sym->usl.spillLoc->allocreq = 1;
1727 /* couldn't find then we need to create a spil
1728 location on the stack , for which one? the least
1730 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1733 /* return a created spil location */
1734 sym = createStackSpil (leastUsedLR (selectS));
1735 sym->usl.spillLoc->allocreq = 1;
1739 /* this is an extreme situation we will spill
1740 this one : happens very rarely but it does happen */
1746 /*-----------------------------------------------------------------*/
1747 /* spilSomething - spil some variable & mark registers as free */
1748 /*-----------------------------------------------------------------*/
1750 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1755 debugLog ("%s\n", __FUNCTION__);
1756 /* get something we can spil */
1757 ssym = selectSpil (ic, ebp, forSym);
1759 /* mark it as spilt */
1761 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1763 /* mark it as not register assigned &
1764 take it away from the set */
1765 bitVectUnSetBit (_G.regAssigned, ssym->key);
1767 /* mark the registers as free */
1768 for (i = 0; i < ssym->nRegs; i++)
1770 freeReg (ssym->regs[i]);
1772 /* if spilt on stack then free up r0 & r1
1773 if they could have been assigned to as gprs */
1774 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1777 spillLRWithPtrReg (ssym);
1780 /* if this was a block level spil then insert push & pop
1781 at the start & end of block respectively */
1782 if (ssym->blockSpil)
1784 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1785 /* add push to the start of the block */
1786 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1787 ebp->sch->next : ebp->sch));
1788 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1789 /* add pop to the end of the block */
1790 addiCodeToeBBlock (ebp, nic, NULL);
1793 /* if spilt because not used in the remainder of the
1794 block then add a push before this instruction and
1795 a pop at the end of the block */
1796 if (ssym->remainSpil)
1799 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1800 /* add push just before this instruction */
1801 addiCodeToeBBlock (ebp, nic, ic);
1803 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1804 /* add pop to the end of the block */
1805 addiCodeToeBBlock (ebp, nic, NULL);
1814 /*-----------------------------------------------------------------*/
1815 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1816 /*-----------------------------------------------------------------*/
1818 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1823 debugLog ("%s\n", __FUNCTION__);
1825 /* try for a ptr type */
1826 if ((reg = allocReg (REG_PTR)))
1829 /* try for gpr type */
1830 if ((reg = allocReg (REG_GPR)))
1833 /* we have to spil */
1834 if (!spilSomething (ic, ebp, sym))
1837 /* make sure partially assigned registers aren't reused */
1838 for (j=0; j<=sym->nRegs; j++)
1840 sym->regs[j]->isFree = 0;
1842 /* this looks like an infinite loop but
1843 in really selectSpil will abort */
1847 /*-----------------------------------------------------------------*/
1848 /* getRegGpr - will try for GPR if not spil */
1849 /*-----------------------------------------------------------------*/
1851 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1856 debugLog ("%s\n", __FUNCTION__);
1858 /* try for gpr type */
1859 if ((reg = allocReg (REG_GPR)))
1862 if (!pic14_ptrRegReq)
1863 if ((reg = allocReg (REG_PTR)))
1866 /* we have to spil */
1867 if (!spilSomething (ic, ebp, sym))
1870 /* make sure partially assigned registers aren't reused */
1871 for (j=0; j<=sym->nRegs; j++)
1873 sym->regs[j]->isFree = 0;
1875 /* this looks like an infinite loop but
1876 in really selectSpil will abort */
1880 /*-----------------------------------------------------------------*/
1881 /* symHasReg - symbol has a given register */
1882 /*-----------------------------------------------------------------*/
1884 symHasReg (symbol * sym, regs * reg)
1888 debugLog ("%s\n", __FUNCTION__);
1889 for (i = 0; i < sym->nRegs; i++)
1890 if (sym->regs[i] == reg)
1896 /*-----------------------------------------------------------------*/
1897 /* deassignLRs - check the live to and if they have registers & are */
1898 /* not spilt then free up the registers */
1899 /*-----------------------------------------------------------------*/
1901 deassignLRs (iCode * ic, eBBlock * ebp)
1907 debugLog ("%s\n", __FUNCTION__);
1908 for (sym = hTabFirstItem (liveRanges, &k); sym;
1909 sym = hTabNextItem (liveRanges, &k))
1912 symbol *psym = NULL;
1913 /* if it does not end here */
1914 if (sym->liveTo > ic->seq)
1917 /* Prevent the result from being assigned the same registers as (one)
1918 * operand as many genXXX-functions fail otherwise.
1919 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1920 * are known to fail. */
1921 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1925 case '=': /* assignment */
1926 case BITWISEAND: /* bitwise AND */
1927 case '|': /* bitwise OR */
1928 case '^': /* bitwise XOR */
1929 case '~': /* bitwise negate */
1930 case RLC: /* rotate through carry */
1933 case '+': /* addition */
1934 case '-': /* subtraction */
1935 /* go ahead, these are safe to use with
1936 * non-disjoint register sets */
1940 /* do not release operand registers */
1941 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1946 /* if it was spilt on stack then we can
1947 mark the stack spil location as free */
1952 sym->usl.spillLoc->isFree = 1;
1958 if (!bitVectBitValue (_G.regAssigned, sym->key))
1960 /* special case check if this is an IFX &
1961 the privious one was a pop and the
1962 previous one was not spilt then keep track
1964 if (ic->op == IFX && ic->prev &&
1965 ic->prev->op == IPOP &&
1966 !ic->prev->parmPush &&
1967 IS_SYMOP(IC_LEFT (ic->prev)) &&
1968 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1969 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1975 bitVectUnSetBit (_G.regAssigned, sym->key);
1977 /* if the result of this one needs registers
1978 and does not have it then assign it right
1980 if (IC_RESULT (ic) &&
1981 !(SKIP_IC2 (ic) || /* not a special icode */
1982 ic->op == JUMPTABLE ||
1987 POINTER_SET (ic)) &&
1988 IS_SYMOP (IC_RESULT (ic)) &&
1989 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1990 result->liveTo > ic->seq && /* and will live beyond this */
1991 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1992 result->liveFrom == ic->seq && /* does not start before here */
1993 result->regType == sym->regType && /* same register types */
1994 result->regType == sym->regType && /* same register types */
1995 result->nRegs && /* which needs registers */
1996 !result->isspilt && /* and does not already have them */
1998 !bitVectBitValue (_G.regAssigned, result->key) &&
1999 /* the number of free regs + number of regs in this LR
2000 can accomodate the what result Needs */
2001 ((nfreeRegsType (result->regType) +
2002 sym->nRegs) >= result->nRegs)
2006 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2008 result->regs[i] = sym->regs[i];
2010 result->regs[i] = getRegGpr (ic, ebp, result);
2012 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2016 /* free the remaining */
2017 for (; i < sym->nRegs; i++)
2021 if (!symHasReg (psym, sym->regs[i]))
2022 freeReg (sym->regs[i]);
2025 freeReg (sym->regs[i]);
2032 /*-----------------------------------------------------------------*/
2033 /* reassignLR - reassign this to registers */
2034 /*-----------------------------------------------------------------*/
2036 reassignLR (operand * op)
2038 symbol *sym = OP_SYMBOL (op);
2041 debugLog ("%s\n", __FUNCTION__);
2042 /* not spilt any more */
2043 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2044 bitVectUnSetBit (_G.spiltSet, sym->key);
2046 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2050 for (i = 0; i < sym->nRegs; i++)
2051 sym->regs[i]->isFree = 0;
2054 /*-----------------------------------------------------------------*/
2055 /* willCauseSpill - determines if allocating will cause a spill */
2056 /*-----------------------------------------------------------------*/
2058 willCauseSpill (int nr, int rt)
2060 debugLog ("%s\n", __FUNCTION__);
2061 /* first check if there are any avlb registers
2062 of te type required */
2065 /* special case for pointer type
2066 if pointer type not avlb then
2067 check for type gpr */
2068 if (nFreeRegs (rt) >= nr)
2070 if (nFreeRegs (REG_GPR) >= nr)
2075 if (pic14_ptrRegReq)
2077 if (nFreeRegs (rt) >= nr)
2082 if (nFreeRegs (REG_PTR) +
2083 nFreeRegs (REG_GPR) >= nr)
2088 debugLog (" ... yep it will (cause a spill)\n");
2089 /* it will cause a spil */
2093 /*-----------------------------------------------------------------*/
2094 /* positionRegs - the allocator can allocate same registers to res- */
2095 /* ult and operand, if this happens make sure they are in the same */
2096 /* position as the operand otherwise chaos results */
2097 /*-----------------------------------------------------------------*/
2099 positionRegs (symbol * result, symbol * opsym, int lineno)
2101 int count = min (result->nRegs, opsym->nRegs);
2102 int i, j = 0, shared = 0;
2104 debugLog ("%s\n", __FUNCTION__);
2105 /* if the result has been spilt then cannot share */
2110 /* first make sure that they actually share */
2111 for (i = 0; i < count; i++)
2113 for (j = 0; j < count; j++)
2115 if (result->regs[i] == opsym->regs[j] && i != j)
2125 regs *tmp = result->regs[i];
2126 result->regs[i] = result->regs[j];
2127 result->regs[j] = tmp;
2132 /*------------------------------------------------------------------*/
2133 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2134 /* it should either have registers or have beed spilled. Otherwise, */
2135 /* there was an uninitialized variable, so just spill this to get */
2136 /* the operand in a valid state. */
2137 /*------------------------------------------------------------------*/
2139 verifyRegsAssigned (operand *op, iCode * ic)
2144 if (!IS_ITEMP (op)) return;
2146 sym = OP_SYMBOL (op);
2147 if (sym->isspilt) return;
2148 if (!sym->nRegs) return;
2149 if (sym->regs[0]) return;
2151 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2152 sym->prereqv ? sym->prereqv->name : sym->name);
2157 /*-----------------------------------------------------------------*/
2158 /* serialRegAssign - serially allocate registers to the variables */
2159 /*-----------------------------------------------------------------*/
2161 serialRegAssign (eBBlock ** ebbs, int count)
2165 debugLog ("%s\n", __FUNCTION__);
2166 /* for all blocks */
2167 for (i = 0; i < count; i++)
2172 if (ebbs[i]->noPath &&
2173 (ebbs[i]->entryLabel != entryLabel &&
2174 ebbs[i]->entryLabel != returnLabel))
2177 /* of all instructions do */
2178 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2180 debugLog (" op: %s\n", decodeOp (ic->op));
2182 /* if this is an ipop that means some live
2183 range will have to be assigned again */
2185 reassignLR (IC_LEFT (ic));
2187 /* if result is present && is a true symbol */
2188 if (IC_RESULT (ic) && ic->op != IFX &&
2189 IS_TRUE_SYMOP (IC_RESULT (ic)))
2190 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2192 /* take away registers from live
2193 ranges that end at this instruction */
2194 deassignLRs (ic, ebbs[i]);
2196 /* some don't need registers */
2197 if (SKIP_IC2 (ic) ||
2198 ic->op == JUMPTABLE ||
2202 (IC_RESULT (ic) && POINTER_SET (ic)))
2205 /* now we need to allocate registers
2206 only for the result */
2207 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2209 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2215 /* Make sure any spill location is definately allocated */
2216 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2217 !sym->usl.spillLoc->allocreq)
2219 sym->usl.spillLoc->allocreq++;
2222 /* if it does not need or is spilt
2223 or is already assigned to registers
2224 or will not live beyond this instructions */
2227 bitVectBitValue (_G.regAssigned, sym->key) ||
2228 sym->liveTo <= ic->seq)
2231 /* if some liverange has been spilt at the block level
2232 and this one live beyond this block then spil this
2234 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2239 /* if trying to allocate this will cause
2240 a spill and there is nothing to spill
2241 or this one is rematerializable then
2243 willCS = willCauseSpill (sym->nRegs, sym->regType);
2244 spillable = computeSpillable (ic);
2246 (willCS && bitVectIsZero (spillable)))
2254 /* If the live range preceeds the point of definition
2255 then ideally we must take into account registers that
2256 have been allocated after sym->liveFrom but freed
2257 before ic->seq. This is complicated, so spill this
2258 symbol instead and let fillGaps handle the allocation. */
2259 if (sym->liveFrom < ic->seq)
2265 /* if it has a spillocation & is used less than
2266 all other live ranges then spill this */
2268 if (sym->usl.spillLoc) {
2269 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2270 allLRs, ebbs[i], ic));
2271 if (leastUsed && leastUsed->used > sym->used) {
2276 /* if none of the liveRanges have a spillLocation then better
2277 to spill this one than anything else already assigned to registers */
2278 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2279 /* if this is local to this block then we might find a block spil */
2280 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2288 if (ic->op == RECEIVE)
2289 debugLog ("When I get clever, I'll optimize the receive logic\n");
2291 /* if we need ptr regs for the right side
2293 if (POINTER_GET (ic)
2294 && IS_SYMOP(IC_LEFT(ic))
2295 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2296 <= (unsigned) PTRSIZE)
2301 /* else we assign registers to it */
2302 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2304 debugLog (" %d - \n", __LINE__);
2306 bitVectDebugOn(_G.regAssigned, debugF);
2307 for (j = 0; j < sym->nRegs; j++)
2309 if (sym->regType == REG_PTR)
2310 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2312 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2314 /* if the allocation failed which means
2315 this was spilt then break */
2319 debugLog (" %d - \n", __LINE__);
2321 /* if it shares registers with operands make sure
2322 that they are in the same position */
2323 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2324 IS_SYMOP(IC_RESULT(ic)) &&
2325 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2326 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2327 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2328 /* do the same for the right operand */
2329 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2330 IS_SYMOP(IC_RESULT(ic)) &&
2331 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2332 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2333 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2335 debugLog (" %d - \n", __LINE__);
2338 debugLog (" %d - \n", __LINE__);
2347 /* Check for and fix any problems with uninitialized operands */
2348 for (i = 0; i < count; i++)
2352 if (ebbs[i]->noPath &&
2353 (ebbs[i]->entryLabel != entryLabel &&
2354 ebbs[i]->entryLabel != returnLabel))
2357 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2364 verifyRegsAssigned (IC_COND (ic), ic);
2368 if (ic->op == JUMPTABLE)
2370 verifyRegsAssigned (IC_JTCOND (ic), ic);
2374 verifyRegsAssigned (IC_RESULT (ic), ic);
2375 verifyRegsAssigned (IC_LEFT (ic), ic);
2376 verifyRegsAssigned (IC_RIGHT (ic), ic);
2382 /*-----------------------------------------------------------------*/
2383 /* rUmaskForOp :- returns register mask for an operand */
2384 /*-----------------------------------------------------------------*/
2386 rUmaskForOp (operand * op)
2392 debugLog ("%s\n", __FUNCTION__);
2393 /* only temporaries are assigned registers */
2397 sym = OP_SYMBOL (op);
2399 /* if spilt or no registers assigned to it
2401 if (sym->isspilt || !sym->nRegs)
2404 rumask = newBitVect (pic14_nRegs);
2406 for (j = 0; j < sym->nRegs; j++)
2408 rumask = bitVectSetBit (rumask,
2409 sym->regs[j]->rIdx);
2415 /*-----------------------------------------------------------------*/
2416 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2417 /*-----------------------------------------------------------------*/
2419 regsUsedIniCode (iCode * ic)
2421 bitVect *rmask = newBitVect (pic14_nRegs);
2423 debugLog ("%s\n", __FUNCTION__);
2424 /* do the special cases first */
2427 rmask = bitVectUnion (rmask,
2428 rUmaskForOp (IC_COND (ic)));
2432 /* for the jumptable */
2433 if (ic->op == JUMPTABLE)
2435 rmask = bitVectUnion (rmask,
2436 rUmaskForOp (IC_JTCOND (ic)));
2441 /* of all other cases */
2443 rmask = bitVectUnion (rmask,
2444 rUmaskForOp (IC_LEFT (ic)));
2448 rmask = bitVectUnion (rmask,
2449 rUmaskForOp (IC_RIGHT (ic)));
2452 rmask = bitVectUnion (rmask,
2453 rUmaskForOp (IC_RESULT (ic)));
2459 /*-----------------------------------------------------------------*/
2460 /* createRegMask - for each instruction will determine the regsUsed */
2461 /*-----------------------------------------------------------------*/
2463 createRegMask (eBBlock ** ebbs, int count)
2467 debugLog ("%s\n", __FUNCTION__);
2468 /* for all blocks */
2469 for (i = 0; i < count; i++)
2473 if (ebbs[i]->noPath &&
2474 (ebbs[i]->entryLabel != entryLabel &&
2475 ebbs[i]->entryLabel != returnLabel))
2478 /* for all instructions */
2479 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2484 if (SKIP_IC2 (ic) || !ic->rlive)
2487 /* first mark the registers used in this
2489 ic->rUsed = regsUsedIniCode (ic);
2490 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2492 /* now create the register mask for those
2493 registers that are in use : this is a
2494 super set of ic->rUsed */
2495 ic->rMask = newBitVect (pic14_nRegs + 1);
2497 /* for all live Ranges alive at this point */
2498 for (j = 1; j < ic->rlive->size; j++)
2503 /* if not alive then continue */
2504 if (!bitVectBitValue (ic->rlive, j))
2507 /* find the live range we are interested in */
2508 if (!(sym = hTabItemWithKey (liveRanges, j)))
2510 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2511 "createRegMask cannot find live range");
2515 /* if no register assigned to it */
2516 if (!sym->nRegs || sym->isspilt)
2519 /* for all the registers allocated to it */
2520 for (k = 0; k < sym->nRegs; k++)
2523 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2529 /* This was the active version */
2530 /*-----------------------------------------------------------------*/
2531 /* rematStr - returns the rematerialized string for a remat var */
2532 /*-----------------------------------------------------------------*/
2534 rematStr (symbol * sym)
2537 iCode *ic = sym->rematiCode;
2538 symbol *psym = NULL;
2540 debugLog ("%s\n", __FUNCTION__);
2542 //printf ("%s\n", s);
2544 /* if plus or minus print the right hand side */
2546 if (ic->op == '+' || ic->op == '-') {
2548 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2550 sprintf (s, "(%s %c 0x%04x)",
2551 OP_SYMBOL (IC_LEFT (ric))->rname,
2553 (int) operandLitValue (IC_RIGHT (ic)));
2556 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2558 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2559 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2564 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2565 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2567 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2573 /* deprecated version */
2574 /*-----------------------------------------------------------------*/
2575 /* rematStr - returns the rematerialized string for a remat var */
2576 /*-----------------------------------------------------------------*/
2578 rematStr (symbol * sym)
2581 iCode *ic = sym->rematiCode;
2583 debugLog ("%s\n", __FUNCTION__);
2588 /* if plus or minus print the right hand side */
2590 if (ic->op == '+' || ic->op == '-') {
2591 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2594 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2598 if (ic->op == '+' || ic->op == '-')
2600 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2601 sprintf (s, "(%s %c 0x%04x)",
2602 OP_SYMBOL (IC_LEFT (ric))->rname,
2604 (int) operandLitValue (IC_RIGHT (ic)));
2607 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2609 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2613 /* we reached the end */
2614 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2618 printf ("%s\n", buffer);
2623 /*-----------------------------------------------------------------*/
2624 /* regTypeNum - computes the type & number of registers required */
2625 /*-----------------------------------------------------------------*/
2633 debugLog ("%s\n", __FUNCTION__);
2634 /* for each live range do */
2635 for (sym = hTabFirstItem (liveRanges, &k); sym;
2636 sym = hTabNextItem (liveRanges, &k)) {
2638 debugLog (" %d - %s\n", __LINE__, sym->rname);
2640 /* if used zero times then no registers needed */
2641 if ((sym->liveTo - sym->liveFrom) == 0)
2645 /* if the live range is a temporary */
2648 debugLog (" %d - itemp register\n", __LINE__);
2650 /* if the type is marked as a conditional */
2651 if (sym->regType == REG_CND)
2654 /* if used in return only then we don't
2657 if (IS_AGGREGATE (sym->type) || sym->isptr)
2658 sym->type = aggrToPtr (sym->type, FALSE);
2659 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2665 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2666 // sym->type = aggrToPtr (sym->type, FALSE);
2667 debugLog (" %d - used as a return\n", __LINE__);
2672 /* if the symbol has only one definition &
2673 that definition is a get_pointer and the
2674 pointer we are getting is rematerializable and
2678 if (bitVectnBitsOn (sym->defs) == 1 &&
2679 (ic = hTabItemWithKey (iCodehTab,
2680 bitVectFirstBit (sym->defs))) &&
2682 !IS_BITVAR (sym->etype) &&
2683 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2685 if (ptrPseudoSymSafe (sym, ic)) {
2689 debugLog (" %d - \n", __LINE__);
2691 /* create a pseudo symbol & force a spil */
2692 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2693 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2694 psym->type = sym->type;
2695 psym->etype = sym->etype;
2696 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2697 strcpy (psym->rname, psym->name);
2699 sym->usl.spillLoc = psym;
2703 /* if in data space or idata space then try to
2704 allocate pointer register */
2709 /* if not then we require registers */
2710 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2711 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2712 getSize (sym->type));
2715 if(IS_PTR_CONST (sym->type)) {
2716 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2720 if (sym->nRegs > 4) {
2721 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2722 printTypeChain (sym->type, stderr);
2723 fprintf (stderr, "\n");
2726 /* determine the type of register required */
2727 if (sym->nRegs == 1 &&
2728 IS_PTR (sym->type) &&
2730 sym->regType = REG_PTR;
2732 sym->regType = REG_GPR;
2735 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2739 /* for the first run we don't provide */
2740 /* registers for true symbols we will */
2741 /* see how things go */
2746 DEFSETFUNC (markRegFree)
2748 ((regs *)item)->isFree = 1;
2753 DEFSETFUNC (deallocReg)
2755 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2756 ((regs *)item)->isFree = 1;
2757 ((regs *)item)->wasUsed = 0;
2761 /*-----------------------------------------------------------------*/
2762 /* freeAllRegs - mark all registers as free */
2763 /*-----------------------------------------------------------------*/
2765 pic14_freeAllRegs ()
2769 debugLog ("%s\n", __FUNCTION__);
2771 applyToSet(dynAllocRegs,markRegFree);
2772 applyToSet(dynStackRegs,markRegFree);
2775 for (i = 0; i < pic14_nRegs; i++)
2776 regspic14[i].isFree = 1;
2780 /*-----------------------------------------------------------------*/
2781 /*-----------------------------------------------------------------*/
2783 pic14_deallocateAllRegs ()
2787 debugLog ("%s\n", __FUNCTION__);
2789 applyToSet(dynAllocRegs,deallocReg);
2792 for (i = 0; i < pic14_nRegs; i++) {
2793 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2794 regspic14[i].isFree = 1;
2795 regspic14[i].wasUsed = 0;
2802 /*-----------------------------------------------------------------*/
2803 /* deallocStackSpil - this will set the stack pointer back */
2804 /*-----------------------------------------------------------------*/
2806 DEFSETFUNC (deallocStackSpil)
2810 debugLog ("%s\n", __FUNCTION__);
2815 /*-----------------------------------------------------------------*/
2816 /* farSpacePackable - returns the packable icode for far variables */
2817 /*-----------------------------------------------------------------*/
2819 farSpacePackable (iCode * ic)
2823 debugLog ("%s\n", __FUNCTION__);
2824 /* go thru till we find a definition for the
2825 symbol on the right */
2826 for (dic = ic->prev; dic; dic = dic->prev)
2829 /* if the definition is a call then no */
2830 if ((dic->op == CALL || dic->op == PCALL) &&
2831 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2836 /* if shift by unknown amount then not */
2837 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2838 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2841 /* if pointer get and size > 1 */
2842 if (POINTER_GET (dic) &&
2843 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2846 if (POINTER_SET (dic) &&
2847 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2850 /* if any three is a true symbol in far space */
2851 if (IC_RESULT (dic) &&
2852 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2853 isOperandInFarSpace (IC_RESULT (dic)))
2856 if (IC_RIGHT (dic) &&
2857 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2858 isOperandInFarSpace (IC_RIGHT (dic)) &&
2859 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2862 if (IC_LEFT (dic) &&
2863 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2864 isOperandInFarSpace (IC_LEFT (dic)) &&
2865 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2868 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2870 if ((dic->op == LEFT_OP ||
2871 dic->op == RIGHT_OP ||
2873 IS_OP_LITERAL (IC_RIGHT (dic)))
2883 /*-----------------------------------------------------------------*/
2884 /* packRegsForAssign - register reduction for assignment */
2885 /*-----------------------------------------------------------------*/
2887 packRegsForAssign (iCode * ic, eBBlock * ebp)
2892 debugLog ("%s\n", __FUNCTION__);
2894 debugAopGet (" result:", IC_RESULT (ic));
2895 debugAopGet (" left:", IC_LEFT (ic));
2896 debugAopGet (" right:", IC_RIGHT (ic));
2898 /* if this is at an absolute address, then get the address. */
2899 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2900 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2901 debugLog (" %d - found config word declaration\n", __LINE__);
2902 if(IS_VALOP(IC_RIGHT(ic))) {
2903 debugLog (" setting config word to %x\n",
2904 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2905 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2906 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2909 /* remove the assignment from the iCode chain. */
2911 remiCodeFromeBBlock (ebp, ic);
2912 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2913 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2920 if (!IS_ITEMP (IC_RESULT (ic))) {
2921 allocDirReg(IC_RESULT (ic));
2922 debugLog (" %d - result is not temp\n", __LINE__);
2925 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2926 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2927 allocDirReg(IC_LEFT (ic));
2931 if (!IS_ITEMP (IC_RIGHT (ic))) {
2932 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2934 /* only pack if this is not a function pointer */
2935 if (!IS_REF (IC_RIGHT (ic)))
2936 allocDirReg(IC_RIGHT (ic));
2940 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2941 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2943 debugLog (" %d - not packing - right side fails \n", __LINE__);
2947 /* if the true symbol is defined in far space or on stack
2948 then we should not since this will increase register pressure */
2949 if (isOperandInFarSpace (IC_RESULT (ic)))
2951 if ((dic = farSpacePackable (ic)))
2957 /* find the definition of iTempNN scanning backwards if we find a
2958 a use of the true symbol before we find the definition then
2960 for (dic = ic->prev; dic; dic = dic->prev)
2963 /* if there is a function call and this is
2964 a parameter & not my parameter then don't pack it */
2965 if ((dic->op == CALL || dic->op == PCALL) &&
2966 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2967 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2969 debugLog (" %d - \n", __LINE__);
2977 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2978 IS_OP_VOLATILE (IC_RESULT (dic)))
2980 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2985 if (IS_SYMOP (IC_RESULT (dic)) &&
2986 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2988 /* A previous result was assigned to the same register - we'll our definition */
2989 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2990 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2991 if (POINTER_SET (dic))
2997 if (IS_SYMOP (IC_RIGHT (dic)) &&
2998 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2999 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3001 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3006 if (IS_SYMOP (IC_LEFT (dic)) &&
3007 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3008 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3010 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3015 if (POINTER_SET (dic) &&
3016 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3018 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3026 return 0; /* did not find */
3028 /* if assignment then check that right is not a bit */
3029 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
3031 sym_link *etype = operandType (IC_RESULT (dic));
3032 if (IS_BITFIELD (etype))
3034 /* if result is a bit too then it's ok */
3035 etype = operandType (IC_RESULT (ic));
3036 if (!IS_BITFIELD (etype))
3041 /* if the result is on stack or iaccess then it must be
3042 the same at least one of the operands */
3043 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3044 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3047 /* the operation has only one symbol
3048 operator then we can pack */
3049 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3050 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3053 if (!((IC_LEFT (dic) &&
3054 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3056 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3060 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3061 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3062 /* found the definition */
3063 /* replace the result with the result of */
3064 /* this assignment and remove this assignment */
3065 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3066 IC_RESULT (dic) = IC_RESULT (ic);
3068 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3070 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3072 /* delete from liverange table also
3073 delete from all the points inbetween and the new
3075 for (sic = dic; sic != ic; sic = sic->next)
3077 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3078 if (IS_ITEMP (IC_RESULT (dic)))
3079 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3082 remiCodeFromeBBlock (ebp, ic);
3083 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3084 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3085 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3091 /*-----------------------------------------------------------------*/
3092 /* findAssignToSym : scanning backwards looks for first assig found */
3093 /*-----------------------------------------------------------------*/
3095 findAssignToSym (operand * op, iCode * ic)
3099 debugLog ("%s\n", __FUNCTION__);
3100 for (dic = ic->prev; dic; dic = dic->prev)
3103 /* if definition by assignment */
3104 if (dic->op == '=' &&
3105 !POINTER_SET (dic) &&
3106 IC_RESULT (dic)->key == op->key
3107 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3111 /* we are interested only if defined in far space */
3112 /* or in stack space in case of + & - */
3114 /* if assigned to a non-symbol then return
3116 if (!IS_SYMOP (IC_RIGHT (dic)))
3119 /* if the symbol is in far space then
3121 if (isOperandInFarSpace (IC_RIGHT (dic)))
3124 /* for + & - operations make sure that
3125 if it is on the stack it is the same
3126 as one of the three operands */
3127 if ((ic->op == '+' || ic->op == '-') &&
3128 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3131 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3132 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3133 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3141 /* if we find an usage then we cannot delete it */
3142 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3145 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3148 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3152 /* now make sure that the right side of dic
3153 is not defined between ic & dic */
3156 iCode *sic = dic->next;
3158 for (; sic != ic; sic = sic->next)
3159 if (IC_RESULT (sic) &&
3160 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3169 /*-----------------------------------------------------------------*/
3170 /* packRegsForSupport :- reduce some registers for support calls */
3171 /*-----------------------------------------------------------------*/
3173 packRegsForSupport (iCode * ic, eBBlock * ebp)
3177 debugLog ("%s\n", __FUNCTION__);
3178 /* for the left & right operand :- look to see if the
3179 left was assigned a true symbol in far space in that
3180 case replace them */
3181 if (IS_ITEMP (IC_LEFT (ic)) &&
3182 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3184 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3190 debugAopGet ("removing left:", IC_LEFT (ic));
3192 /* found it we need to remove it from the
3194 for (sic = dic; sic != ic; sic = sic->next)
3195 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3197 IC_LEFT (ic)->operand.symOperand =
3198 IC_RIGHT (dic)->operand.symOperand;
3199 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3200 remiCodeFromeBBlock (ebp, dic);
3201 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3202 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3206 /* do the same for the right operand */
3209 IS_ITEMP (IC_RIGHT (ic)) &&
3210 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3212 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3218 /* if this is a subtraction & the result
3219 is a true symbol in far space then don't pack */
3220 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3222 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3223 if (IN_FARSPACE (SPEC_OCLS (etype)))
3227 debugAopGet ("removing right:", IC_RIGHT (ic));
3229 /* found it we need to remove it from the
3231 for (sic = dic; sic != ic; sic = sic->next)
3232 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3234 IC_RIGHT (ic)->operand.symOperand =
3235 IC_RIGHT (dic)->operand.symOperand;
3236 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3238 remiCodeFromeBBlock (ebp, dic);
3239 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3240 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3247 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3250 /*-----------------------------------------------------------------*/
3251 /* packRegsForOneuse : - will reduce some registers for single Use */
3252 /*-----------------------------------------------------------------*/
3254 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3259 debugLog ("%s\n", __FUNCTION__);
3260 /* if returning a literal then do nothing */
3264 /* only upto 2 bytes since we cannot predict
3265 the usage of b, & acc */
3266 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3271 /* this routine will mark the a symbol as used in one
3272 instruction use only && if the definition is local
3273 (ie. within the basic block) && has only one definition &&
3274 that definition is either a return value from a
3275 function or does not contain any variables in
3277 uses = bitVectCopy (OP_USES (op));
3278 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3279 if (!bitVectIsZero (uses)) /* has other uses */
3282 /* if it has only one defintion */
3283 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3284 return NULL; /* has more than one definition */
3286 /* get that definition */
3288 hTabItemWithKey (iCodehTab,
3289 bitVectFirstBit (OP_DEFS (op)))))
3292 /* found the definition now check if it is local */
3293 if (dic->seq < ebp->fSeq ||
3294 dic->seq > ebp->lSeq)
3295 return NULL; /* non-local */
3297 /* now check if it is the return from
3299 if (dic->op == CALL || dic->op == PCALL)
3301 if (ic->op != SEND && ic->op != RETURN &&
3302 !POINTER_SET(ic) && !POINTER_GET(ic))
3304 OP_SYMBOL (op)->ruonly = 1;
3311 /* otherwise check that the definition does
3312 not contain any symbols in far space */
3313 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3314 isOperandInFarSpace (IC_RIGHT (dic)) ||
3315 IS_OP_RUONLY (IC_LEFT (ic)) ||
3316 IS_OP_RUONLY (IC_RIGHT (ic)))
3321 /* if pointer set then make sure the pointer
3323 if (POINTER_SET (dic) &&
3324 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3327 if (POINTER_GET (dic) &&
3328 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3333 /* also make sure the intervenening instructions
3334 don't have any thing in far space */
3335 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3338 /* if there is an intervening function call then no */
3339 if (dic->op == CALL || dic->op == PCALL)
3341 /* if pointer set then make sure the pointer
3343 if (POINTER_SET (dic) &&
3344 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3347 if (POINTER_GET (dic) &&
3348 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3351 /* if address of & the result is remat then okay */
3352 if (dic->op == ADDRESS_OF &&
3353 OP_SYMBOL (IC_RESULT (dic))->remat)
3356 /* if operand has size of three or more & this
3357 operation is a '*','/' or '%' then 'b' may
3359 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3360 getSize (operandType (op)) >= 3)
3363 /* if left or right or result is in far space */
3364 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3365 isOperandInFarSpace (IC_RIGHT (dic)) ||
3366 isOperandInFarSpace (IC_RESULT (dic)) ||
3367 IS_OP_RUONLY (IC_LEFT (dic)) ||
3368 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3369 IS_OP_RUONLY (IC_RESULT (dic)))
3375 OP_SYMBOL (op)->ruonly = 1;
3380 /*-----------------------------------------------------------------*/
3381 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3382 /*-----------------------------------------------------------------*/
3384 isBitwiseOptimizable (iCode * ic)
3386 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3387 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3389 debugLog ("%s\n", __FUNCTION__);
3390 /* bitwise operations are considered optimizable
3391 under the following conditions (Jean-Louis VERN)
3403 if (IS_LITERAL (rtype) ||
3404 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3410 /*-----------------------------------------------------------------*/
3411 /* packRegsForAccUse - pack registers for acc use */
3412 /*-----------------------------------------------------------------*/
3414 packRegsForAccUse (iCode * ic)
3418 debugLog ("%s\n", __FUNCTION__);
3420 /* result too large for WREG? */
3421 if (getSize (operandType (IC_RESULT (ic))) > 1)
3424 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3425 * is never used as an operand to an instruction that
3426 * cannot have WREG as an operand (e.g. BTFSx cannot
3427 * operate on WREG...
3428 * For now, store all results into proper registers. */
3432 /* if this is an aggregate, e.g. a one byte char array */
3433 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3436 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3438 /* if + or - then it has to be one byte result */
3439 if ((ic->op == '+' || ic->op == '-')
3440 && getSize (operandType (IC_RESULT (ic))) > 1)
3443 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3444 /* if shift operation make sure right side is not a literal */
3445 if (ic->op == RIGHT_OP &&
3446 (isOperandLiteral (IC_RIGHT (ic)) ||
3447 getSize (operandType (IC_RESULT (ic))) > 1))
3450 if (ic->op == LEFT_OP &&
3451 (isOperandLiteral (IC_RIGHT (ic)) ||
3452 getSize (operandType (IC_RESULT (ic))) > 1))
3455 if (IS_BITWISE_OP (ic) &&
3456 getSize (operandType (IC_RESULT (ic))) > 1)
3460 /* has only one definition */
3461 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3464 /* has only one use */
3465 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3468 /* and the usage immediately follows this iCode */
3469 if (!(uic = hTabItemWithKey (iCodehTab,
3470 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3473 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3474 if (ic->next != uic)
3477 /* if it is a conditional branch then we definitely can */
3481 if (uic->op == JUMPTABLE)
3484 /* if the usage is not is an assignment
3485 or an arithmetic / bitwise / shift operation then not */
3486 if (POINTER_SET (uic) &&
3487 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3490 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3491 if (uic->op != '=' &&
3492 !IS_ARITHMETIC_OP (uic) &&
3493 !IS_BITWISE_OP (uic) &&
3494 uic->op != LEFT_OP &&
3495 uic->op != RIGHT_OP)
3498 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3499 /* if used in ^ operation then make sure right is not a
3501 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3504 /* if shift operation make sure right side is not a literal */
3505 if (uic->op == RIGHT_OP &&
3506 (isOperandLiteral (IC_RIGHT (uic)) ||
3507 getSize (operandType (IC_RESULT (uic))) > 1))
3510 if (uic->op == LEFT_OP &&
3511 (isOperandLiteral (IC_RIGHT (uic)) ||
3512 getSize (operandType (IC_RESULT (uic))) > 1))
3515 /* make sure that the result of this icode is not on the
3516 stack, since acc is used to compute stack offset */
3517 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3518 OP_SYMBOL (IC_RESULT (uic))->onStack)
3521 /* if either one of them in far space then we cannot */
3522 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3523 isOperandInFarSpace (IC_LEFT (uic))) ||
3524 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3525 isOperandInFarSpace (IC_RIGHT (uic))))
3528 /* if the usage has only one operand then we can */
3529 if (IC_LEFT (uic) == NULL ||
3530 IC_RIGHT (uic) == NULL)
3533 /* make sure this is on the left side if not
3534 a '+' since '+' is commutative */
3535 if (ic->op != '+' &&
3536 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3539 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3540 /* if one of them is a literal then we can */
3541 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3542 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3543 (getSize (operandType (IC_RESULT (uic))) <= 1))
3545 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3549 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3550 /* if the other one is not on stack then we can */
3551 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3552 (IS_ITEMP (IC_RIGHT (uic)) ||
3553 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3554 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3557 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3558 (IS_ITEMP (IC_LEFT (uic)) ||
3559 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3560 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3566 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3567 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3571 /*-----------------------------------------------------------------*/
3572 /* packForPush - hueristics to reduce iCode for pushing */
3573 /*-----------------------------------------------------------------*/
3575 packForReceive (iCode * ic, eBBlock * ebp)
3579 debugLog ("%s\n", __FUNCTION__);
3580 debugAopGet (" result:", IC_RESULT (ic));
3581 debugAopGet (" left:", IC_LEFT (ic));
3582 debugAopGet (" right:", IC_RIGHT (ic));
3587 for (dic = ic->next; dic; dic = dic->next)
3592 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3593 debugLog (" used on left\n");
3594 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3595 debugLog (" used on right\n");
3596 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3597 debugLog (" used on result\n");
3599 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3600 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3605 debugLog (" hey we can remove this unnecessary assign\n");
3607 /*-----------------------------------------------------------------*/
3608 /* packForPush - hueristics to reduce iCode for pushing */
3609 /*-----------------------------------------------------------------*/
3611 packForPush (iCode * ic, eBBlock * ebp)
3615 debugLog ("%s\n", __FUNCTION__);
3616 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3619 /* must have only definition & one usage */
3620 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3621 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3624 /* find the definition */
3625 if (!(dic = hTabItemWithKey (iCodehTab,
3626 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3629 if (dic->op != '=' || POINTER_SET (dic))
3632 /* we now we know that it has one & only one def & use
3633 and the that the definition is an assignment */
3634 IC_LEFT (ic) = IC_RIGHT (dic);
3636 remiCodeFromeBBlock (ebp, dic);
3637 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3638 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3641 void printSymType(char * str, sym_link *sl)
3643 debugLog (" %s Symbol type: ",str);
3644 printTypeChain( sl, debugF);
3649 /*-----------------------------------------------------------------*/
3650 /* some debug code to print the symbol S_TYPE. Note that
3651 * the function checkSClass in src/SDCCsymt.c dinks with
3652 * the S_TYPE in ways the PIC port doesn't fully like...*/
3653 /*-----------------------------------------------------------------*/
3654 void isData(sym_link *sl)
3664 for ( ; sl; sl=sl->next) {
3666 switch (SPEC_SCLS(sl)) {
3668 case S_DATA: fprintf (of, "data "); break;
3669 case S_XDATA: fprintf (of, "xdata "); break;
3670 case S_SFR: fprintf (of, "sfr "); break;
3671 case S_SBIT: fprintf (of, "sbit "); break;
3672 case S_CODE: fprintf (of, "code "); break;
3673 case S_IDATA: fprintf (of, "idata "); break;
3674 case S_PDATA: fprintf (of, "pdata "); break;
3675 case S_LITERAL: fprintf (of, "literal "); break;
3676 case S_STACK: fprintf (of, "stack "); break;
3677 case S_XSTACK: fprintf (of, "xstack "); break;
3678 case S_BIT: fprintf (of, "bit "); break;
3679 case S_EEPROM: fprintf (of, "eeprom "); break;
3689 /*-----------------------------------------------------------------*/
3690 /* packRegisters - does some transformations to reduce register */
3692 /*-----------------------------------------------------------------*/
3694 packRegisters (eBBlock * ebp)
3699 debugLog ("%s\n", __FUNCTION__);
3705 /* look for assignments of the form */
3706 /* iTempNN = TRueSym (someoperation) SomeOperand */
3708 /* TrueSym := iTempNN:1 */
3709 for (ic = ebp->sch; ic; ic = ic->next)
3712 /* find assignment of the form TrueSym := iTempNN:1 */
3713 if (ic->op == '=' && !POINTER_SET (ic))
3714 change += packRegsForAssign (ic, ebp);
3718 if (POINTER_SET (ic))
3719 debugLog ("pointer is set\n");
3720 debugAopGet (" result:", IC_RESULT (ic));
3721 debugAopGet (" left:", IC_LEFT (ic));
3722 debugAopGet (" right:", IC_RIGHT (ic));
3731 for (ic = ebp->sch; ic; ic = ic->next) {
3733 if(IS_SYMOP ( IC_LEFT(ic))) {
3734 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3736 debugAopGet (" left:", IC_LEFT (ic));
3737 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3738 debugLog (" is a pointer\n");
3740 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3741 debugLog (" is volatile\n");
3745 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3748 if(IS_SYMOP ( IC_RIGHT(ic))) {
3749 debugAopGet (" right:", IC_RIGHT (ic));
3750 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3753 if(IS_SYMOP ( IC_RESULT(ic))) {
3754 debugAopGet (" result:", IC_RESULT (ic));
3755 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3758 if (POINTER_SET (ic))
3759 debugLog (" %d - Pointer set\n", __LINE__);
3762 /* Look for two subsequent iCodes with */
3764 /* _c = iTemp & op; */
3765 /* and replace them by */
3768 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3770 ic->prev->op == '=' &&
3771 IS_ITEMP (IC_LEFT (ic)) &&
3772 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3773 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3775 iCode* ic_prev = ic->prev;
3776 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3778 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3779 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3781 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3782 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3783 prev_result_sym->liveTo == ic->seq)
3785 prev_result_sym->liveTo = ic_prev->seq;
3788 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3790 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3792 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3794 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3795 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3796 remiCodeFromeBBlock (ebp, ic_prev);
3797 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3801 /* if this is an itemp & result of a address of a true sym
3802 then mark this as rematerialisable */
3803 if (ic->op == ADDRESS_OF &&
3804 IS_ITEMP (IC_RESULT (ic)) &&
3805 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3806 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3807 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3810 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3812 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3813 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3814 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3818 /* if straight assignment then carry remat flag if
3819 this is the only definition */
3820 if (ic->op == '=' &&
3821 !POINTER_SET (ic) &&
3822 IS_SYMOP (IC_RIGHT (ic)) &&
3823 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3824 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3826 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3828 OP_SYMBOL (IC_RESULT (ic))->remat =
3829 OP_SYMBOL (IC_RIGHT (ic))->remat;
3830 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3831 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3834 /* if this is a +/- operation with a rematerizable
3835 then mark this as rematerializable as well */
3836 if ((ic->op == '+' || ic->op == '-') &&
3837 (IS_SYMOP (IC_LEFT (ic)) &&
3838 IS_ITEMP (IC_RESULT (ic)) &&
3839 OP_SYMBOL (IC_LEFT (ic))->remat &&
3840 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3841 IS_OP_LITERAL (IC_RIGHT (ic))))
3843 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3845 operandLitValue (IC_RIGHT (ic));
3846 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3847 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3848 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3851 /* mark the pointer usages */
3852 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3854 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3855 debugLog (" marking as a pointer (set) =>");
3856 debugAopGet (" result:", IC_RESULT (ic));
3858 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3860 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3861 debugLog (" marking as a pointer (get) =>");
3862 debugAopGet (" left:", IC_LEFT (ic));
3867 /* if we are using a symbol on the stack
3868 then we should say pic14_ptrRegReq */
3869 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3870 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3871 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3872 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3873 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3874 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3877 if (IS_SYMOP (IC_LEFT (ic)))
3878 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3879 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3880 if (IS_SYMOP (IC_RIGHT (ic)))
3881 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3882 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3883 if (IS_SYMOP (IC_RESULT (ic)))
3884 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3885 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3888 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3892 /* if the condition of an if instruction
3893 is defined in the previous instruction then
3894 mark the itemp as a conditional */
3895 if ((IS_CONDITIONAL (ic) ||
3896 ((ic->op == BITWISEAND ||
3899 isBitwiseOptimizable (ic))) &&
3900 ic->next && ic->next->op == IFX &&
3901 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3902 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3905 debugLog (" %d\n", __LINE__);
3906 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3910 /* reduce for support function calls */
3911 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3912 packRegsForSupport (ic, ebp);
3914 /* if a parameter is passed, it's in W, so we may not
3915 need to place a copy in a register */
3916 if (ic->op == RECEIVE)
3917 packForReceive (ic, ebp);
3919 /* some cases the redundant moves can
3920 can be eliminated for return statements */
3921 if ((ic->op == RETURN || ic->op == SEND) &&
3922 !isOperandInFarSpace (IC_LEFT (ic)) &&
3924 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3926 /* if pointer set & left has a size more than
3927 one and right is not in far space */
3928 if (POINTER_SET (ic) &&
3929 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3930 IS_SYMOP(IC_RESULT(ic)) &&
3931 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3932 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3933 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3935 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3937 /* if pointer get */
3938 if (POINTER_GET (ic) &&
3939 !isOperandInFarSpace (IC_RESULT (ic)) &&
3940 IS_SYMOP(IC_LEFT(ic)) &&
3941 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3942 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3943 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3945 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3948 /* if this is cast for intergral promotion then
3949 check if only use of the definition of the
3950 operand being casted/ if yes then replace
3951 the result of that arithmetic operation with
3952 this result and get rid of the cast */
3953 if (ic->op == CAST) {
3955 sym_link *fromType = operandType (IC_RIGHT (ic));
3956 sym_link *toType = operandType (IC_LEFT (ic));
3958 debugLog (" %d - casting\n", __LINE__);
3960 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3961 getSize (fromType) != getSize (toType)) {
3964 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3967 if (IS_ARITHMETIC_OP (dic)) {
3969 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3970 IC_RESULT (dic) = IC_RESULT (ic);
3971 remiCodeFromeBBlock (ebp, ic);
3972 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3973 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3974 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3978 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3982 /* if the type from and type to are the same
3983 then if this is the only use then packit */
3984 if (compareType (operandType (IC_RIGHT (ic)),
3985 operandType (IC_LEFT (ic))) == 1) {
3987 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3990 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3991 IC_RESULT (dic) = IC_RESULT (ic);
3992 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3993 remiCodeFromeBBlock (ebp, ic);
3994 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3995 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4003 iTempNN := (some variable in farspace) V1
4008 if (ic->op == IPUSH)
4010 packForPush (ic, ebp);
4014 /* pack registers for accumulator use, when the
4015 result of an arithmetic or bit wise operation
4016 has only one use, that use is immediately following
4017 the defintion and the using iCode has only one
4018 operand or has two operands but one is literal &
4019 the result of that operation is not on stack then
4020 we can leave the result of this operation in acc:b
4022 if ((IS_ARITHMETIC_OP (ic)
4024 || IS_BITWISE_OP (ic)
4026 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4029 IS_ITEMP (IC_RESULT (ic)) &&
4030 getSize (operandType (IC_RESULT (ic))) <= 2)
4032 packRegsForAccUse (ic);
4038 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4042 if (!debug || !debugF)
4045 for (i = 0; i < count; i++)
4047 fprintf (debugF, "\n----------------------------------------------------------------\n");
4048 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4049 ebbs[i]->entryLabel->name,
4052 ebbs[i]->isLastInLoop);
4053 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4058 fprintf (debugF, "visited %d : hasFcall = %d\n",
4062 fprintf (debugF, "\ndefines bitVector :");
4063 bitVectDebugOn (ebbs[i]->defSet, debugF);
4064 fprintf (debugF, "\nlocal defines bitVector :");
4065 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4066 fprintf (debugF, "\npointers Set bitvector :");
4067 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4068 fprintf (debugF, "\nin pointers Set bitvector :");
4069 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4070 fprintf (debugF, "\ninDefs Set bitvector :");
4071 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4072 fprintf (debugF, "\noutDefs Set bitvector :");
4073 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4074 fprintf (debugF, "\nusesDefs Set bitvector :");
4075 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4076 fprintf (debugF, "\n----------------------------------------------------------------\n");
4077 printiCChain (ebbs[i]->sch, debugF);
4080 /*-----------------------------------------------------------------*/
4081 /* assignRegisters - assigns registers to each live range as need */
4082 /*-----------------------------------------------------------------*/
4084 pic14_assignRegisters (ebbIndex * ebbi)
4086 eBBlock ** ebbs = ebbi->bbOrder;
4087 int count = ebbi->count;
4091 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4092 debugLog ("ebbs before optimizing:\n");
4093 dumpEbbsToDebug (ebbs, count);
4095 setToNull ((void *) &_G.funcrUsed);
4096 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4099 /* change assignments this will remove some
4100 live ranges reducing some register pressure */
4101 for (i = 0; i < count; i++)
4102 packRegisters (ebbs[i]);
4109 debugLog("dir registers allocated so far:\n");
4110 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4113 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4114 reg = hTabNextItem(dynDirectRegNames, &hkey);
4119 if (options.dump_pack)
4120 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4122 /* first determine for each live range the number of
4123 registers & the type of registers required for each */
4126 /* and serially allocate registers */
4127 serialRegAssign (ebbs, count);
4129 /* if stack was extended then tell the user */
4132 /* werror(W_TOOMANY_SPILS,"stack", */
4133 /* _G.stackExtend,currFunc->name,""); */
4139 /* werror(W_TOOMANY_SPILS,"data space", */
4140 /* _G.dataExtend,currFunc->name,""); */
4144 /* after that create the register mask
4145 for each of the instruction */
4146 createRegMask (ebbs, count);
4148 /* redo that offsets for stacked automatic variables */
4149 redoStackOffsets ();
4151 if (options.dump_rassgn)
4152 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4154 /* now get back the chain */
4155 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4157 debugLog ("ebbs after optimizing:\n");
4158 dumpEbbsToDebug (ebbs, count);
4163 /* free up any _G.stackSpil locations allocated */
4164 applyToSet (_G.stackSpil, deallocStackSpil);
4166 setToNull ((void *) &_G.stackSpil);
4167 setToNull ((void *) &_G.spiltSet);
4168 /* mark all registers as free */
4169 //pic14_freeAllRegs ();
4171 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");