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 *);
91 static int debug = 0; // should be 0 when committed, creates .d files
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 debugLog is called, we'll append the debug info
126 vsprintf (buffer, fmt, ap);
129 fprintf (debugF, "%s", buffer);
130 //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
137 fputc ('\n', debugF);
139 /*-----------------------------------------------------------------*/
140 /* pic14_debugLogClose - closes the debug log file (if opened) */
141 /*-----------------------------------------------------------------*/
143 pic14_debugLogClose (void)
151 #define AOP(op) op->aop
154 debugAopGet (char *str, operand * op)
156 if (!debug) return NULL;
158 if (str) debugLog (str);
160 printOperand (op, debugF);
167 decodeOp (unsigned int op)
170 if (op < 128 && op > ' ')
172 buffer[0] = (op & 0xff);
179 case IDENTIFIER: return "IDENTIFIER";
180 case TYPE_NAME: return "TYPE_NAME";
181 case CONSTANT: return "CONSTANT";
182 case STRING_LITERAL: return "STRING_LITERAL";
183 case SIZEOF: return "SIZEOF";
184 case PTR_OP: return "PTR_OP";
185 case INC_OP: return "INC_OP";
186 case DEC_OP: return "DEC_OP";
187 case LEFT_OP: return "LEFT_OP";
188 case RIGHT_OP: return "RIGHT_OP";
189 case LE_OP: return "LE_OP";
190 case GE_OP: return "GE_OP";
191 case EQ_OP: return "EQ_OP";
192 case NE_OP: return "NE_OP";
193 case AND_OP: return "AND_OP";
194 case OR_OP: return "OR_OP";
195 case MUL_ASSIGN: return "MUL_ASSIGN";
196 case DIV_ASSIGN: return "DIV_ASSIGN";
197 case MOD_ASSIGN: return "MOD_ASSIGN";
198 case ADD_ASSIGN: return "ADD_ASSIGN";
199 case SUB_ASSIGN: return "SUB_ASSIGN";
200 case LEFT_ASSIGN: return "LEFT_ASSIGN";
201 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
202 case AND_ASSIGN: return "AND_ASSIGN";
203 case XOR_ASSIGN: return "XOR_ASSIGN";
204 case OR_ASSIGN: return "OR_ASSIGN";
205 case TYPEDEF: return "TYPEDEF";
206 case EXTERN: return "EXTERN";
207 case STATIC: return "STATIC";
208 case AUTO: return "AUTO";
209 case REGISTER: return "REGISTER";
210 case CODE: return "CODE";
211 case EEPROM: return "EEPROM";
212 case INTERRUPT: return "INTERRUPT";
213 case SFR: return "SFR";
214 case AT: return "AT";
215 case SBIT: return "SBIT";
216 case REENTRANT: return "REENTRANT";
217 case USING: return "USING";
218 case XDATA: return "XDATA";
219 case DATA: return "DATA";
220 case IDATA: return "IDATA";
221 case PDATA: return "PDATA";
222 case VAR_ARGS: return "VAR_ARGS";
223 case CRITICAL: return "CRITICAL";
224 case NONBANKED: return "NONBANKED";
225 case BANKED: return "BANKED";
226 case CHAR: return "CHAR";
227 case SHORT: return "SHORT";
228 case INT: return "INT";
229 case LONG: return "LONG";
230 case SIGNED: return "SIGNED";
231 case UNSIGNED: return "UNSIGNED";
232 case FLOAT: return "FLOAT";
233 case DOUBLE: return "DOUBLE";
234 case CONST: return "CONST";
235 case VOLATILE: return "VOLATILE";
236 case VOID: return "VOID";
237 case BIT: return "BIT";
238 case STRUCT: return "STRUCT";
239 case UNION: return "UNION";
240 case ENUM: return "ENUM";
241 case RANGE: return "RANGE";
242 case FAR: return "FAR";
243 case CASE: return "CASE";
244 case DEFAULT: return "DEFAULT";
245 case IF: return "IF";
246 case ELSE: return "ELSE";
247 case SWITCH: return "SWITCH";
248 case WHILE: return "WHILE";
249 case DO: return "DO";
250 case FOR: return "FOR";
251 case GOTO: return "GOTO";
252 case CONTINUE: return "CONTINUE";
253 case BREAK: return "BREAK";
254 case RETURN: return "RETURN";
255 case INLINEASM: return "INLINEASM";
256 case IFX: return "IFX";
257 case ADDRESS_OF: return "ADDRESS_OF";
258 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
259 case SPIL: return "SPIL";
260 case UNSPIL: return "UNSPIL";
261 case GETHBIT: return "GETHBIT";
262 case BITWISEAND: return "BITWISEAND";
263 case UNARYMINUS: return "UNARYMINUS";
264 case IPUSH: return "IPUSH";
265 case IPOP: return "IPOP";
266 case PCALL: return "PCALL";
267 case ENDFUNCTION: return "ENDFUNCTION";
268 case JUMPTABLE: return "JUMPTABLE";
269 case RRC: return "RRC";
270 case RLC: return "RLC";
271 case CAST: return "CAST";
272 case CALL: return "CALL";
273 case PARAM: return "PARAM ";
274 case NULLOP: return "NULLOP";
275 case BLOCK: return "BLOCK";
276 case LABEL: return "LABEL";
277 case RECEIVE: return "RECEIVE";
278 case SEND: return "SEND";
280 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
283 /*-----------------------------------------------------------------*/
284 /*-----------------------------------------------------------------*/
286 debugLogRegType (short type)
291 case REG_GPR: return "REG_GPR";
292 case REG_PTR: return "REG_PTR";
293 case REG_CND: return "REG_CND";
296 sprintf (buffer, "unknown reg type %d", type);
300 /*-----------------------------------------------------------------*/
301 /*-----------------------------------------------------------------*/
302 static int regname2key(char const *name)
311 key += (*name++) + 1;
315 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
319 static regs *regWithIdx (set *dRegs, int idx, int fixed);
320 /*-----------------------------------------------------------------*/
321 /* newReg - allocate and init memory for a new register */
322 /*-----------------------------------------------------------------*/
323 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
326 regs *dReg, *reg_alias;
328 /* check whether a matching register already exists */
329 dReg = dirregWithName( name );
331 //printf( "%s: already present: %s\n", __FUNCTION__, name );
335 // check whether a register at that location exists
336 reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
337 if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
339 // create a new register
340 dReg = Safe_calloc(1,sizeof(regs));
342 dReg->pc_type = pc_type;
345 dReg->name = Safe_strdup(name);
347 sprintf(buffer,"r0x%02X", dReg->rIdx);
348 dReg->name = Safe_strdup(buffer);
364 dReg->reg_alias = reg_alias;
365 dReg->reglives.usedpFlows = newSet();
366 dReg->reglives.assignedpFlows = newSet();
367 if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
368 debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
373 /*-----------------------------------------------------------------*/
374 /* regWithIdx - Search through a set of registers that matches idx */
375 /*-----------------------------------------------------------------*/
377 regWithIdx (set *dRegs, int idx, int fixed)
381 for (dReg = setFirstItem(dRegs) ; dReg ;
382 dReg = setNextItem(dRegs)) {
384 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
385 while (dReg->reg_alias) dReg = dReg->reg_alias;
393 /*-----------------------------------------------------------------*/
394 /* regWithName - Search through a set of registers that matches name */
395 /*-----------------------------------------------------------------*/
397 regWithName (set *dRegs, const char *name)
401 for (dReg = setFirstItem(dRegs) ; dReg ;
402 dReg = setNextItem(dRegs)) {
404 if((strcmp(name,dReg->name)==0)) {
412 /*-----------------------------------------------------------------*/
413 /* regWithName - Search for a registers that matches name */
414 /*-----------------------------------------------------------------*/
416 regFindWithName (const char *name)
420 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
421 debugLog ("Found a Direct Register!\n");
424 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
425 debugLog ("Found a Direct Bit Register!\n");
429 if (*name=='_') name++; // Step passed '_'
431 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
432 debugLog ("Found a Dynamic Register!\n");
435 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
436 debugLog ("Found a Processor Register!\n");
439 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
440 debugLog ("Found an Internal Register!\n");
443 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
444 debugLog ("Found an Stack Register!\n");
451 /*-----------------------------------------------------------------*/
452 /* regFindFree - Search for a free register in a set of registers */
453 /*-----------------------------------------------------------------*/
455 regFindFree (set *dRegs)
459 for (dReg = setFirstItem(dRegs) ; dReg ;
460 dReg = setNextItem(dRegs)) {
468 /*-----------------------------------------------------------------*/
469 /* initStack - allocate registers for a pseudo stack */
470 /*-----------------------------------------------------------------*/
471 void initStack(int base_address, int size, int shared)
477 pic = pic14_getPIC();
478 Gstack_base_addr = base_address;
480 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
482 for(i = 0; i<size; i++) {
485 SNPRINTF(&buffer[0], 16, "STK%02d", i);
486 // multi-bank device, sharebank prohibited by user
487 r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
492 addSet(&dynStackRegs,r);
496 /*-----------------------------------------------------------------*
497 *-----------------------------------------------------------------*/
499 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
502 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
503 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
506 /*-----------------------------------------------------------------*
507 *-----------------------------------------------------------------*/
510 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
512 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
514 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
517 return addSet(&dynInternalRegs,reg);
522 /*-----------------------------------------------------------------*/
523 /* allocReg - allocates register of given type */
524 /*-----------------------------------------------------------------*/
526 allocReg (short type)
530 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
531 //fprintf(stderr,"allocReg\n");
533 reg = pic14_findFreeReg (type);
541 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
546 /*-----------------------------------------------------------------*/
547 /* dirregWithName - search for register by name */
548 /*-----------------------------------------------------------------*/
550 dirregWithName (char *name)
558 /* hash the name to get a key */
560 hkey = regname2key(name);
562 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
566 if(STRCASECMP(reg->name, name) == 0) {
567 // handle registers with multiple names
568 while (reg->reg_alias) reg = reg->reg_alias;
572 reg = hTabNextItemWK (dynDirectRegNames);
576 return NULL; // name wasn't found in the hash table
579 int IS_CONFIG_ADDRESS(int address)
582 return ((address == 0x2007) || (address == 0x2008));
585 /*-----------------------------------------------------------------*/
586 /* allocNewDirReg - allocates a new register of given type */
587 /*-----------------------------------------------------------------*/
589 allocNewDirReg (sym_link *symlnk,const char *name)
593 sym_link *spec = getSpec (symlnk);
595 /* if this is at an absolute address, then get the address. */
596 if (SPEC_ABSA (spec) ) {
597 address = SPEC_ADDR (spec);
598 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
601 /* Register wasn't found in hash, so let's create
602 * a new one and put it in the hash table AND in the
603 * dynDirectRegNames set */
604 if (IS_CONFIG_ADDRESS(address)) {
605 debugLog (" -- %s is declared at address 0x2007\n",name);
610 if (IS_BITVAR (spec))
617 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
618 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
620 if (SPEC_ABSA (spec) ) {
624 if (IS_BITVAR (spec)) {
625 addSet(&dynDirectBitRegs, reg);
628 addSet(&dynDirectRegs, reg);
630 if (!IS_STATIC (spec)) {
633 if (IS_EXTERN (spec)) {
639 if (address && reg) {
641 reg->address = address;
642 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
648 /*-----------------------------------------------------------------*/
649 /* allocDirReg - allocates register of given type */
650 /*-----------------------------------------------------------------*/
652 allocDirReg (operand *op )
659 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
663 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
665 /* If the symbol is at a fixed address, then remove the leading underscore
666 * from the name. This is hack to allow the .asm include file named registers
667 * to match the .c declared register names */
669 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
672 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
674 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
675 debugLog(" %d const char\n",__LINE__);
676 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
679 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
680 if (IS_CODE ( OP_SYM_ETYPE(op)) )
681 debugLog(" %d code space\n",__LINE__);
683 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
684 debugLog(" %d integral\n",__LINE__);
685 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
686 debugLog(" %d literal\n",__LINE__);
687 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
688 debugLog(" %d specifier\n",__LINE__);
689 debugAopGet(NULL, op);
692 if (IS_CODE ( OP_SYM_ETYPE(op)) )
695 /* First, search the hash table to see if there is a register with this name */
696 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
697 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
700 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
701 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
703 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
704 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
707 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
709 reg = dirregWithName(name);
716 /* if this is at an absolute address, then get the address. */
717 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
718 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
719 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
722 /* Register wasn't found in hash, so let's create
723 * a new one and put it in the hash table AND in the
724 * dynDirectRegNames set */
725 if(!IS_CONFIG_ADDRESS(address)) {
726 //fprintf(stderr,"allocating new reg %s\n",name);
728 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
729 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
731 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
733 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
735 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
739 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
740 addSet(&dynDirectBitRegs, reg);
743 addSet(&dynDirectRegs, reg);
745 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
748 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
754 debugLog (" -- %s is declared at address 0x2007\n",name);
759 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
761 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
762 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
767 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
769 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
770 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
773 allocNewDirReg (OP_SYM_TYPE(op),name);
780 /*-----------------------------------------------------------------*/
781 /* allocRegByName - allocates register with given name */
782 /*-----------------------------------------------------------------*/
784 allocRegByName (char *name, int size)
790 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
794 /* First, search the hash table to see if there is a register with this name */
795 reg = dirregWithName(name);
801 /* Register wasn't found in hash, so let's create
802 * a new one and put it in the hash table AND in the
803 * dynDirectRegNames set */
804 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
805 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
806 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
807 if (strcmp(reg->name+1,sym->name)==0) {
808 unsigned a = SPEC_ADDR(sym->etype);
812 if (!IS_STATIC (sym->etype)) {
815 if (IS_EXTERN (sym->etype)) {
818 if (IS_BITVAR (sym->etype))
825 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
826 if (strcmp(reg->name+1,sym->name)==0) {
827 unsigned a = SPEC_ADDR(sym->etype);
829 if (!IS_STATIC (sym->etype)) {
832 if (IS_EXTERN (sym->etype)) {
835 if (IS_BITVAR (sym->etype))
843 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
845 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
846 if (reg->isBitField) {
847 addSet(&dynDirectBitRegs, reg);
849 addSet(&dynDirectRegs, reg);
855 /*-----------------------------------------------------------------*/
856 /* RegWithIdx - returns pointer to register with index number */
857 /*-----------------------------------------------------------------*/
859 typeRegWithIdx (int idx, int type, int fixed)
864 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
869 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
871 debugLog ("Found a Dynamic Register!\n");
874 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
875 debugLog ("Found a Direct Register!\n");
881 if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
882 debugLog ("Found a Stack Register!\n");
885 if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
886 debugLog ("Found a Stack Register!\n");
890 werror (E_STACK_OUT, "Register");
891 /* return an existing register just to avoid the SDCC crash */
892 return regWithIdx ( dynStackRegs, 0x7f, 0);
896 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
897 debugLog ("Found a Processor Register!\n");
911 /*-----------------------------------------------------------------*/
912 /* pic14_regWithIdx - returns pointer to register with index number*/
913 /*-----------------------------------------------------------------*/
915 pic14_regWithIdx (int idx)
919 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
922 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
928 /*-----------------------------------------------------------------*/
929 /* pic14_regWithIdx - returns pointer to register with index number */
930 /*-----------------------------------------------------------------*/
932 pic14_allocWithIdx (int idx)
937 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
939 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
941 debugLog ("Found a Dynamic Register!\n");
942 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
943 debugLog ("Found a Stack Register!\n");
944 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
945 debugLog ("Found a Processor Register!\n");
946 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
947 debugLog ("Found an Internal Register!\n");
948 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
949 debugLog ("Found an Internal Register!\n");
952 debugLog ("Dynamic Register not found\n");
955 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
956 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
957 "regWithIdx not found");
967 /*-----------------------------------------------------------------*/
968 /*-----------------------------------------------------------------*/
970 pic14_findFreeReg(short type)
977 if((dReg = regFindFree(dynAllocRegs)) != NULL)
979 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
983 if((dReg = regFindFree(dynStackRegs)) != NULL)
995 /*-----------------------------------------------------------------*/
996 /* freeReg - frees a register */
997 /*-----------------------------------------------------------------*/
1001 debugLog ("%s\n", __FUNCTION__);
1006 /*-----------------------------------------------------------------*/
1007 /* nFreeRegs - returns number of free registers */
1008 /*-----------------------------------------------------------------*/
1010 nFreeRegs (int type)
1012 /* dynamically allocate as many as we need and worry about
1013 * fitting them into a PIC later */
1020 debugLog ("%s\n", __FUNCTION__);
1021 for (i = 0; i < pic14_nRegs; i++)
1022 if (regspic14[i].isFree && regspic14[i].type == type)
1028 /*-----------------------------------------------------------------*/
1029 /* nfreeRegsType - free registers with type */
1030 /*-----------------------------------------------------------------*/
1032 nfreeRegsType (int type)
1035 debugLog ("%s\n", __FUNCTION__);
1036 if (type == REG_PTR)
1038 if ((nfr = nFreeRegs (type)) == 0)
1039 return nFreeRegs (REG_GPR);
1042 return nFreeRegs (type);
1045 void writeSetUsedRegs(FILE *of, set *dRegs)
1050 for (dReg = setFirstItem(dRegs) ; dReg ;
1051 dReg = setNextItem(dRegs)) {
1054 fprintf (of, "\t%s\n",dReg->name);
1058 extern void dump_map(void);
1060 void packBits(set *bregs)
1064 regs *bitfield=NULL;
1065 regs *relocbitfield=NULL;
1071 for (regset = bregs ; regset ;
1072 regset = regset->next) {
1074 breg = regset->item;
1075 breg->isBitField = 1;
1076 //fprintf(stderr,"bit reg: %s\n",breg->name);
1079 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1081 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1082 breg->rIdx = breg->address & 7;
1083 breg->address >>= 3;
1086 //sprintf (buffer, "fbitfield%02x", breg->address);
1087 sprintf (buffer, "0x%02x", breg->address);
1088 //fprintf(stderr,"new bit field\n");
1089 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1090 bitfield->isBitField = 1;
1091 bitfield->isFixed = 1;
1092 bitfield->address = breg->address;
1093 //addSet(&dynDirectRegs,bitfield);
1094 addSet(&dynInternalRegs,bitfield);
1095 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1097 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1100 breg->reg_alias = bitfield;
1104 if(!relocbitfield || bit_no >7) {
1107 sprintf (buffer, "bitfield%d", byte_no);
1108 //fprintf(stderr,"new relocatable bit field\n");
1109 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
1110 relocbitfield->isBitField = 1;
1111 //addSet(&dynDirectRegs,relocbitfield);
1112 addSet(&dynInternalRegs,relocbitfield);
1113 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1117 breg->reg_alias = relocbitfield;
1118 breg->address = dynrIdx; /* byte_no; */
1119 breg->rIdx = bit_no++;
1127 void bitEQUs(FILE *of, set *bregs)
1129 regs *breg,*bytereg;
1132 //fprintf(stderr," %s\n",__FUNCTION__);
1133 for (breg = setFirstItem(bregs) ; breg ;
1134 breg = setNextItem(bregs)) {
1136 //fprintf(stderr,"bit reg: %s\n",breg->name);
1138 bytereg = breg->reg_alias;
1140 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1143 breg->rIdx & 0x0007);
1146 //fprintf(stderr, "bit field is not assigned to a register\n");
1147 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1158 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1163 for (reg = setFirstItem(fregs) ; reg ;
1164 reg = setNextItem(fregs)) {
1166 //if(!reg->isEmitted && reg->wasUsed) {
1169 fprintf (of, "%s\tEQU\t0x%03x\n",
1173 fprintf (of, "%s\tEQU\t0x%03x\n",
1181 void writeUsedRegs(FILE *of)
1184 packBits(dynDirectBitRegs);
1188 bitEQUs(of,dynDirectBitRegs);
1191 /*-----------------------------------------------------------------*/
1192 /* computeSpillable - given a point find the spillable live ranges */
1193 /*-----------------------------------------------------------------*/
1195 computeSpillable (iCode * ic)
1199 debugLog ("%s\n", __FUNCTION__);
1200 /* spillable live ranges are those that are live at this
1201 point . the following categories need to be subtracted
1203 a) - those that are already spilt
1204 b) - if being used by this one
1205 c) - defined by this one */
1207 spillable = bitVectCopy (ic->rlive);
1209 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1211 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1212 bitVectUnSetBit (spillable, ic->defKey);
1213 spillable = bitVectIntersect (spillable, _G.regAssigned);
1218 /*-----------------------------------------------------------------*/
1219 /* noSpilLoc - return true if a variable has no spil location */
1220 /*-----------------------------------------------------------------*/
1222 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1224 debugLog ("%s\n", __FUNCTION__);
1225 return (sym->usl.spillLoc ? 0 : 1);
1228 /*-----------------------------------------------------------------*/
1229 /* hasSpilLoc - will return 1 if the symbol has spil location */
1230 /*-----------------------------------------------------------------*/
1232 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1234 debugLog ("%s\n", __FUNCTION__);
1235 return (sym->usl.spillLoc ? 1 : 0);
1238 /*-----------------------------------------------------------------*/
1239 /* directSpilLoc - will return 1 if the splilocation is in direct */
1240 /*-----------------------------------------------------------------*/
1242 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1244 debugLog ("%s\n", __FUNCTION__);
1245 if (sym->usl.spillLoc &&
1246 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1252 /*-----------------------------------------------------------------*/
1253 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1254 /* but is not used as a pointer */
1255 /*-----------------------------------------------------------------*/
1257 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1259 debugLog ("%s\n", __FUNCTION__);
1260 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1263 /*-----------------------------------------------------------------*/
1264 /* rematable - will return 1 if the remat flag is set */
1265 /*-----------------------------------------------------------------*/
1267 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1269 debugLog ("%s\n", __FUNCTION__);
1273 /*-----------------------------------------------------------------*/
1274 /* notUsedInRemaining - not used or defined in remain of the block */
1275 /*-----------------------------------------------------------------*/
1277 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1279 debugLog ("%s\n", __FUNCTION__);
1280 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1281 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1284 /*-----------------------------------------------------------------*/
1285 /* allLRs - return true for all */
1286 /*-----------------------------------------------------------------*/
1288 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1290 debugLog ("%s\n", __FUNCTION__);
1294 /*-----------------------------------------------------------------*/
1295 /* liveRangesWith - applies function to a given set of live range */
1296 /*-----------------------------------------------------------------*/
1298 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1299 eBBlock * ebp, iCode * ic)
1304 debugLog ("%s\n", __FUNCTION__);
1305 if (!lrs || !lrs->size)
1308 for (i = 1; i < lrs->size; i++)
1311 if (!bitVectBitValue (lrs, i))
1314 /* if we don't find it in the live range
1315 hash table we are in serious trouble */
1316 if (!(sym = hTabItemWithKey (liveRanges, i)))
1318 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1319 "liveRangesWith could not find liveRange");
1323 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1324 addSetHead (&rset, sym);
1331 /*-----------------------------------------------------------------*/
1332 /* leastUsedLR - given a set determines which is the least used */
1333 /*-----------------------------------------------------------------*/
1335 leastUsedLR (set * sset)
1337 symbol *sym = NULL, *lsym = NULL;
1339 debugLog ("%s\n", __FUNCTION__);
1340 sym = lsym = setFirstItem (sset);
1345 for (; lsym; lsym = setNextItem (sset))
1348 /* if usage is the same then prefer
1349 the spill the smaller of the two */
1350 if (lsym->used == sym->used)
1351 if (getSize (lsym->type) < getSize (sym->type))
1355 if (lsym->used < sym->used)
1360 setToNull ((void *) &sset);
1365 /*-----------------------------------------------------------------*/
1366 /* noOverLap - will iterate through the list looking for over lap */
1367 /*-----------------------------------------------------------------*/
1369 noOverLap (set * itmpStack, symbol * fsym)
1372 debugLog ("%s\n", __FUNCTION__);
1375 for (sym = setFirstItem (itmpStack); sym;
1376 sym = setNextItem (itmpStack))
1378 if (sym->liveTo > fsym->liveFrom)
1386 /*-----------------------------------------------------------------*/
1387 /* isFree - will return 1 if the a free spil location is found */
1388 /*-----------------------------------------------------------------*/
1393 V_ARG (symbol **, sloc);
1394 V_ARG (symbol *, fsym);
1396 debugLog ("%s\n", __FUNCTION__);
1397 /* if already found */
1401 /* if it is free && and the itmp assigned to
1402 this does not have any overlapping live ranges
1403 with the one currently being assigned and
1404 the size can be accomodated */
1406 noOverLap (sym->usl.itmpStack, fsym) &&
1407 getSize (sym->type) >= getSize (fsym->type))
1416 /*-----------------------------------------------------------------*/
1417 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1418 /*-----------------------------------------------------------------*/
1420 spillLRWithPtrReg (symbol * forSym)
1426 debugLog ("%s\n", __FUNCTION__);
1427 if (!_G.regAssigned ||
1428 bitVectIsZero (_G.regAssigned))
1431 r0 = pic14_regWithIdx (R0_IDX);
1432 r1 = pic14_regWithIdx (R1_IDX);
1434 /* for all live ranges */
1435 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1436 lrsym = hTabNextItem (liveRanges, &k))
1440 /* if no registers assigned to it or
1442 /* if it does not overlap with this then
1443 not need to spill it */
1445 if (lrsym->isspilt || !lrsym->nRegs ||
1446 (lrsym->liveTo < forSym->liveFrom))
1449 /* go thru the registers : if it is either
1450 r0 or r1 then spil it */
1451 for (j = 0; j < lrsym->nRegs; j++)
1452 if (lrsym->regs[j] == r0 ||
1453 lrsym->regs[j] == r1)
1462 /*-----------------------------------------------------------------*/
1463 /* createStackSpil - create a location on the stack to spil */
1464 /*-----------------------------------------------------------------*/
1466 createStackSpil (symbol * sym)
1468 symbol *sloc = NULL;
1469 int useXstack, model, noOverlay;
1471 char slocBuffer[30];
1472 debugLog ("%s\n", __FUNCTION__);
1476 /* first go try and find a free one that is already
1477 existing on the stack */
1478 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1480 /* found a free one : just update & return */
1481 sym->usl.spillLoc = sloc;
1484 addSetHead (&sloc->usl.itmpStack, sym);
1488 /* could not then have to create one , this is the hard part
1489 we need to allocate this on the stack : this is really a
1490 hack!! but cannot think of anything better at this time */
1492 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1494 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1495 __FILE__, __LINE__);
1499 sloc = newiTemp (slocBuffer);
1501 /* set the type to the spilling symbol */
1502 sloc->type = copyLinkChain (sym->type);
1503 sloc->etype = getSpec (sloc->type);
1504 SPEC_SCLS (sloc->etype) = S_DATA;
1505 SPEC_EXTR (sloc->etype) = 0;
1506 SPEC_STAT (sloc->etype) = 0;
1508 /* we don't allow it to be allocated`
1509 onto the external stack since : so we
1510 temporarily turn it off ; we also
1511 turn off memory model to prevent
1512 the spil from going to the external storage
1513 and turn off overlaying
1516 useXstack = options.useXstack;
1517 model = options.model;
1518 noOverlay = options.noOverlay;
1519 options.noOverlay = 1;
1520 options.model = options.useXstack = 0;
1524 options.useXstack = useXstack;
1525 options.model = model;
1526 options.noOverlay = noOverlay;
1527 sloc->isref = 1; /* to prevent compiler warning */
1529 /* if it is on the stack then update the stack */
1530 if (IN_STACK (sloc->etype))
1532 currFunc->stack += getSize (sloc->type);
1533 _G.stackExtend += getSize (sloc->type);
1536 _G.dataExtend += getSize (sloc->type);
1538 /* add it to the _G.stackSpil set */
1539 addSetHead (&_G.stackSpil, sloc);
1540 sym->usl.spillLoc = sloc;
1543 /* add it to the set of itempStack set
1544 of the spill location */
1545 addSetHead (&sloc->usl.itmpStack, sym);
1549 /*-----------------------------------------------------------------*/
1550 /* isSpiltOnStack - returns true if the spil location is on stack */
1551 /*-----------------------------------------------------------------*/
1553 isSpiltOnStack (symbol * sym)
1557 debugLog ("%s\n", __FUNCTION__);
1566 /* if (sym->_G.stackSpil) */
1569 if (!sym->usl.spillLoc)
1572 etype = getSpec (sym->usl.spillLoc->type);
1573 if (IN_STACK (etype))
1579 /*-----------------------------------------------------------------*/
1580 /* spillThis - spils a specific operand */
1581 /*-----------------------------------------------------------------*/
1583 spillThis (symbol * sym)
1586 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1587 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1589 /* if this is rematerializable or has a spillLocation
1590 we are okay, else we need to create a spillLocation
1592 if (!(sym->remat || sym->usl.spillLoc))
1593 createStackSpil (sym);
1596 /* mark it has spilt & put it in the spilt set */
1598 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1600 bitVectUnSetBit (_G.regAssigned, sym->key);
1602 for (i = 0; i < sym->nRegs; i++)
1606 freeReg (sym->regs[i]);
1607 sym->regs[i] = NULL;
1611 /* if spilt on stack then free up r0 & r1
1612 if they could have been assigned to some
1614 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1617 spillLRWithPtrReg (sym);
1620 if (sym->usl.spillLoc && !sym->remat)
1621 sym->usl.spillLoc->allocreq = 1;
1626 /*-----------------------------------------------------------------*/
1627 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1628 /*-----------------------------------------------------------------*/
1630 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1632 bitVect *lrcs = NULL;
1636 debugLog ("%s\n", __FUNCTION__);
1638 /* get the spillable live ranges */
1639 lrcs = computeSpillable (ic);
1642 /* get all live ranges that are rematerizable */
1643 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1645 /* return the least used of these */
1646 return leastUsedLR (selectS);
1649 /* get live ranges with spillLocations in direct space */
1650 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1652 sym = leastUsedLR (selectS);
1653 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1654 sym->usl.spillLoc->rname :
1655 sym->usl.spillLoc->name));
1657 /* mark it as allocation required */
1658 sym->usl.spillLoc->allocreq = 1;
1662 /* if the symbol is local to the block then */
1663 if (forSym->liveTo < ebp->lSeq)
1666 /* check if there are any live ranges allocated
1667 to registers that are not used in this block */
1668 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1670 sym = leastUsedLR (selectS);
1671 /* if this is not rematerializable */
1680 /* check if there are any live ranges that not
1681 used in the remainder of the block */
1682 if (!_G.blockSpil &&
1683 !isiCodeInFunctionCall (ic) &&
1684 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1686 sym = leastUsedLR (selectS);
1689 sym->remainSpil = 1;
1696 /* find live ranges with spillocation && not used as pointers */
1697 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1700 sym = leastUsedLR (selectS);
1701 /* mark this as allocation required */
1702 sym->usl.spillLoc->allocreq = 1;
1706 /* find live ranges with spillocation */
1707 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1710 sym = leastUsedLR (selectS);
1711 sym->usl.spillLoc->allocreq = 1;
1715 /* couldn't find then we need to create a spil
1716 location on the stack , for which one? the least
1718 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1721 /* return a created spil location */
1722 sym = createStackSpil (leastUsedLR (selectS));
1723 sym->usl.spillLoc->allocreq = 1;
1727 /* this is an extreme situation we will spill
1728 this one : happens very rarely but it does happen */
1734 /*-----------------------------------------------------------------*/
1735 /* spilSomething - spil some variable & mark registers as free */
1736 /*-----------------------------------------------------------------*/
1738 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1743 debugLog ("%s\n", __FUNCTION__);
1744 /* get something we can spil */
1745 ssym = selectSpil (ic, ebp, forSym);
1747 /* mark it as spilt */
1749 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1751 /* mark it as not register assigned &
1752 take it away from the set */
1753 bitVectUnSetBit (_G.regAssigned, ssym->key);
1755 /* mark the registers as free */
1756 for (i = 0; i < ssym->nRegs; i++)
1758 freeReg (ssym->regs[i]);
1760 /* if spilt on stack then free up r0 & r1
1761 if they could have been assigned to as gprs */
1762 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1765 spillLRWithPtrReg (ssym);
1768 /* if this was a block level spil then insert push & pop
1769 at the start & end of block respectively */
1770 if (ssym->blockSpil)
1772 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1773 /* add push to the start of the block */
1774 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1775 ebp->sch->next : ebp->sch));
1776 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1777 /* add pop to the end of the block */
1778 addiCodeToeBBlock (ebp, nic, NULL);
1781 /* if spilt because not used in the remainder of the
1782 block then add a push before this instruction and
1783 a pop at the end of the block */
1784 if (ssym->remainSpil)
1787 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1788 /* add push just before this instruction */
1789 addiCodeToeBBlock (ebp, nic, ic);
1791 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1792 /* add pop to the end of the block */
1793 addiCodeToeBBlock (ebp, nic, NULL);
1802 /*-----------------------------------------------------------------*/
1803 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1804 /*-----------------------------------------------------------------*/
1806 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1811 debugLog ("%s\n", __FUNCTION__);
1813 /* try for a ptr type */
1814 if ((reg = allocReg (REG_PTR)))
1817 /* try for gpr type */
1818 if ((reg = allocReg (REG_GPR)))
1821 /* we have to spil */
1822 if (!spilSomething (ic, ebp, sym))
1825 /* make sure partially assigned registers aren't reused */
1826 for (j=0; j<=sym->nRegs; j++)
1828 sym->regs[j]->isFree = 0;
1830 /* this looks like an infinite loop but
1831 in really selectSpil will abort */
1835 /*-----------------------------------------------------------------*/
1836 /* getRegGpr - will try for GPR if not spil */
1837 /*-----------------------------------------------------------------*/
1839 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1844 debugLog ("%s\n", __FUNCTION__);
1846 /* try for gpr type */
1847 if ((reg = allocReg (REG_GPR)))
1850 if (!pic14_ptrRegReq)
1851 if ((reg = allocReg (REG_PTR)))
1854 /* we have to spil */
1855 if (!spilSomething (ic, ebp, sym))
1858 /* make sure partially assigned registers aren't reused */
1859 for (j=0; j<=sym->nRegs; j++)
1861 sym->regs[j]->isFree = 0;
1863 /* this looks like an infinite loop but
1864 in really selectSpil will abort */
1868 /*-----------------------------------------------------------------*/
1869 /* symHasReg - symbol has a given register */
1870 /*-----------------------------------------------------------------*/
1872 symHasReg (symbol * sym, regs * reg)
1876 debugLog ("%s\n", __FUNCTION__);
1877 for (i = 0; i < sym->nRegs; i++)
1878 if (sym->regs[i] == reg)
1884 /*-----------------------------------------------------------------*/
1885 /* deassignLRs - check the live to and if they have registers & are */
1886 /* not spilt then free up the registers */
1887 /*-----------------------------------------------------------------*/
1889 deassignLRs (iCode * ic, eBBlock * ebp)
1895 debugLog ("%s\n", __FUNCTION__);
1896 for (sym = hTabFirstItem (liveRanges, &k); sym;
1897 sym = hTabNextItem (liveRanges, &k))
1900 symbol *psym = NULL;
1901 /* if it does not end here */
1902 if (sym->liveTo > ic->seq)
1905 /* Prevent the result from being assigned the same registers as (one)
1906 * operand as many genXXX-functions fail otherwise.
1907 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1908 * are known to fail. */
1909 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1913 case '=': /* assignment */
1914 case BITWISEAND: /* bitwise AND */
1915 case '|': /* bitwise OR */
1916 case '^': /* bitwise XOR */
1917 case '~': /* bitwise negate */
1918 case RLC: /* rotate through carry */
1921 case '+': /* addition */
1922 case '-': /* subtraction */
1923 /* go ahead, these are safe to use with
1924 * non-disjoint register sets */
1928 /* do not release operand registers */
1929 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1934 /* if it was spilt on stack then we can
1935 mark the stack spil location as free */
1940 sym->usl.spillLoc->isFree = 1;
1946 if (!bitVectBitValue (_G.regAssigned, sym->key))
1948 /* special case check if this is an IFX &
1949 the privious one was a pop and the
1950 previous one was not spilt then keep track
1952 if (ic->op == IFX && ic->prev &&
1953 ic->prev->op == IPOP &&
1954 !ic->prev->parmPush &&
1955 IS_SYMOP(IC_LEFT (ic->prev)) &&
1956 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1957 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1963 bitVectUnSetBit (_G.regAssigned, sym->key);
1965 /* if the result of this one needs registers
1966 and does not have it then assign it right
1968 if (IC_RESULT (ic) &&
1969 !(SKIP_IC2 (ic) || /* not a special icode */
1970 ic->op == JUMPTABLE ||
1975 POINTER_SET (ic)) &&
1976 IS_SYMOP (IC_RESULT (ic)) &&
1977 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1978 result->liveTo > ic->seq && /* and will live beyond this */
1979 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1980 result->liveFrom == ic->seq && /* does not start before here */
1981 result->regType == sym->regType && /* same register types */
1982 result->regType == sym->regType && /* same register types */
1983 result->nRegs && /* which needs registers */
1984 !result->isspilt && /* and does not already have them */
1986 !bitVectBitValue (_G.regAssigned, result->key) &&
1987 /* the number of free regs + number of regs in this LR
1988 can accomodate the what result Needs */
1989 ((nfreeRegsType (result->regType) +
1990 sym->nRegs) >= result->nRegs)
1994 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1996 result->regs[i] = sym->regs[i];
1998 result->regs[i] = getRegGpr (ic, ebp, result);
2000 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2004 /* free the remaining */
2005 for (; i < sym->nRegs; i++)
2009 if (!symHasReg (psym, sym->regs[i]))
2010 freeReg (sym->regs[i]);
2013 freeReg (sym->regs[i]);
2020 /*-----------------------------------------------------------------*/
2021 /* reassignLR - reassign this to registers */
2022 /*-----------------------------------------------------------------*/
2024 reassignLR (operand * op)
2026 symbol *sym = OP_SYMBOL (op);
2029 debugLog ("%s\n", __FUNCTION__);
2030 /* not spilt any more */
2031 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2032 bitVectUnSetBit (_G.spiltSet, sym->key);
2034 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2038 for (i = 0; i < sym->nRegs; i++)
2039 sym->regs[i]->isFree = 0;
2042 /*-----------------------------------------------------------------*/
2043 /* willCauseSpill - determines if allocating will cause a spill */
2044 /*-----------------------------------------------------------------*/
2046 willCauseSpill (int nr, int rt)
2048 debugLog ("%s\n", __FUNCTION__);
2049 /* first check if there are any avlb registers
2050 of te type required */
2053 /* special case for pointer type
2054 if pointer type not avlb then
2055 check for type gpr */
2056 if (nFreeRegs (rt) >= nr)
2058 if (nFreeRegs (REG_GPR) >= nr)
2063 if (pic14_ptrRegReq)
2065 if (nFreeRegs (rt) >= nr)
2070 if (nFreeRegs (REG_PTR) +
2071 nFreeRegs (REG_GPR) >= nr)
2076 debugLog (" ... yep it will (cause a spill)\n");
2077 /* it will cause a spil */
2081 /*-----------------------------------------------------------------*/
2082 /* positionRegs - the allocator can allocate same registers to res- */
2083 /* ult and operand, if this happens make sure they are in the same */
2084 /* position as the operand otherwise chaos results */
2085 /*-----------------------------------------------------------------*/
2087 positionRegs (symbol * result, symbol * opsym, int lineno)
2089 int count = min (result->nRegs, opsym->nRegs);
2090 int i, j = 0, shared = 0;
2092 debugLog ("%s\n", __FUNCTION__);
2093 /* if the result has been spilt then cannot share */
2098 /* first make sure that they actually share */
2099 for (i = 0; i < count; i++)
2101 for (j = 0; j < count; j++)
2103 if (result->regs[i] == opsym->regs[j] && i != j)
2113 regs *tmp = result->regs[i];
2114 result->regs[i] = result->regs[j];
2115 result->regs[j] = tmp;
2120 /*------------------------------------------------------------------*/
2121 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2122 /* it should either have registers or have beed spilled. Otherwise, */
2123 /* there was an uninitialized variable, so just spill this to get */
2124 /* the operand in a valid state. */
2125 /*------------------------------------------------------------------*/
2127 verifyRegsAssigned (operand *op, iCode * ic)
2132 if (!IS_ITEMP (op)) return;
2134 sym = OP_SYMBOL (op);
2135 if (sym->isspilt) return;
2136 if (!sym->nRegs) return;
2137 if (sym->regs[0]) return;
2139 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2140 sym->prereqv ? sym->prereqv->name : sym->name);
2145 /*-----------------------------------------------------------------*/
2146 /* serialRegAssign - serially allocate registers to the variables */
2147 /*-----------------------------------------------------------------*/
2149 serialRegAssign (eBBlock ** ebbs, int count)
2153 debugLog ("%s\n", __FUNCTION__);
2154 /* for all blocks */
2155 for (i = 0; i < count; i++)
2160 if (ebbs[i]->noPath &&
2161 (ebbs[i]->entryLabel != entryLabel &&
2162 ebbs[i]->entryLabel != returnLabel))
2165 /* of all instructions do */
2166 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2168 debugLog (" op: %s\n", decodeOp (ic->op));
2170 /* if this is an ipop that means some live
2171 range will have to be assigned again */
2173 reassignLR (IC_LEFT (ic));
2175 /* if result is present && is a true symbol */
2176 if (IC_RESULT (ic) && ic->op != IFX &&
2177 IS_TRUE_SYMOP (IC_RESULT (ic)))
2178 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2180 /* take away registers from live
2181 ranges that end at this instruction */
2182 deassignLRs (ic, ebbs[i]);
2184 /* some don't need registers */
2185 if (SKIP_IC2 (ic) ||
2186 ic->op == JUMPTABLE ||
2190 (IC_RESULT (ic) && POINTER_SET (ic)))
2193 /* now we need to allocate registers
2194 only for the result */
2195 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2197 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2203 /* Make sure any spill location is definately allocated */
2204 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2205 !sym->usl.spillLoc->allocreq)
2207 sym->usl.spillLoc->allocreq++;
2210 /* if it does not need or is spilt
2211 or is already assigned to registers
2212 or will not live beyond this instructions */
2215 bitVectBitValue (_G.regAssigned, sym->key) ||
2216 sym->liveTo <= ic->seq)
2219 /* if some liverange has been spilt at the block level
2220 and this one live beyond this block then spil this
2222 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2227 /* if trying to allocate this will cause
2228 a spill and there is nothing to spill
2229 or this one is rematerializable then
2231 willCS = willCauseSpill (sym->nRegs, sym->regType);
2232 spillable = computeSpillable (ic);
2234 (willCS && bitVectIsZero (spillable)))
2242 /* If the live range preceeds the point of definition
2243 then ideally we must take into account registers that
2244 have been allocated after sym->liveFrom but freed
2245 before ic->seq. This is complicated, so spill this
2246 symbol instead and let fillGaps handle the allocation. */
2247 if (sym->liveFrom < ic->seq)
2253 /* if it has a spillocation & is used less than
2254 all other live ranges then spill this */
2256 if (sym->usl.spillLoc) {
2257 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2258 allLRs, ebbs[i], ic));
2259 if (leastUsed && leastUsed->used > sym->used) {
2264 /* if none of the liveRanges have a spillLocation then better
2265 to spill this one than anything else already assigned to registers */
2266 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2267 /* if this is local to this block then we might find a block spil */
2268 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2276 if (ic->op == RECEIVE)
2277 debugLog ("When I get clever, I'll optimize the receive logic\n");
2279 /* if we need ptr regs for the right side
2281 if (POINTER_GET (ic)
2282 && IS_SYMOP(IC_LEFT(ic))
2283 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2284 <= (unsigned) PTRSIZE)
2289 /* else we assign registers to it */
2290 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2292 debugLog (" %d - \n", __LINE__);
2294 bitVectDebugOn(_G.regAssigned, debugF);
2295 for (j = 0; j < sym->nRegs; j++)
2297 if (sym->regType == REG_PTR)
2298 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2300 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2302 /* if the allocation failed which means
2303 this was spilt then break */
2307 debugLog (" %d - \n", __LINE__);
2309 /* if it shares registers with operands make sure
2310 that they are in the same position */
2311 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2312 IS_SYMOP(IC_RESULT(ic)) &&
2313 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2314 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2315 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2316 /* do the same for the right operand */
2317 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2318 IS_SYMOP(IC_RESULT(ic)) &&
2319 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2320 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2321 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2323 debugLog (" %d - \n", __LINE__);
2326 debugLog (" %d - \n", __LINE__);
2335 /* Check for and fix any problems with uninitialized operands */
2336 for (i = 0; i < count; i++)
2340 if (ebbs[i]->noPath &&
2341 (ebbs[i]->entryLabel != entryLabel &&
2342 ebbs[i]->entryLabel != returnLabel))
2345 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2352 verifyRegsAssigned (IC_COND (ic), ic);
2356 if (ic->op == JUMPTABLE)
2358 verifyRegsAssigned (IC_JTCOND (ic), ic);
2362 verifyRegsAssigned (IC_RESULT (ic), ic);
2363 verifyRegsAssigned (IC_LEFT (ic), ic);
2364 verifyRegsAssigned (IC_RIGHT (ic), ic);
2370 /*-----------------------------------------------------------------*/
2371 /* rUmaskForOp :- returns register mask for an operand */
2372 /*-----------------------------------------------------------------*/
2374 rUmaskForOp (operand * op)
2380 debugLog ("%s\n", __FUNCTION__);
2381 /* only temporaries are assigned registers */
2385 sym = OP_SYMBOL (op);
2387 /* if spilt or no registers assigned to it
2389 if (sym->isspilt || !sym->nRegs)
2392 rumask = newBitVect (pic14_nRegs);
2394 for (j = 0; j < sym->nRegs; j++)
2396 rumask = bitVectSetBit (rumask,
2397 sym->regs[j]->rIdx);
2403 /*-----------------------------------------------------------------*/
2404 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2405 /*-----------------------------------------------------------------*/
2407 regsUsedIniCode (iCode * ic)
2409 bitVect *rmask = newBitVect (pic14_nRegs);
2411 debugLog ("%s\n", __FUNCTION__);
2412 /* do the special cases first */
2415 rmask = bitVectUnion (rmask,
2416 rUmaskForOp (IC_COND (ic)));
2420 /* for the jumptable */
2421 if (ic->op == JUMPTABLE)
2423 rmask = bitVectUnion (rmask,
2424 rUmaskForOp (IC_JTCOND (ic)));
2429 /* of all other cases */
2431 rmask = bitVectUnion (rmask,
2432 rUmaskForOp (IC_LEFT (ic)));
2436 rmask = bitVectUnion (rmask,
2437 rUmaskForOp (IC_RIGHT (ic)));
2440 rmask = bitVectUnion (rmask,
2441 rUmaskForOp (IC_RESULT (ic)));
2447 /*-----------------------------------------------------------------*/
2448 /* createRegMask - for each instruction will determine the regsUsed */
2449 /*-----------------------------------------------------------------*/
2451 createRegMask (eBBlock ** ebbs, int count)
2455 debugLog ("%s\n", __FUNCTION__);
2456 /* for all blocks */
2457 for (i = 0; i < count; i++)
2461 if (ebbs[i]->noPath &&
2462 (ebbs[i]->entryLabel != entryLabel &&
2463 ebbs[i]->entryLabel != returnLabel))
2466 /* for all instructions */
2467 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2472 if (SKIP_IC2 (ic) || !ic->rlive)
2475 /* first mark the registers used in this
2477 ic->rUsed = regsUsedIniCode (ic);
2478 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2480 /* now create the register mask for those
2481 registers that are in use : this is a
2482 super set of ic->rUsed */
2483 ic->rMask = newBitVect (pic14_nRegs + 1);
2485 /* for all live Ranges alive at this point */
2486 for (j = 1; j < ic->rlive->size; j++)
2491 /* if not alive then continue */
2492 if (!bitVectBitValue (ic->rlive, j))
2495 /* find the live range we are interested in */
2496 if (!(sym = hTabItemWithKey (liveRanges, j)))
2498 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2499 "createRegMask cannot find live range");
2503 /* if no register assigned to it */
2504 if (!sym->nRegs || sym->isspilt)
2507 /* for all the registers allocated to it */
2508 for (k = 0; k < sym->nRegs; k++)
2511 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2517 /* This was the active version */
2518 /*-----------------------------------------------------------------*/
2519 /* rematStr - returns the rematerialized string for a remat var */
2520 /*-----------------------------------------------------------------*/
2522 rematStr (symbol * sym)
2525 iCode *ic = sym->rematiCode;
2526 symbol *psym = NULL;
2528 debugLog ("%s\n", __FUNCTION__);
2530 //printf ("%s\n", s);
2532 /* if plus or minus print the right hand side */
2534 if (ic->op == '+' || ic->op == '-') {
2536 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2538 sprintf (s, "(%s %c 0x%04x)",
2539 OP_SYMBOL (IC_LEFT (ric))->rname,
2541 (int) operandLitValue (IC_RIGHT (ic)));
2544 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2546 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2547 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2552 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2553 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2555 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2561 /* deprecated version */
2562 /*-----------------------------------------------------------------*/
2563 /* rematStr - returns the rematerialized string for a remat var */
2564 /*-----------------------------------------------------------------*/
2566 rematStr (symbol * sym)
2569 iCode *ic = sym->rematiCode;
2571 debugLog ("%s\n", __FUNCTION__);
2576 /* if plus or minus print the right hand side */
2578 if (ic->op == '+' || ic->op == '-') {
2579 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2582 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2586 if (ic->op == '+' || ic->op == '-')
2588 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2589 sprintf (s, "(%s %c 0x%04x)",
2590 OP_SYMBOL (IC_LEFT (ric))->rname,
2592 (int) operandLitValue (IC_RIGHT (ic)));
2595 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2597 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2601 /* we reached the end */
2602 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2606 printf ("%s\n", buffer);
2611 /*-----------------------------------------------------------------*/
2612 /* regTypeNum - computes the type & number of registers required */
2613 /*-----------------------------------------------------------------*/
2621 debugLog ("%s\n", __FUNCTION__);
2622 /* for each live range do */
2623 for (sym = hTabFirstItem (liveRanges, &k); sym;
2624 sym = hTabNextItem (liveRanges, &k)) {
2626 debugLog (" %d - %s\n", __LINE__, sym->rname);
2628 /* if used zero times then no registers needed */
2629 if ((sym->liveTo - sym->liveFrom) == 0)
2633 /* if the live range is a temporary */
2636 debugLog (" %d - itemp register\n", __LINE__);
2638 /* if the type is marked as a conditional */
2639 if (sym->regType == REG_CND)
2642 /* if used in return only then we don't
2645 if (IS_AGGREGATE (sym->type) || sym->isptr)
2646 sym->type = aggrToPtr (sym->type, FALSE);
2647 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2653 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2654 // sym->type = aggrToPtr (sym->type, FALSE);
2655 debugLog (" %d - used as a return\n", __LINE__);
2660 /* if the symbol has only one definition &
2661 that definition is a get_pointer and the
2662 pointer we are getting is rematerializable and
2666 if (bitVectnBitsOn (sym->defs) == 1 &&
2667 (ic = hTabItemWithKey (iCodehTab,
2668 bitVectFirstBit (sym->defs))) &&
2670 !IS_BITVAR (sym->etype) &&
2671 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2673 if (ptrPseudoSymSafe (sym, ic)) {
2677 debugLog (" %d - \n", __LINE__);
2679 /* create a pseudo symbol & force a spil */
2680 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2681 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2682 psym->type = sym->type;
2683 psym->etype = sym->etype;
2684 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2685 strcpy (psym->rname, psym->name);
2687 sym->usl.spillLoc = psym;
2691 /* if in data space or idata space then try to
2692 allocate pointer register */
2697 /* if not then we require registers */
2698 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2699 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2700 getSize (sym->type));
2703 if(IS_PTR_CONST (sym->type)) {
2704 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2708 if (sym->nRegs > 4) {
2709 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2710 printTypeChain (sym->type, stderr);
2711 fprintf (stderr, "\n");
2714 /* determine the type of register required */
2715 if (sym->nRegs == 1 &&
2716 IS_PTR (sym->type) &&
2718 sym->regType = REG_PTR;
2720 sym->regType = REG_GPR;
2723 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2727 /* for the first run we don't provide */
2728 /* registers for true symbols we will */
2729 /* see how things go */
2734 DEFSETFUNC (markRegFree)
2736 ((regs *)item)->isFree = 1;
2741 DEFSETFUNC (deallocReg)
2743 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2744 ((regs *)item)->isFree = 1;
2745 ((regs *)item)->wasUsed = 0;
2749 /*-----------------------------------------------------------------*/
2750 /* freeAllRegs - mark all registers as free */
2751 /*-----------------------------------------------------------------*/
2753 pic14_freeAllRegs ()
2757 debugLog ("%s\n", __FUNCTION__);
2759 applyToSet(dynAllocRegs,markRegFree);
2760 applyToSet(dynStackRegs,markRegFree);
2763 for (i = 0; i < pic14_nRegs; i++)
2764 regspic14[i].isFree = 1;
2768 /*-----------------------------------------------------------------*/
2769 /*-----------------------------------------------------------------*/
2771 pic14_deallocateAllRegs ()
2775 debugLog ("%s\n", __FUNCTION__);
2777 applyToSet(dynAllocRegs,deallocReg);
2780 for (i = 0; i < pic14_nRegs; i++) {
2781 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2782 regspic14[i].isFree = 1;
2783 regspic14[i].wasUsed = 0;
2790 /*-----------------------------------------------------------------*/
2791 /* deallocStackSpil - this will set the stack pointer back */
2792 /*-----------------------------------------------------------------*/
2794 DEFSETFUNC (deallocStackSpil)
2798 debugLog ("%s\n", __FUNCTION__);
2803 /*-----------------------------------------------------------------*/
2804 /* farSpacePackable - returns the packable icode for far variables */
2805 /*-----------------------------------------------------------------*/
2807 farSpacePackable (iCode * ic)
2811 debugLog ("%s\n", __FUNCTION__);
2812 /* go thru till we find a definition for the
2813 symbol on the right */
2814 for (dic = ic->prev; dic; dic = dic->prev)
2817 /* if the definition is a call then no */
2818 if ((dic->op == CALL || dic->op == PCALL) &&
2819 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2824 /* if shift by unknown amount then not */
2825 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2826 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2829 /* if pointer get and size > 1 */
2830 if (POINTER_GET (dic) &&
2831 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2834 if (POINTER_SET (dic) &&
2835 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2838 /* if any three is a true symbol in far space */
2839 if (IC_RESULT (dic) &&
2840 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2841 isOperandInFarSpace (IC_RESULT (dic)))
2844 if (IC_RIGHT (dic) &&
2845 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2846 isOperandInFarSpace (IC_RIGHT (dic)) &&
2847 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2850 if (IC_LEFT (dic) &&
2851 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2852 isOperandInFarSpace (IC_LEFT (dic)) &&
2853 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2856 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2858 if ((dic->op == LEFT_OP ||
2859 dic->op == RIGHT_OP ||
2861 IS_OP_LITERAL (IC_RIGHT (dic)))
2871 /*-----------------------------------------------------------------*/
2872 /* packRegsForAssign - register reduction for assignment */
2873 /*-----------------------------------------------------------------*/
2875 packRegsForAssign (iCode * ic, eBBlock * ebp)
2880 debugLog ("%s\n", __FUNCTION__);
2882 debugAopGet (" result:", IC_RESULT (ic));
2883 debugAopGet (" left:", IC_LEFT (ic));
2884 debugAopGet (" right:", IC_RIGHT (ic));
2886 /* if this is at an absolute address, then get the address. */
2887 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2888 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2889 debugLog (" %d - found config word declaration\n", __LINE__);
2890 if(IS_VALOP(IC_RIGHT(ic))) {
2891 debugLog (" setting config word to %x\n",
2892 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2893 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2894 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2897 /* remove the assignment from the iCode chain. */
2899 remiCodeFromeBBlock (ebp, ic);
2900 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2901 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2908 if (!IS_ITEMP (IC_RESULT (ic))) {
2909 allocDirReg(IC_RESULT (ic));
2910 debugLog (" %d - result is not temp\n", __LINE__);
2913 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2914 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2915 allocDirReg(IC_LEFT (ic));
2919 if (!IS_ITEMP (IC_RIGHT (ic))) {
2920 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2922 /* only pack if this is not a function pointer */
2923 if (!IS_REF (IC_RIGHT (ic)))
2924 allocDirReg(IC_RIGHT (ic));
2928 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2929 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2931 debugLog (" %d - not packing - right side fails \n", __LINE__);
2935 /* if the true symbol is defined in far space or on stack
2936 then we should not since this will increase register pressure */
2937 if (isOperandInFarSpace (IC_RESULT (ic)))
2939 if ((dic = farSpacePackable (ic)))
2945 /* find the definition of iTempNN scanning backwards if we find a
2946 a use of the true symbol before we find the definition then
2948 for (dic = ic->prev; dic; dic = dic->prev)
2951 /* if there is a function call and this is
2952 a parameter & not my parameter then don't pack it */
2953 if ((dic->op == CALL || dic->op == PCALL) &&
2954 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2955 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2957 debugLog (" %d - \n", __LINE__);
2965 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2966 IS_OP_VOLATILE (IC_RESULT (dic)))
2968 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2973 if (IS_SYMOP (IC_RESULT (dic)) &&
2974 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2976 /* A previous result was assigned to the same register - we'll our definition */
2977 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2978 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2979 if (POINTER_SET (dic))
2985 if (IS_SYMOP (IC_RIGHT (dic)) &&
2986 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2987 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2989 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2994 if (IS_SYMOP (IC_LEFT (dic)) &&
2995 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2996 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2998 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3003 if (POINTER_SET (dic) &&
3004 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3006 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3014 return 0; /* did not find */
3016 /* if assignment then check that right is not a bit */
3017 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
3019 sym_link *etype = operandType (IC_RESULT (dic));
3020 if (IS_BITFIELD (etype))
3022 /* if result is a bit too then it's ok */
3023 etype = operandType (IC_RESULT (ic));
3024 if (!IS_BITFIELD (etype))
3029 /* if the result is on stack or iaccess then it must be
3030 the same at least one of the operands */
3031 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3032 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3035 /* the operation has only one symbol
3036 operator then we can pack */
3037 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3038 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3041 if (!((IC_LEFT (dic) &&
3042 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3044 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3048 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3049 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3050 /* found the definition */
3051 /* replace the result with the result of */
3052 /* this assignment and remove this assignment */
3053 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3054 IC_RESULT (dic) = IC_RESULT (ic);
3056 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3058 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3060 /* delete from liverange table also
3061 delete from all the points inbetween and the new
3063 for (sic = dic; sic != ic; sic = sic->next)
3065 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3066 if (IS_ITEMP (IC_RESULT (dic)))
3067 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3070 remiCodeFromeBBlock (ebp, ic);
3071 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3072 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3073 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3079 /*-----------------------------------------------------------------*/
3080 /* findAssignToSym : scanning backwards looks for first assig found */
3081 /*-----------------------------------------------------------------*/
3083 findAssignToSym (operand * op, iCode * ic)
3087 debugLog ("%s\n", __FUNCTION__);
3088 for (dic = ic->prev; dic; dic = dic->prev)
3091 /* if definition by assignment */
3092 if (dic->op == '=' &&
3093 !POINTER_SET (dic) &&
3094 IC_RESULT (dic)->key == op->key
3095 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3099 /* we are interested only if defined in far space */
3100 /* or in stack space in case of + & - */
3102 /* if assigned to a non-symbol then return
3104 if (!IS_SYMOP (IC_RIGHT (dic)))
3107 /* if the symbol is in far space then
3109 if (isOperandInFarSpace (IC_RIGHT (dic)))
3112 /* for + & - operations make sure that
3113 if it is on the stack it is the same
3114 as one of the three operands */
3115 if ((ic->op == '+' || ic->op == '-') &&
3116 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3119 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3120 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3121 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3129 /* if we find an usage then we cannot delete it */
3130 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3133 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3136 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3140 /* now make sure that the right side of dic
3141 is not defined between ic & dic */
3144 iCode *sic = dic->next;
3146 for (; sic != ic; sic = sic->next)
3147 if (IC_RESULT (sic) &&
3148 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3157 /*-----------------------------------------------------------------*/
3158 /* packRegsForSupport :- reduce some registers for support calls */
3159 /*-----------------------------------------------------------------*/
3161 packRegsForSupport (iCode * ic, eBBlock * ebp)
3165 debugLog ("%s\n", __FUNCTION__);
3166 /* for the left & right operand :- look to see if the
3167 left was assigned a true symbol in far space in that
3168 case replace them */
3169 if (IS_ITEMP (IC_LEFT (ic)) &&
3170 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3172 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3178 debugAopGet ("removing left:", IC_LEFT (ic));
3180 /* found it we need to remove it from the
3182 for (sic = dic; sic != ic; sic = sic->next)
3183 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3185 IC_LEFT (ic)->operand.symOperand =
3186 IC_RIGHT (dic)->operand.symOperand;
3187 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3188 remiCodeFromeBBlock (ebp, dic);
3189 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3190 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3194 /* do the same for the right operand */
3197 IS_ITEMP (IC_RIGHT (ic)) &&
3198 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3200 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3206 /* if this is a subtraction & the result
3207 is a true symbol in far space then don't pack */
3208 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3210 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3211 if (IN_FARSPACE (SPEC_OCLS (etype)))
3215 debugAopGet ("removing right:", IC_RIGHT (ic));
3217 /* found it we need to remove it from the
3219 for (sic = dic; sic != ic; sic = sic->next)
3220 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3222 IC_RIGHT (ic)->operand.symOperand =
3223 IC_RIGHT (dic)->operand.symOperand;
3224 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3226 remiCodeFromeBBlock (ebp, dic);
3227 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3228 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3235 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3238 /*-----------------------------------------------------------------*/
3239 /* packRegsForOneuse : - will reduce some registers for single Use */
3240 /*-----------------------------------------------------------------*/
3242 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3247 debugLog ("%s\n", __FUNCTION__);
3248 /* if returning a literal then do nothing */
3252 /* only upto 2 bytes since we cannot predict
3253 the usage of b, & acc */
3254 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3259 /* this routine will mark the a symbol as used in one
3260 instruction use only && if the definition is local
3261 (ie. within the basic block) && has only one definition &&
3262 that definition is either a return value from a
3263 function or does not contain any variables in
3265 uses = bitVectCopy (OP_USES (op));
3266 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3267 if (!bitVectIsZero (uses)) /* has other uses */
3270 /* if it has only one defintion */
3271 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3272 return NULL; /* has more than one definition */
3274 /* get that definition */
3276 hTabItemWithKey (iCodehTab,
3277 bitVectFirstBit (OP_DEFS (op)))))
3280 /* found the definition now check if it is local */
3281 if (dic->seq < ebp->fSeq ||
3282 dic->seq > ebp->lSeq)
3283 return NULL; /* non-local */
3285 /* now check if it is the return from
3287 if (dic->op == CALL || dic->op == PCALL)
3289 if (ic->op != SEND && ic->op != RETURN &&
3290 !POINTER_SET(ic) && !POINTER_GET(ic))
3292 OP_SYMBOL (op)->ruonly = 1;
3299 /* otherwise check that the definition does
3300 not contain any symbols in far space */
3301 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3302 isOperandInFarSpace (IC_RIGHT (dic)) ||
3303 IS_OP_RUONLY (IC_LEFT (ic)) ||
3304 IS_OP_RUONLY (IC_RIGHT (ic)))
3309 /* if pointer set then make sure the pointer
3311 if (POINTER_SET (dic) &&
3312 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3315 if (POINTER_GET (dic) &&
3316 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3321 /* also make sure the intervenening instructions
3322 don't have any thing in far space */
3323 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3326 /* if there is an intervening function call then no */
3327 if (dic->op == CALL || dic->op == PCALL)
3329 /* if pointer set then make sure the pointer
3331 if (POINTER_SET (dic) &&
3332 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3335 if (POINTER_GET (dic) &&
3336 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3339 /* if address of & the result is remat then okay */
3340 if (dic->op == ADDRESS_OF &&
3341 OP_SYMBOL (IC_RESULT (dic))->remat)
3344 /* if operand has size of three or more & this
3345 operation is a '*','/' or '%' then 'b' may
3347 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3348 getSize (operandType (op)) >= 3)
3351 /* if left or right or result is in far space */
3352 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3353 isOperandInFarSpace (IC_RIGHT (dic)) ||
3354 isOperandInFarSpace (IC_RESULT (dic)) ||
3355 IS_OP_RUONLY (IC_LEFT (dic)) ||
3356 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3357 IS_OP_RUONLY (IC_RESULT (dic)))
3363 OP_SYMBOL (op)->ruonly = 1;
3368 /*-----------------------------------------------------------------*/
3369 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3370 /*-----------------------------------------------------------------*/
3372 isBitwiseOptimizable (iCode * ic)
3374 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3375 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3377 debugLog ("%s\n", __FUNCTION__);
3378 /* bitwise operations are considered optimizable
3379 under the following conditions (Jean-Louis VERN)
3391 if (IS_LITERAL (rtype) ||
3392 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3398 /*-----------------------------------------------------------------*/
3399 /* packRegsForAccUse - pack registers for acc use */
3400 /*-----------------------------------------------------------------*/
3402 packRegsForAccUse (iCode * ic)
3406 debugLog ("%s\n", __FUNCTION__);
3408 /* result too large for WREG? */
3409 if (getSize (operandType (IC_RESULT (ic))) > 1)
3412 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3413 * is never used as an operand to an instruction that
3414 * cannot have WREG as an operand (e.g. BTFSx cannot
3415 * operate on WREG...
3416 * For now, store all results into proper registers. */
3420 /* if this is an aggregate, e.g. a one byte char array */
3421 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3424 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3426 /* if + or - then it has to be one byte result */
3427 if ((ic->op == '+' || ic->op == '-')
3428 && getSize (operandType (IC_RESULT (ic))) > 1)
3431 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3432 /* if shift operation make sure right side is not a literal */
3433 if (ic->op == RIGHT_OP &&
3434 (isOperandLiteral (IC_RIGHT (ic)) ||
3435 getSize (operandType (IC_RESULT (ic))) > 1))
3438 if (ic->op == LEFT_OP &&
3439 (isOperandLiteral (IC_RIGHT (ic)) ||
3440 getSize (operandType (IC_RESULT (ic))) > 1))
3443 if (IS_BITWISE_OP (ic) &&
3444 getSize (operandType (IC_RESULT (ic))) > 1)
3448 /* has only one definition */
3449 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3452 /* has only one use */
3453 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3456 /* and the usage immediately follows this iCode */
3457 if (!(uic = hTabItemWithKey (iCodehTab,
3458 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3461 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3462 if (ic->next != uic)
3465 /* if it is a conditional branch then we definitely can */
3469 if (uic->op == JUMPTABLE)
3472 /* if the usage is not is an assignment
3473 or an arithmetic / bitwise / shift operation then not */
3474 if (POINTER_SET (uic) &&
3475 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3478 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3479 if (uic->op != '=' &&
3480 !IS_ARITHMETIC_OP (uic) &&
3481 !IS_BITWISE_OP (uic) &&
3482 uic->op != LEFT_OP &&
3483 uic->op != RIGHT_OP)
3486 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3487 /* if used in ^ operation then make sure right is not a
3489 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3492 /* if shift operation make sure right side is not a literal */
3493 if (uic->op == RIGHT_OP &&
3494 (isOperandLiteral (IC_RIGHT (uic)) ||
3495 getSize (operandType (IC_RESULT (uic))) > 1))
3498 if (uic->op == LEFT_OP &&
3499 (isOperandLiteral (IC_RIGHT (uic)) ||
3500 getSize (operandType (IC_RESULT (uic))) > 1))
3503 /* make sure that the result of this icode is not on the
3504 stack, since acc is used to compute stack offset */
3505 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3506 OP_SYMBOL (IC_RESULT (uic))->onStack)
3509 /* if either one of them in far space then we cannot */
3510 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3511 isOperandInFarSpace (IC_LEFT (uic))) ||
3512 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3513 isOperandInFarSpace (IC_RIGHT (uic))))
3516 /* if the usage has only one operand then we can */
3517 if (IC_LEFT (uic) == NULL ||
3518 IC_RIGHT (uic) == NULL)
3521 /* make sure this is on the left side if not
3522 a '+' since '+' is commutative */
3523 if (ic->op != '+' &&
3524 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3527 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3528 /* if one of them is a literal then we can */
3529 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3530 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3531 (getSize (operandType (IC_RESULT (uic))) <= 1))
3533 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3537 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3538 /* if the other one is not on stack then we can */
3539 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3540 (IS_ITEMP (IC_RIGHT (uic)) ||
3541 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3542 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3545 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3546 (IS_ITEMP (IC_LEFT (uic)) ||
3547 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3548 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3554 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3555 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3559 /*-----------------------------------------------------------------*/
3560 /* packForPush - hueristics to reduce iCode for pushing */
3561 /*-----------------------------------------------------------------*/
3563 packForReceive (iCode * ic, eBBlock * ebp)
3567 debugLog ("%s\n", __FUNCTION__);
3568 debugAopGet (" result:", IC_RESULT (ic));
3569 debugAopGet (" left:", IC_LEFT (ic));
3570 debugAopGet (" right:", IC_RIGHT (ic));
3575 for (dic = ic->next; dic; dic = dic->next)
3580 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3581 debugLog (" used on left\n");
3582 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3583 debugLog (" used on right\n");
3584 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3585 debugLog (" used on result\n");
3587 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3588 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3593 debugLog (" hey we can remove this unnecessary assign\n");
3595 /*-----------------------------------------------------------------*/
3596 /* packForPush - hueristics to reduce iCode for pushing */
3597 /*-----------------------------------------------------------------*/
3599 packForPush (iCode * ic, eBBlock * ebp)
3603 debugLog ("%s\n", __FUNCTION__);
3604 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3607 /* must have only definition & one usage */
3608 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3609 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3612 /* find the definition */
3613 if (!(dic = hTabItemWithKey (iCodehTab,
3614 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3617 if (dic->op != '=' || POINTER_SET (dic))
3620 /* we now we know that it has one & only one def & use
3621 and the that the definition is an assignment */
3622 IC_LEFT (ic) = IC_RIGHT (dic);
3624 remiCodeFromeBBlock (ebp, dic);
3625 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3626 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3629 void printSymType(char * str, sym_link *sl)
3632 debugLog (" %s Symbol type: ",str);
3633 printTypeChain( sl, debugF);
3638 /*-----------------------------------------------------------------*/
3639 /* some debug code to print the symbol S_TYPE. Note that
3640 * the function checkSClass in src/SDCCsymt.c dinks with
3641 * the S_TYPE in ways the PIC port doesn't fully like...*/
3642 /*-----------------------------------------------------------------*/
3643 void isData(sym_link *sl)
3653 for ( ; sl; sl=sl->next) {
3655 switch (SPEC_SCLS(sl)) {
3657 case S_DATA: fprintf (of, "data "); break;
3658 case S_XDATA: fprintf (of, "xdata "); break;
3659 case S_SFR: fprintf (of, "sfr "); break;
3660 case S_SBIT: fprintf (of, "sbit "); break;
3661 case S_CODE: fprintf (of, "code "); break;
3662 case S_IDATA: fprintf (of, "idata "); break;
3663 case S_PDATA: fprintf (of, "pdata "); break;
3664 case S_LITERAL: fprintf (of, "literal "); break;
3665 case S_STACK: fprintf (of, "stack "); break;
3666 case S_XSTACK: fprintf (of, "xstack "); break;
3667 case S_BIT: fprintf (of, "bit "); break;
3668 case S_EEPROM: fprintf (of, "eeprom "); break;
3678 /*-----------------------------------------------------------------*/
3679 /* packRegisters - does some transformations to reduce register */
3681 /*-----------------------------------------------------------------*/
3683 packRegisters (eBBlock * ebp)
3688 debugLog ("%s\n", __FUNCTION__);
3694 /* look for assignments of the form */
3695 /* iTempNN = TRueSym (someoperation) SomeOperand */
3697 /* TrueSym := iTempNN:1 */
3698 for (ic = ebp->sch; ic; ic = ic->next)
3701 /* find assignment of the form TrueSym := iTempNN:1 */
3702 if (ic->op == '=' && !POINTER_SET (ic))
3703 change += packRegsForAssign (ic, ebp);
3707 if (POINTER_SET (ic))
3708 debugLog ("pointer is set\n");
3709 debugAopGet (" result:", IC_RESULT (ic));
3710 debugAopGet (" left:", IC_LEFT (ic));
3711 debugAopGet (" right:", IC_RIGHT (ic));
3720 for (ic = ebp->sch; ic; ic = ic->next) {
3722 if(IS_SYMOP ( IC_LEFT(ic))) {
3723 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3725 debugAopGet (" left:", IC_LEFT (ic));
3726 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3727 debugLog (" is a pointer\n");
3729 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3730 debugLog (" is volatile\n");
3734 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3737 if(IS_SYMOP ( IC_RIGHT(ic))) {
3738 debugAopGet (" right:", IC_RIGHT (ic));
3739 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3742 if(IS_SYMOP ( IC_RESULT(ic))) {
3743 debugAopGet (" result:", IC_RESULT (ic));
3744 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3747 if (POINTER_SET (ic))
3748 debugLog (" %d - Pointer set\n", __LINE__);
3751 /* Look for two subsequent iCodes with */
3753 /* _c = iTemp & op; */
3754 /* and replace them by */
3757 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3759 ic->prev->op == '=' &&
3760 IS_ITEMP (IC_LEFT (ic)) &&
3761 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3762 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3764 iCode* ic_prev = ic->prev;
3765 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3767 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3768 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3770 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3771 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3772 prev_result_sym->liveTo == ic->seq)
3774 prev_result_sym->liveTo = ic_prev->seq;
3777 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3779 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3781 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3783 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3784 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3785 remiCodeFromeBBlock (ebp, ic_prev);
3786 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3790 /* if this is an itemp & result of a address of a true sym
3791 then mark this as rematerialisable */
3792 if (ic->op == ADDRESS_OF &&
3793 IS_ITEMP (IC_RESULT (ic)) &&
3794 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3795 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3796 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3799 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3801 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3802 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3803 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3807 /* if straight assignment then carry remat flag if
3808 this is the only definition */
3809 if (ic->op == '=' &&
3810 !POINTER_SET (ic) &&
3811 IS_SYMOP (IC_RIGHT (ic)) &&
3812 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3813 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3815 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3817 OP_SYMBOL (IC_RESULT (ic))->remat =
3818 OP_SYMBOL (IC_RIGHT (ic))->remat;
3819 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3820 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3823 /* if this is a +/- operation with a rematerizable
3824 then mark this as rematerializable as well */
3825 if ((ic->op == '+' || ic->op == '-') &&
3826 (IS_SYMOP (IC_LEFT (ic)) &&
3827 IS_ITEMP (IC_RESULT (ic)) &&
3828 OP_SYMBOL (IC_LEFT (ic))->remat &&
3829 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3830 IS_OP_LITERAL (IC_RIGHT (ic))))
3832 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3834 operandLitValue (IC_RIGHT (ic));
3835 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3836 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3837 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3840 /* mark the pointer usages */
3841 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3843 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3844 debugLog (" marking as a pointer (set) =>");
3845 debugAopGet (" result:", IC_RESULT (ic));
3847 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3849 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3850 debugLog (" marking as a pointer (get) =>");
3851 debugAopGet (" left:", IC_LEFT (ic));
3856 /* if we are using a symbol on the stack
3857 then we should say pic14_ptrRegReq */
3858 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3859 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3860 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3861 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3862 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3863 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3866 if (IS_SYMOP (IC_LEFT (ic)))
3867 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3868 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3869 if (IS_SYMOP (IC_RIGHT (ic)))
3870 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3871 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3872 if (IS_SYMOP (IC_RESULT (ic)))
3873 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3874 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3877 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3881 /* if the condition of an if instruction
3882 is defined in the previous instruction then
3883 mark the itemp as a conditional */
3884 if ((IS_CONDITIONAL (ic) ||
3885 ((ic->op == BITWISEAND ||
3888 isBitwiseOptimizable (ic))) &&
3889 ic->next && ic->next->op == IFX &&
3890 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3891 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3894 debugLog (" %d\n", __LINE__);
3895 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3899 /* reduce for support function calls */
3900 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3901 packRegsForSupport (ic, ebp);
3903 /* if a parameter is passed, it's in W, so we may not
3904 need to place a copy in a register */
3905 if (ic->op == RECEIVE)
3906 packForReceive (ic, ebp);
3908 /* some cases the redundant moves can
3909 can be eliminated for return statements */
3910 if ((ic->op == RETURN || ic->op == SEND) &&
3911 !isOperandInFarSpace (IC_LEFT (ic)) &&
3913 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3915 /* if pointer set & left has a size more than
3916 one and right is not in far space */
3917 if (POINTER_SET (ic) &&
3918 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3919 IS_SYMOP(IC_RESULT(ic)) &&
3920 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3921 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3922 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3924 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3926 /* if pointer get */
3927 if (POINTER_GET (ic) &&
3928 !isOperandInFarSpace (IC_RESULT (ic)) &&
3929 IS_SYMOP(IC_LEFT(ic)) &&
3930 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3931 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3932 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3934 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3937 /* if this is cast for intergral promotion then
3938 check if only use of the definition of the
3939 operand being casted/ if yes then replace
3940 the result of that arithmetic operation with
3941 this result and get rid of the cast */
3942 if (ic->op == CAST) {
3944 sym_link *fromType = operandType (IC_RIGHT (ic));
3945 sym_link *toType = operandType (IC_LEFT (ic));
3947 debugLog (" %d - casting\n", __LINE__);
3949 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3950 getSize (fromType) != getSize (toType)) {
3953 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3956 if (IS_ARITHMETIC_OP (dic)) {
3958 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3959 IC_RESULT (dic) = IC_RESULT (ic);
3960 remiCodeFromeBBlock (ebp, ic);
3961 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3962 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3963 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3967 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3971 /* if the type from and type to are the same
3972 then if this is the only use then packit */
3973 if (compareType (operandType (IC_RIGHT (ic)),
3974 operandType (IC_LEFT (ic))) == 1) {
3976 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3979 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3980 IC_RESULT (dic) = IC_RESULT (ic);
3981 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3982 remiCodeFromeBBlock (ebp, ic);
3983 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3984 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3992 iTempNN := (some variable in farspace) V1
3997 if (ic->op == IPUSH)
3999 packForPush (ic, ebp);
4003 /* pack registers for accumulator use, when the
4004 result of an arithmetic or bit wise operation
4005 has only one use, that use is immediately following
4006 the defintion and the using iCode has only one
4007 operand or has two operands but one is literal &
4008 the result of that operation is not on stack then
4009 we can leave the result of this operation in acc:b
4011 if ((IS_ARITHMETIC_OP (ic)
4013 || IS_BITWISE_OP (ic)
4015 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4018 IS_ITEMP (IC_RESULT (ic)) &&
4019 getSize (operandType (IC_RESULT (ic))) <= 2)
4021 packRegsForAccUse (ic);
4027 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4031 if (!debug || !debugF)
4034 for (i = 0; i < count; i++)
4036 fprintf (debugF, "\n----------------------------------------------------------------\n");
4037 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4038 ebbs[i]->entryLabel->name,
4041 ebbs[i]->isLastInLoop);
4042 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4047 fprintf (debugF, "visited %d : hasFcall = %d\n",
4051 fprintf (debugF, "\ndefines bitVector :");
4052 bitVectDebugOn (ebbs[i]->defSet, debugF);
4053 fprintf (debugF, "\nlocal defines bitVector :");
4054 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4055 fprintf (debugF, "\npointers Set bitvector :");
4056 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4057 fprintf (debugF, "\nin pointers Set bitvector :");
4058 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4059 fprintf (debugF, "\ninDefs Set bitvector :");
4060 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4061 fprintf (debugF, "\noutDefs Set bitvector :");
4062 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4063 fprintf (debugF, "\nusesDefs Set bitvector :");
4064 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4065 fprintf (debugF, "\n----------------------------------------------------------------\n");
4066 printiCChain (ebbs[i]->sch, debugF);
4069 /*-----------------------------------------------------------------*/
4070 /* assignRegisters - assigns registers to each live range as need */
4071 /*-----------------------------------------------------------------*/
4073 pic14_assignRegisters (ebbIndex * ebbi)
4075 eBBlock ** ebbs = ebbi->bbOrder;
4076 int count = ebbi->count;
4080 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4081 debugLog ("ebbs before optimizing:\n");
4082 dumpEbbsToDebug (ebbs, count);
4084 setToNull ((void *) &_G.funcrUsed);
4085 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4088 /* change assignments this will remove some
4089 live ranges reducing some register pressure */
4090 for (i = 0; i < count; i++)
4091 packRegisters (ebbs[i]);
4098 debugLog("dir registers allocated so far:\n");
4099 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4102 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4103 reg = hTabNextItem(dynDirectRegNames, &hkey);
4108 if (options.dump_pack)
4109 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4111 /* first determine for each live range the number of
4112 registers & the type of registers required for each */
4115 /* and serially allocate registers */
4116 serialRegAssign (ebbs, count);
4118 /* if stack was extended then tell the user */
4121 /* werror(W_TOOMANY_SPILS,"stack", */
4122 /* _G.stackExtend,currFunc->name,""); */
4128 /* werror(W_TOOMANY_SPILS,"data space", */
4129 /* _G.dataExtend,currFunc->name,""); */
4133 /* after that create the register mask
4134 for each of the instruction */
4135 createRegMask (ebbs, count);
4137 /* redo that offsets for stacked automatic variables */
4138 redoStackOffsets ();
4140 if (options.dump_rassgn)
4141 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4143 /* now get back the chain */
4144 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4146 debugLog ("ebbs after optimizing:\n");
4147 dumpEbbsToDebug (ebbs, count);
4152 /* free up any _G.stackSpil locations allocated */
4153 applyToSet (_G.stackSpil, deallocStackSpil);
4155 setToNull ((void *) &_G.stackSpil);
4156 setToNull ((void *) &_G.spiltSet);
4157 /* mark all registers as free */
4158 //pic14_freeAllRegs ();
4160 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4161 pic14_debugLogClose ();