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)
1425 debugLog ("%s\n", __FUNCTION__);
1426 if (!_G.regAssigned ||
1427 bitVectIsZero (_G.regAssigned))
1430 /* for all live ranges */
1431 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1432 lrsym = hTabNextItem (liveRanges, &k))
1434 /* if no registers assigned to it or
1436 /* if it does not overlap with this then
1437 not need to spill it */
1439 if (lrsym->isspilt || !lrsym->nRegs ||
1440 (lrsym->liveTo < forSym->liveFrom))
1447 /*-----------------------------------------------------------------*/
1448 /* createStackSpil - create a location on the stack to spil */
1449 /*-----------------------------------------------------------------*/
1451 createStackSpil (symbol * sym)
1453 symbol *sloc = NULL;
1454 int useXstack, model, noOverlay;
1456 char slocBuffer[30];
1457 debugLog ("%s\n", __FUNCTION__);
1461 /* first go try and find a free one that is already
1462 existing on the stack */
1463 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1465 /* found a free one : just update & return */
1466 sym->usl.spillLoc = sloc;
1469 addSetHead (&sloc->usl.itmpStack, sym);
1473 /* could not then have to create one , this is the hard part
1474 we need to allocate this on the stack : this is really a
1475 hack!! but cannot think of anything better at this time */
1477 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1479 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1480 __FILE__, __LINE__);
1484 sloc = newiTemp (slocBuffer);
1486 /* set the type to the spilling symbol */
1487 sloc->type = copyLinkChain (sym->type);
1488 sloc->etype = getSpec (sloc->type);
1489 SPEC_SCLS (sloc->etype) = S_DATA;
1490 SPEC_EXTR (sloc->etype) = 0;
1491 SPEC_STAT (sloc->etype) = 0;
1493 /* we don't allow it to be allocated`
1494 onto the external stack since : so we
1495 temporarily turn it off ; we also
1496 turn off memory model to prevent
1497 the spil from going to the external storage
1498 and turn off overlaying
1501 useXstack = options.useXstack;
1502 model = options.model;
1503 noOverlay = options.noOverlay;
1504 options.noOverlay = 1;
1505 options.model = options.useXstack = 0;
1509 options.useXstack = useXstack;
1510 options.model = model;
1511 options.noOverlay = noOverlay;
1512 sloc->isref = 1; /* to prevent compiler warning */
1514 /* if it is on the stack then update the stack */
1515 if (IN_STACK (sloc->etype))
1517 currFunc->stack += getSize (sloc->type);
1518 _G.stackExtend += getSize (sloc->type);
1521 _G.dataExtend += getSize (sloc->type);
1523 /* add it to the _G.stackSpil set */
1524 addSetHead (&_G.stackSpil, sloc);
1525 sym->usl.spillLoc = sloc;
1528 /* add it to the set of itempStack set
1529 of the spill location */
1530 addSetHead (&sloc->usl.itmpStack, sym);
1534 /*-----------------------------------------------------------------*/
1535 /* isSpiltOnStack - returns true if the spil location is on stack */
1536 /*-----------------------------------------------------------------*/
1538 isSpiltOnStack (symbol * sym)
1542 debugLog ("%s\n", __FUNCTION__);
1551 /* if (sym->_G.stackSpil) */
1554 if (!sym->usl.spillLoc)
1557 etype = getSpec (sym->usl.spillLoc->type);
1558 if (IN_STACK (etype))
1564 /*-----------------------------------------------------------------*/
1565 /* spillThis - spils a specific operand */
1566 /*-----------------------------------------------------------------*/
1568 spillThis (symbol * sym)
1571 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1572 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1574 /* if this is rematerializable or has a spillLocation
1575 we are okay, else we need to create a spillLocation
1577 if (!(sym->remat || sym->usl.spillLoc))
1578 createStackSpil (sym);
1581 /* mark it has spilt & put it in the spilt set */
1583 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1585 bitVectUnSetBit (_G.regAssigned, sym->key);
1587 for (i = 0; i < sym->nRegs; i++)
1591 freeReg (sym->regs[i]);
1592 sym->regs[i] = NULL;
1596 /* if spilt on stack then free up r0 & r1
1597 if they could have been assigned to some
1599 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1602 spillLRWithPtrReg (sym);
1605 if (sym->usl.spillLoc && !sym->remat)
1606 sym->usl.spillLoc->allocreq = 1;
1611 /*-----------------------------------------------------------------*/
1612 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1613 /*-----------------------------------------------------------------*/
1615 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1617 bitVect *lrcs = NULL;
1621 debugLog ("%s\n", __FUNCTION__);
1623 /* get the spillable live ranges */
1624 lrcs = computeSpillable (ic);
1627 /* get all live ranges that are rematerizable */
1628 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1630 /* return the least used of these */
1631 return leastUsedLR (selectS);
1634 /* get live ranges with spillLocations in direct space */
1635 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1637 sym = leastUsedLR (selectS);
1638 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1639 sym->usl.spillLoc->rname :
1640 sym->usl.spillLoc->name));
1642 /* mark it as allocation required */
1643 sym->usl.spillLoc->allocreq = 1;
1647 /* if the symbol is local to the block then */
1648 if (forSym->liveTo < ebp->lSeq)
1651 /* check if there are any live ranges allocated
1652 to registers that are not used in this block */
1653 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1655 sym = leastUsedLR (selectS);
1656 /* if this is not rematerializable */
1665 /* check if there are any live ranges that not
1666 used in the remainder of the block */
1667 if (!_G.blockSpil &&
1668 !isiCodeInFunctionCall (ic) &&
1669 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1671 sym = leastUsedLR (selectS);
1674 sym->remainSpil = 1;
1681 /* find live ranges with spillocation && not used as pointers */
1682 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1685 sym = leastUsedLR (selectS);
1686 /* mark this as allocation required */
1687 sym->usl.spillLoc->allocreq = 1;
1691 /* find live ranges with spillocation */
1692 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1695 sym = leastUsedLR (selectS);
1696 sym->usl.spillLoc->allocreq = 1;
1700 /* couldn't find then we need to create a spil
1701 location on the stack , for which one? the least
1703 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1706 /* return a created spil location */
1707 sym = createStackSpil (leastUsedLR (selectS));
1708 sym->usl.spillLoc->allocreq = 1;
1712 /* this is an extreme situation we will spill
1713 this one : happens very rarely but it does happen */
1719 /*-----------------------------------------------------------------*/
1720 /* spilSomething - spil some variable & mark registers as free */
1721 /*-----------------------------------------------------------------*/
1723 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1728 debugLog ("%s\n", __FUNCTION__);
1729 /* get something we can spil */
1730 ssym = selectSpil (ic, ebp, forSym);
1732 /* mark it as spilt */
1734 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1736 /* mark it as not register assigned &
1737 take it away from the set */
1738 bitVectUnSetBit (_G.regAssigned, ssym->key);
1740 /* mark the registers as free */
1741 for (i = 0; i < ssym->nRegs; i++)
1743 freeReg (ssym->regs[i]);
1745 /* if spilt on stack then free up r0 & r1
1746 if they could have been assigned to as gprs */
1747 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1750 spillLRWithPtrReg (ssym);
1753 /* if this was a block level spil then insert push & pop
1754 at the start & end of block respectively */
1755 if (ssym->blockSpil)
1757 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1758 /* add push to the start of the block */
1759 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1760 ebp->sch->next : ebp->sch));
1761 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1762 /* add pop to the end of the block */
1763 addiCodeToeBBlock (ebp, nic, NULL);
1766 /* if spilt because not used in the remainder of the
1767 block then add a push before this instruction and
1768 a pop at the end of the block */
1769 if (ssym->remainSpil)
1772 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1773 /* add push just before this instruction */
1774 addiCodeToeBBlock (ebp, nic, ic);
1776 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1777 /* add pop to the end of the block */
1778 addiCodeToeBBlock (ebp, nic, NULL);
1787 /*-----------------------------------------------------------------*/
1788 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1789 /*-----------------------------------------------------------------*/
1791 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1796 debugLog ("%s\n", __FUNCTION__);
1798 /* try for a ptr type */
1799 if ((reg = allocReg (REG_PTR)))
1802 /* try for gpr type */
1803 if ((reg = allocReg (REG_GPR)))
1806 /* we have to spil */
1807 if (!spilSomething (ic, ebp, sym))
1810 /* make sure partially assigned registers aren't reused */
1811 for (j=0; j<=sym->nRegs; j++)
1813 sym->regs[j]->isFree = 0;
1815 /* this looks like an infinite loop but
1816 in really selectSpil will abort */
1820 /*-----------------------------------------------------------------*/
1821 /* getRegGpr - will try for GPR if not spil */
1822 /*-----------------------------------------------------------------*/
1824 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1829 debugLog ("%s\n", __FUNCTION__);
1831 /* try for gpr type */
1832 if ((reg = allocReg (REG_GPR)))
1835 if (!pic14_ptrRegReq)
1836 if ((reg = allocReg (REG_PTR)))
1839 /* we have to spil */
1840 if (!spilSomething (ic, ebp, sym))
1843 /* make sure partially assigned registers aren't reused */
1844 for (j=0; j<=sym->nRegs; j++)
1846 sym->regs[j]->isFree = 0;
1848 /* this looks like an infinite loop but
1849 in really selectSpil will abort */
1853 /*-----------------------------------------------------------------*/
1854 /* symHasReg - symbol has a given register */
1855 /*-----------------------------------------------------------------*/
1857 symHasReg (symbol * sym, regs * reg)
1861 debugLog ("%s\n", __FUNCTION__);
1862 for (i = 0; i < sym->nRegs; i++)
1863 if (sym->regs[i] == reg)
1869 /*-----------------------------------------------------------------*/
1870 /* deassignLRs - check the live to and if they have registers & are */
1871 /* not spilt then free up the registers */
1872 /*-----------------------------------------------------------------*/
1874 deassignLRs (iCode * ic, eBBlock * ebp)
1880 debugLog ("%s\n", __FUNCTION__);
1881 for (sym = hTabFirstItem (liveRanges, &k); sym;
1882 sym = hTabNextItem (liveRanges, &k))
1885 symbol *psym = NULL;
1886 /* if it does not end here */
1887 if (sym->liveTo > ic->seq)
1890 /* Prevent the result from being assigned the same registers as (one)
1891 * operand as many genXXX-functions fail otherwise.
1892 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1893 * are known to fail. */
1894 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1898 case '=': /* assignment */
1899 case BITWISEAND: /* bitwise AND */
1900 case '|': /* bitwise OR */
1901 case '^': /* bitwise XOR */
1902 case '~': /* bitwise negate */
1903 case RLC: /* rotate through carry */
1906 case '+': /* addition */
1907 case '-': /* subtraction */
1908 /* go ahead, these are safe to use with
1909 * non-disjoint register sets */
1913 /* do not release operand registers */
1914 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1919 /* if it was spilt on stack then we can
1920 mark the stack spil location as free */
1925 sym->usl.spillLoc->isFree = 1;
1931 if (!bitVectBitValue (_G.regAssigned, sym->key))
1933 /* special case check if this is an IFX &
1934 the privious one was a pop and the
1935 previous one was not spilt then keep track
1937 if (ic->op == IFX && ic->prev &&
1938 ic->prev->op == IPOP &&
1939 !ic->prev->parmPush &&
1940 IS_SYMOP(IC_LEFT (ic->prev)) &&
1941 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1942 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1948 bitVectUnSetBit (_G.regAssigned, sym->key);
1950 /* if the result of this one needs registers
1951 and does not have it then assign it right
1953 if (IC_RESULT (ic) &&
1954 !(SKIP_IC2 (ic) || /* not a special icode */
1955 ic->op == JUMPTABLE ||
1960 POINTER_SET (ic)) &&
1961 IS_SYMOP (IC_RESULT (ic)) &&
1962 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1963 result->liveTo > ic->seq && /* and will live beyond this */
1964 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1965 result->liveFrom == ic->seq && /* does not start before here */
1966 result->regType == sym->regType && /* same register types */
1967 result->regType == sym->regType && /* same register types */
1968 result->nRegs && /* which needs registers */
1969 !result->isspilt && /* and does not already have them */
1971 !bitVectBitValue (_G.regAssigned, result->key) &&
1972 /* the number of free regs + number of regs in this LR
1973 can accomodate the what result Needs */
1974 ((nfreeRegsType (result->regType) +
1975 sym->nRegs) >= result->nRegs)
1979 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1981 result->regs[i] = sym->regs[i];
1983 result->regs[i] = getRegGpr (ic, ebp, result);
1985 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1989 /* free the remaining */
1990 for (; i < sym->nRegs; i++)
1994 if (!symHasReg (psym, sym->regs[i]))
1995 freeReg (sym->regs[i]);
1998 freeReg (sym->regs[i]);
2005 /*-----------------------------------------------------------------*/
2006 /* reassignLR - reassign this to registers */
2007 /*-----------------------------------------------------------------*/
2009 reassignLR (operand * op)
2011 symbol *sym = OP_SYMBOL (op);
2014 debugLog ("%s\n", __FUNCTION__);
2015 /* not spilt any more */
2016 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2017 bitVectUnSetBit (_G.spiltSet, sym->key);
2019 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2023 for (i = 0; i < sym->nRegs; i++)
2024 sym->regs[i]->isFree = 0;
2027 /*-----------------------------------------------------------------*/
2028 /* willCauseSpill - determines if allocating will cause a spill */
2029 /*-----------------------------------------------------------------*/
2031 willCauseSpill (int nr, int rt)
2033 debugLog ("%s\n", __FUNCTION__);
2034 /* first check if there are any avlb registers
2035 of te type required */
2038 /* special case for pointer type
2039 if pointer type not avlb then
2040 check for type gpr */
2041 if (nFreeRegs (rt) >= nr)
2043 if (nFreeRegs (REG_GPR) >= nr)
2048 if (pic14_ptrRegReq)
2050 if (nFreeRegs (rt) >= nr)
2055 if (nFreeRegs (REG_PTR) +
2056 nFreeRegs (REG_GPR) >= nr)
2061 debugLog (" ... yep it will (cause a spill)\n");
2062 /* it will cause a spil */
2066 /*-----------------------------------------------------------------*/
2067 /* positionRegs - the allocator can allocate same registers to res- */
2068 /* ult and operand, if this happens make sure they are in the same */
2069 /* position as the operand otherwise chaos results */
2070 /*-----------------------------------------------------------------*/
2072 positionRegs (symbol * result, symbol * opsym, int lineno)
2074 int count = min (result->nRegs, opsym->nRegs);
2075 int i, j = 0, shared = 0;
2077 debugLog ("%s\n", __FUNCTION__);
2078 /* if the result has been spilt then cannot share */
2083 /* first make sure that they actually share */
2084 for (i = 0; i < count; i++)
2086 for (j = 0; j < count; j++)
2088 if (result->regs[i] == opsym->regs[j] && i != j)
2098 regs *tmp = result->regs[i];
2099 result->regs[i] = result->regs[j];
2100 result->regs[j] = tmp;
2105 /*------------------------------------------------------------------*/
2106 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2107 /* it should either have registers or have beed spilled. Otherwise, */
2108 /* there was an uninitialized variable, so just spill this to get */
2109 /* the operand in a valid state. */
2110 /*------------------------------------------------------------------*/
2112 verifyRegsAssigned (operand *op, iCode * ic)
2117 if (!IS_ITEMP (op)) return;
2119 sym = OP_SYMBOL (op);
2120 if (sym->isspilt) return;
2121 if (!sym->nRegs) return;
2122 if (sym->regs[0]) return;
2124 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2125 sym->prereqv ? sym->prereqv->name : sym->name);
2130 /*-----------------------------------------------------------------*/
2131 /* serialRegAssign - serially allocate registers to the variables */
2132 /*-----------------------------------------------------------------*/
2134 serialRegAssign (eBBlock ** ebbs, int count)
2138 debugLog ("%s\n", __FUNCTION__);
2139 /* for all blocks */
2140 for (i = 0; i < count; i++)
2145 if (ebbs[i]->noPath &&
2146 (ebbs[i]->entryLabel != entryLabel &&
2147 ebbs[i]->entryLabel != returnLabel))
2150 /* of all instructions do */
2151 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2153 debugLog (" op: %s\n", decodeOp (ic->op));
2155 /* if this is an ipop that means some live
2156 range will have to be assigned again */
2158 reassignLR (IC_LEFT (ic));
2160 /* if result is present && is a true symbol */
2161 if (IC_RESULT (ic) && ic->op != IFX &&
2162 IS_TRUE_SYMOP (IC_RESULT (ic)))
2163 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2165 /* take away registers from live
2166 ranges that end at this instruction */
2167 deassignLRs (ic, ebbs[i]);
2169 /* some don't need registers */
2170 if (SKIP_IC2 (ic) ||
2171 ic->op == JUMPTABLE ||
2175 (IC_RESULT (ic) && POINTER_SET (ic)))
2178 /* now we need to allocate registers
2179 only for the result */
2180 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2182 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2188 /* Make sure any spill location is definately allocated */
2189 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2190 !sym->usl.spillLoc->allocreq)
2192 sym->usl.spillLoc->allocreq++;
2195 /* if it does not need or is spilt
2196 or is already assigned to registers
2197 or will not live beyond this instructions */
2200 bitVectBitValue (_G.regAssigned, sym->key) ||
2201 sym->liveTo <= ic->seq)
2204 /* if some liverange has been spilt at the block level
2205 and this one live beyond this block then spil this
2207 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2212 /* if trying to allocate this will cause
2213 a spill and there is nothing to spill
2214 or this one is rematerializable then
2216 willCS = willCauseSpill (sym->nRegs, sym->regType);
2217 spillable = computeSpillable (ic);
2219 (willCS && bitVectIsZero (spillable)))
2227 /* If the live range preceeds the point of definition
2228 then ideally we must take into account registers that
2229 have been allocated after sym->liveFrom but freed
2230 before ic->seq. This is complicated, so spill this
2231 symbol instead and let fillGaps handle the allocation. */
2232 if (sym->liveFrom < ic->seq)
2238 /* if it has a spillocation & is used less than
2239 all other live ranges then spill this */
2241 if (sym->usl.spillLoc) {
2242 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2243 allLRs, ebbs[i], ic));
2244 if (leastUsed && leastUsed->used > sym->used) {
2249 /* if none of the liveRanges have a spillLocation then better
2250 to spill this one than anything else already assigned to registers */
2251 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2252 /* if this is local to this block then we might find a block spil */
2253 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2261 if (ic->op == RECEIVE)
2262 debugLog ("When I get clever, I'll optimize the receive logic\n");
2264 /* if we need ptr regs for the right side
2266 if (POINTER_GET (ic)
2267 && IS_SYMOP(IC_LEFT(ic))
2268 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2269 <= (unsigned) PTRSIZE)
2274 /* else we assign registers to it */
2275 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2277 debugLog (" %d - \n", __LINE__);
2279 bitVectDebugOn(_G.regAssigned, debugF);
2280 for (j = 0; j < sym->nRegs; j++)
2282 if (sym->regType == REG_PTR)
2283 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2285 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2287 /* if the allocation failed which means
2288 this was spilt then break */
2292 debugLog (" %d - \n", __LINE__);
2294 /* if it shares registers with operands make sure
2295 that they are in the same position */
2296 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2297 IS_SYMOP(IC_RESULT(ic)) &&
2298 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2299 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2300 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2301 /* do the same for the right operand */
2302 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2303 IS_SYMOP(IC_RESULT(ic)) &&
2304 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2305 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2306 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2308 debugLog (" %d - \n", __LINE__);
2311 debugLog (" %d - \n", __LINE__);
2320 /* Check for and fix any problems with uninitialized operands */
2321 for (i = 0; i < count; i++)
2325 if (ebbs[i]->noPath &&
2326 (ebbs[i]->entryLabel != entryLabel &&
2327 ebbs[i]->entryLabel != returnLabel))
2330 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2337 verifyRegsAssigned (IC_COND (ic), ic);
2341 if (ic->op == JUMPTABLE)
2343 verifyRegsAssigned (IC_JTCOND (ic), ic);
2347 verifyRegsAssigned (IC_RESULT (ic), ic);
2348 verifyRegsAssigned (IC_LEFT (ic), ic);
2349 verifyRegsAssigned (IC_RIGHT (ic), ic);
2355 /*-----------------------------------------------------------------*/
2356 /* rUmaskForOp :- returns register mask for an operand */
2357 /*-----------------------------------------------------------------*/
2359 rUmaskForOp (operand * op)
2365 debugLog ("%s\n", __FUNCTION__);
2366 /* only temporaries are assigned registers */
2370 sym = OP_SYMBOL (op);
2372 /* if spilt or no registers assigned to it
2374 if (sym->isspilt || !sym->nRegs)
2377 rumask = newBitVect (pic14_nRegs);
2379 for (j = 0; j < sym->nRegs; j++)
2381 rumask = bitVectSetBit (rumask,
2382 sym->regs[j]->rIdx);
2388 /*-----------------------------------------------------------------*/
2389 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2390 /*-----------------------------------------------------------------*/
2392 regsUsedIniCode (iCode * ic)
2394 bitVect *rmask = newBitVect (pic14_nRegs);
2396 debugLog ("%s\n", __FUNCTION__);
2397 /* do the special cases first */
2400 rmask = bitVectUnion (rmask,
2401 rUmaskForOp (IC_COND (ic)));
2405 /* for the jumptable */
2406 if (ic->op == JUMPTABLE)
2408 rmask = bitVectUnion (rmask,
2409 rUmaskForOp (IC_JTCOND (ic)));
2414 /* of all other cases */
2416 rmask = bitVectUnion (rmask,
2417 rUmaskForOp (IC_LEFT (ic)));
2421 rmask = bitVectUnion (rmask,
2422 rUmaskForOp (IC_RIGHT (ic)));
2425 rmask = bitVectUnion (rmask,
2426 rUmaskForOp (IC_RESULT (ic)));
2432 /*-----------------------------------------------------------------*/
2433 /* createRegMask - for each instruction will determine the regsUsed */
2434 /*-----------------------------------------------------------------*/
2436 createRegMask (eBBlock ** ebbs, int count)
2440 debugLog ("%s\n", __FUNCTION__);
2441 /* for all blocks */
2442 for (i = 0; i < count; i++)
2446 if (ebbs[i]->noPath &&
2447 (ebbs[i]->entryLabel != entryLabel &&
2448 ebbs[i]->entryLabel != returnLabel))
2451 /* for all instructions */
2452 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2457 if (SKIP_IC2 (ic) || !ic->rlive)
2460 /* first mark the registers used in this
2462 ic->rUsed = regsUsedIniCode (ic);
2463 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2465 /* now create the register mask for those
2466 registers that are in use : this is a
2467 super set of ic->rUsed */
2468 ic->rMask = newBitVect (pic14_nRegs + 1);
2470 /* for all live Ranges alive at this point */
2471 for (j = 1; j < ic->rlive->size; j++)
2476 /* if not alive then continue */
2477 if (!bitVectBitValue (ic->rlive, j))
2480 /* find the live range we are interested in */
2481 if (!(sym = hTabItemWithKey (liveRanges, j)))
2483 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2484 "createRegMask cannot find live range");
2488 /* if no register assigned to it */
2489 if (!sym->nRegs || sym->isspilt)
2492 /* for all the registers allocated to it */
2493 for (k = 0; k < sym->nRegs; k++)
2496 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2502 /* This was the active version */
2503 /*-----------------------------------------------------------------*/
2504 /* rematStr - returns the rematerialized string for a remat var */
2505 /*-----------------------------------------------------------------*/
2507 rematStr (symbol * sym)
2510 iCode *ic = sym->rematiCode;
2511 symbol *psym = NULL;
2513 debugLog ("%s\n", __FUNCTION__);
2515 //printf ("%s\n", s);
2517 /* if plus or minus print the right hand side */
2519 if (ic->op == '+' || ic->op == '-') {
2521 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2523 sprintf (s, "(%s %c 0x%04x)",
2524 OP_SYMBOL (IC_LEFT (ric))->rname,
2526 (int) operandLitValue (IC_RIGHT (ic)));
2529 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2531 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2532 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2537 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2538 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2540 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2546 /* deprecated version */
2547 /*-----------------------------------------------------------------*/
2548 /* rematStr - returns the rematerialized string for a remat var */
2549 /*-----------------------------------------------------------------*/
2551 rematStr (symbol * sym)
2554 iCode *ic = sym->rematiCode;
2556 debugLog ("%s\n", __FUNCTION__);
2561 /* if plus or minus print the right hand side */
2563 if (ic->op == '+' || ic->op == '-') {
2564 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2567 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2571 if (ic->op == '+' || ic->op == '-')
2573 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2574 sprintf (s, "(%s %c 0x%04x)",
2575 OP_SYMBOL (IC_LEFT (ric))->rname,
2577 (int) operandLitValue (IC_RIGHT (ic)));
2580 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2582 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2586 /* we reached the end */
2587 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2591 printf ("%s\n", buffer);
2596 /*-----------------------------------------------------------------*/
2597 /* regTypeNum - computes the type & number of registers required */
2598 /*-----------------------------------------------------------------*/
2606 debugLog ("%s\n", __FUNCTION__);
2607 /* for each live range do */
2608 for (sym = hTabFirstItem (liveRanges, &k); sym;
2609 sym = hTabNextItem (liveRanges, &k)) {
2611 debugLog (" %d - %s\n", __LINE__, sym->rname);
2613 /* if used zero times then no registers needed */
2614 if ((sym->liveTo - sym->liveFrom) == 0)
2618 /* if the live range is a temporary */
2621 debugLog (" %d - itemp register\n", __LINE__);
2623 /* if the type is marked as a conditional */
2624 if (sym->regType == REG_CND)
2627 /* if used in return only then we don't
2630 if (IS_AGGREGATE (sym->type) || sym->isptr)
2631 sym->type = aggrToPtr (sym->type, FALSE);
2632 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2638 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2639 // sym->type = aggrToPtr (sym->type, FALSE);
2640 debugLog (" %d - used as a return\n", __LINE__);
2645 /* if the symbol has only one definition &
2646 that definition is a get_pointer and the
2647 pointer we are getting is rematerializable and
2651 if (bitVectnBitsOn (sym->defs) == 1 &&
2652 (ic = hTabItemWithKey (iCodehTab,
2653 bitVectFirstBit (sym->defs))) &&
2655 !IS_BITVAR (sym->etype) &&
2656 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2658 if (ptrPseudoSymSafe (sym, ic)) {
2662 debugLog (" %d - \n", __LINE__);
2664 /* create a pseudo symbol & force a spil */
2665 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2666 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2667 psym->type = sym->type;
2668 psym->etype = sym->etype;
2669 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2670 strcpy (psym->rname, psym->name);
2672 sym->usl.spillLoc = psym;
2676 /* if in data space or idata space then try to
2677 allocate pointer register */
2682 /* if not then we require registers */
2683 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2684 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2685 getSize (sym->type));
2688 if(IS_PTR_CONST (sym->type)) {
2689 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2693 if (sym->nRegs > 4) {
2694 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2695 printTypeChain (sym->type, stderr);
2696 fprintf (stderr, "\n");
2699 /* determine the type of register required */
2700 if (sym->nRegs == 1 &&
2701 IS_PTR (sym->type) &&
2703 sym->regType = REG_PTR;
2705 sym->regType = REG_GPR;
2708 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2712 /* for the first run we don't provide */
2713 /* registers for true symbols we will */
2714 /* see how things go */
2719 DEFSETFUNC (markRegFree)
2721 ((regs *)item)->isFree = 1;
2726 DEFSETFUNC (deallocReg)
2728 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2729 ((regs *)item)->isFree = 1;
2730 ((regs *)item)->wasUsed = 0;
2734 /*-----------------------------------------------------------------*/
2735 /* freeAllRegs - mark all registers as free */
2736 /*-----------------------------------------------------------------*/
2738 pic14_freeAllRegs ()
2742 debugLog ("%s\n", __FUNCTION__);
2744 applyToSet(dynAllocRegs,markRegFree);
2745 applyToSet(dynStackRegs,markRegFree);
2748 for (i = 0; i < pic14_nRegs; i++)
2749 regspic14[i].isFree = 1;
2753 /*-----------------------------------------------------------------*/
2754 /*-----------------------------------------------------------------*/
2756 pic14_deallocateAllRegs ()
2760 debugLog ("%s\n", __FUNCTION__);
2762 applyToSet(dynAllocRegs,deallocReg);
2765 for (i = 0; i < pic14_nRegs; i++) {
2766 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2767 regspic14[i].isFree = 1;
2768 regspic14[i].wasUsed = 0;
2775 /*-----------------------------------------------------------------*/
2776 /* deallocStackSpil - this will set the stack pointer back */
2777 /*-----------------------------------------------------------------*/
2779 DEFSETFUNC (deallocStackSpil)
2783 debugLog ("%s\n", __FUNCTION__);
2788 /*-----------------------------------------------------------------*/
2789 /* farSpacePackable - returns the packable icode for far variables */
2790 /*-----------------------------------------------------------------*/
2792 farSpacePackable (iCode * ic)
2796 debugLog ("%s\n", __FUNCTION__);
2797 /* go thru till we find a definition for the
2798 symbol on the right */
2799 for (dic = ic->prev; dic; dic = dic->prev)
2802 /* if the definition is a call then no */
2803 if ((dic->op == CALL || dic->op == PCALL) &&
2804 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2809 /* if shift by unknown amount then not */
2810 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2811 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2814 /* if pointer get and size > 1 */
2815 if (POINTER_GET (dic) &&
2816 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2819 if (POINTER_SET (dic) &&
2820 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2823 /* if any three is a true symbol in far space */
2824 if (IC_RESULT (dic) &&
2825 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2826 isOperandInFarSpace (IC_RESULT (dic)))
2829 if (IC_RIGHT (dic) &&
2830 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2831 isOperandInFarSpace (IC_RIGHT (dic)) &&
2832 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2835 if (IC_LEFT (dic) &&
2836 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2837 isOperandInFarSpace (IC_LEFT (dic)) &&
2838 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2841 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2843 if ((dic->op == LEFT_OP ||
2844 dic->op == RIGHT_OP ||
2846 IS_OP_LITERAL (IC_RIGHT (dic)))
2856 /*-----------------------------------------------------------------*/
2857 /* packRegsForAssign - register reduction for assignment */
2858 /*-----------------------------------------------------------------*/
2860 packRegsForAssign (iCode * ic, eBBlock * ebp)
2865 debugLog ("%s\n", __FUNCTION__);
2867 debugAopGet (" result:", IC_RESULT (ic));
2868 debugAopGet (" left:", IC_LEFT (ic));
2869 debugAopGet (" right:", IC_RIGHT (ic));
2871 /* if this is at an absolute address, then get the address. */
2872 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2873 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2874 debugLog (" %d - found config word declaration\n", __LINE__);
2875 if(IS_VALOP(IC_RIGHT(ic))) {
2876 debugLog (" setting config word to %x\n",
2877 (int) ulFromVal (IC_RIGHT(ic)->operand.valOperand));
2878 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2879 (int) ulFromVal (IC_RIGHT(ic)->operand.valOperand));
2882 /* remove the assignment from the iCode chain. */
2884 remiCodeFromeBBlock (ebp, ic);
2885 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2886 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2893 if (!IS_ITEMP (IC_RESULT (ic))) {
2894 allocDirReg(IC_RESULT (ic));
2895 debugLog (" %d - result is not temp\n", __LINE__);
2898 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2899 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2900 allocDirReg(IC_LEFT (ic));
2904 if (!IS_ITEMP (IC_RIGHT (ic))) {
2905 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2907 /* only pack if this is not a function pointer */
2908 if (!IS_REF (IC_RIGHT (ic)))
2909 allocDirReg(IC_RIGHT (ic));
2913 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2914 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2916 debugLog (" %d - not packing - right side fails \n", __LINE__);
2920 /* if the true symbol is defined in far space or on stack
2921 then we should not since this will increase register pressure */
2922 if (isOperandInFarSpace (IC_RESULT (ic)))
2924 if ((dic = farSpacePackable (ic)))
2930 /* find the definition of iTempNN scanning backwards if we find a
2931 a use of the true symbol before we find the definition then
2933 for (dic = ic->prev; dic; dic = dic->prev)
2936 /* if there is a function call and this is
2937 a parameter & not my parameter then don't pack it */
2938 if ((dic->op == CALL || dic->op == PCALL) &&
2939 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2940 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2942 debugLog (" %d - \n", __LINE__);
2950 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2951 IS_OP_VOLATILE (IC_RESULT (dic)))
2953 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2958 if (IS_SYMOP (IC_RESULT (dic)) &&
2959 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2961 /* A previous result was assigned to the same register - we'll our definition */
2962 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2963 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2964 if (POINTER_SET (dic))
2970 if (IS_SYMOP (IC_RIGHT (dic)) &&
2971 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2972 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2974 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2979 if (IS_SYMOP (IC_LEFT (dic)) &&
2980 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2981 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2983 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2988 if (POINTER_SET (dic) &&
2989 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2991 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2999 return 0; /* did not find */
3001 /* if assignment then check that right is not a bit */
3002 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
3004 sym_link *etype = operandType (IC_RESULT (dic));
3005 if (IS_BITFIELD (etype))
3007 /* if result is a bit too then it's ok */
3008 etype = operandType (IC_RESULT (ic));
3009 if (!IS_BITFIELD (etype))
3014 /* if the result is on stack or iaccess then it must be
3015 the same at least one of the operands */
3016 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3017 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3020 /* the operation has only one symbol
3021 operator then we can pack */
3022 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3023 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3026 if (!((IC_LEFT (dic) &&
3027 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3029 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3033 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3034 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3035 /* found the definition */
3036 /* replace the result with the result of */
3037 /* this assignment and remove this assignment */
3038 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3039 IC_RESULT (dic) = IC_RESULT (ic);
3041 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3043 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3045 /* delete from liverange table also
3046 delete from all the points inbetween and the new
3048 for (sic = dic; sic != ic; sic = sic->next)
3050 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3051 if (IS_ITEMP (IC_RESULT (dic)))
3052 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3055 remiCodeFromeBBlock (ebp, ic);
3056 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3057 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3058 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3064 /*-----------------------------------------------------------------*/
3065 /* findAssignToSym : scanning backwards looks for first assig found */
3066 /*-----------------------------------------------------------------*/
3068 findAssignToSym (operand * op, iCode * ic)
3072 debugLog ("%s\n", __FUNCTION__);
3073 for (dic = ic->prev; dic; dic = dic->prev)
3076 /* if definition by assignment */
3077 if (dic->op == '=' &&
3078 !POINTER_SET (dic) &&
3079 IC_RESULT (dic)->key == op->key
3080 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3084 /* we are interested only if defined in far space */
3085 /* or in stack space in case of + & - */
3087 /* if assigned to a non-symbol then return
3089 if (!IS_SYMOP (IC_RIGHT (dic)))
3092 /* if the symbol is in far space then
3094 if (isOperandInFarSpace (IC_RIGHT (dic)))
3097 /* for + & - operations make sure that
3098 if it is on the stack it is the same
3099 as one of the three operands */
3100 if ((ic->op == '+' || ic->op == '-') &&
3101 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3104 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3105 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3106 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3114 /* if we find an usage then we cannot delete it */
3115 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3118 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3121 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3125 /* now make sure that the right side of dic
3126 is not defined between ic & dic */
3129 iCode *sic = dic->next;
3131 for (; sic != ic; sic = sic->next)
3132 if (IC_RESULT (sic) &&
3133 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3142 /*-----------------------------------------------------------------*/
3143 /* packRegsForSupport :- reduce some registers for support calls */
3144 /*-----------------------------------------------------------------*/
3146 packRegsForSupport (iCode * ic, eBBlock * ebp)
3150 debugLog ("%s\n", __FUNCTION__);
3151 /* for the left & right operand :- look to see if the
3152 left was assigned a true symbol in far space in that
3153 case replace them */
3154 if (IS_ITEMP (IC_LEFT (ic)) &&
3155 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3157 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3163 debugAopGet ("removing left:", IC_LEFT (ic));
3165 /* found it we need to remove it from the
3167 for (sic = dic; sic != ic; sic = sic->next)
3168 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3170 IC_LEFT (ic)->operand.symOperand =
3171 IC_RIGHT (dic)->operand.symOperand;
3172 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3173 remiCodeFromeBBlock (ebp, dic);
3174 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3175 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3179 /* do the same for the right operand */
3182 IS_ITEMP (IC_RIGHT (ic)) &&
3183 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3185 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3191 /* if this is a subtraction & the result
3192 is a true symbol in far space then don't pack */
3193 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3195 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3196 if (IN_FARSPACE (SPEC_OCLS (etype)))
3200 debugAopGet ("removing right:", IC_RIGHT (ic));
3202 /* found it we need to remove it from the
3204 for (sic = dic; sic != ic; sic = sic->next)
3205 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3207 IC_RIGHT (ic)->operand.symOperand =
3208 IC_RIGHT (dic)->operand.symOperand;
3209 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3211 remiCodeFromeBBlock (ebp, dic);
3212 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3213 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3221 /*-----------------------------------------------------------------*/
3222 /* packRegsForOneuse : - will reduce some registers for single Use */
3223 /*-----------------------------------------------------------------*/
3225 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3230 debugLog ("%s\n", __FUNCTION__);
3231 /* if returning a literal then do nothing */
3235 /* only upto 2 bytes since we cannot predict
3236 the usage of b, & acc */
3237 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3242 /* this routine will mark the a symbol as used in one
3243 instruction use only && if the definition is local
3244 (ie. within the basic block) && has only one definition &&
3245 that definition is either a return value from a
3246 function or does not contain any variables in
3248 uses = bitVectCopy (OP_USES (op));
3249 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3250 if (!bitVectIsZero (uses)) /* has other uses */
3253 /* if it has only one defintion */
3254 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3255 return NULL; /* has more than one definition */
3257 /* get that definition */
3259 hTabItemWithKey (iCodehTab,
3260 bitVectFirstBit (OP_DEFS (op)))))
3263 /* found the definition now check if it is local */
3264 if (dic->seq < ebp->fSeq ||
3265 dic->seq > ebp->lSeq)
3266 return NULL; /* non-local */
3268 /* now check if it is the return from
3270 if (dic->op == CALL || dic->op == PCALL)
3272 if (ic->op != SEND && ic->op != RETURN &&
3273 !POINTER_SET(ic) && !POINTER_GET(ic))
3275 OP_SYMBOL (op)->ruonly = 1;
3282 /* otherwise check that the definition does
3283 not contain any symbols in far space */
3284 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3285 isOperandInFarSpace (IC_RIGHT (dic)) ||
3286 IS_OP_RUONLY (IC_LEFT (ic)) ||
3287 IS_OP_RUONLY (IC_RIGHT (ic)))
3292 /* if pointer set then make sure the pointer
3294 if (POINTER_SET (dic) &&
3295 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3298 if (POINTER_GET (dic) &&
3299 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3304 /* also make sure the intervenening instructions
3305 don't have any thing in far space */
3306 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3309 /* if there is an intervening function call then no */
3310 if (dic->op == CALL || dic->op == PCALL)
3312 /* if pointer set then make sure the pointer
3314 if (POINTER_SET (dic) &&
3315 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3318 if (POINTER_GET (dic) &&
3319 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3322 /* if address of & the result is remat then okay */
3323 if (dic->op == ADDRESS_OF &&
3324 OP_SYMBOL (IC_RESULT (dic))->remat)
3327 /* if operand has size of three or more & this
3328 operation is a '*','/' or '%' then 'b' may
3330 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3331 getSize (operandType (op)) >= 3)
3334 /* if left or right or result is in far space */
3335 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3336 isOperandInFarSpace (IC_RIGHT (dic)) ||
3337 isOperandInFarSpace (IC_RESULT (dic)) ||
3338 IS_OP_RUONLY (IC_LEFT (dic)) ||
3339 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3340 IS_OP_RUONLY (IC_RESULT (dic)))
3346 OP_SYMBOL (op)->ruonly = 1;
3351 /*-----------------------------------------------------------------*/
3352 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3353 /*-----------------------------------------------------------------*/
3355 isBitwiseOptimizable (iCode * ic)
3357 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3358 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3360 debugLog ("%s\n", __FUNCTION__);
3361 /* bitwise operations are considered optimizable
3362 under the following conditions (Jean-Louis VERN)
3374 if (IS_LITERAL (rtype) ||
3375 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3381 /*-----------------------------------------------------------------*/
3382 /* packRegsForAccUse - pack registers for acc use */
3383 /*-----------------------------------------------------------------*/
3385 packRegsForAccUse (iCode * ic)
3389 debugLog ("%s\n", __FUNCTION__);
3391 /* result too large for WREG? */
3392 if (getSize (operandType (IC_RESULT (ic))) > 1)
3395 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3396 * is never used as an operand to an instruction that
3397 * cannot have WREG as an operand (e.g. BTFSx cannot
3398 * operate on WREG...
3399 * For now, store all results into proper registers. */
3403 /* if this is an aggregate, e.g. a one byte char array */
3404 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3407 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3409 /* if + or - then it has to be one byte result */
3410 if ((ic->op == '+' || ic->op == '-')
3411 && getSize (operandType (IC_RESULT (ic))) > 1)
3414 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3415 /* if shift operation make sure right side is not a literal */
3416 if (ic->op == RIGHT_OP &&
3417 (isOperandLiteral (IC_RIGHT (ic)) ||
3418 getSize (operandType (IC_RESULT (ic))) > 1))
3421 if (ic->op == LEFT_OP &&
3422 (isOperandLiteral (IC_RIGHT (ic)) ||
3423 getSize (operandType (IC_RESULT (ic))) > 1))
3426 if (IS_BITWISE_OP (ic) &&
3427 getSize (operandType (IC_RESULT (ic))) > 1)
3431 /* has only one definition */
3432 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3435 /* has only one use */
3436 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3439 /* and the usage immediately follows this iCode */
3440 if (!(uic = hTabItemWithKey (iCodehTab,
3441 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3444 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3445 if (ic->next != uic)
3448 /* if it is a conditional branch then we definitely can */
3452 if (uic->op == JUMPTABLE)
3455 /* if the usage is not is an assignment
3456 or an arithmetic / bitwise / shift operation then not */
3457 if (POINTER_SET (uic) &&
3458 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3461 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3462 if (uic->op != '=' &&
3463 !IS_ARITHMETIC_OP (uic) &&
3464 !IS_BITWISE_OP (uic) &&
3465 uic->op != LEFT_OP &&
3466 uic->op != RIGHT_OP)
3469 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3470 /* if used in ^ operation then make sure right is not a
3472 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3475 /* if shift operation make sure right side is not a literal */
3476 if (uic->op == RIGHT_OP &&
3477 (isOperandLiteral (IC_RIGHT (uic)) ||
3478 getSize (operandType (IC_RESULT (uic))) > 1))
3481 if (uic->op == LEFT_OP &&
3482 (isOperandLiteral (IC_RIGHT (uic)) ||
3483 getSize (operandType (IC_RESULT (uic))) > 1))
3486 /* make sure that the result of this icode is not on the
3487 stack, since acc is used to compute stack offset */
3488 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3489 OP_SYMBOL (IC_RESULT (uic))->onStack)
3492 /* if either one of them in far space then we cannot */
3493 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3494 isOperandInFarSpace (IC_LEFT (uic))) ||
3495 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3496 isOperandInFarSpace (IC_RIGHT (uic))))
3499 /* if the usage has only one operand then we can */
3500 if (IC_LEFT (uic) == NULL ||
3501 IC_RIGHT (uic) == NULL)
3504 /* make sure this is on the left side if not
3505 a '+' since '+' is commutative */
3506 if (ic->op != '+' &&
3507 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3510 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3511 /* if one of them is a literal then we can */
3512 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3513 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3514 (getSize (operandType (IC_RESULT (uic))) <= 1))
3516 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3520 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3521 /* if the other one is not on stack then we can */
3522 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3523 (IS_ITEMP (IC_RIGHT (uic)) ||
3524 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3525 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3528 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3529 (IS_ITEMP (IC_LEFT (uic)) ||
3530 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3531 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3537 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3538 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3542 /*-----------------------------------------------------------------*/
3543 /* packForPush - hueristics to reduce iCode for pushing */
3544 /*-----------------------------------------------------------------*/
3546 packForReceive (iCode * ic, eBBlock * ebp)
3550 debugLog ("%s\n", __FUNCTION__);
3551 debugAopGet (" result:", IC_RESULT (ic));
3552 debugAopGet (" left:", IC_LEFT (ic));
3553 debugAopGet (" right:", IC_RIGHT (ic));
3558 for (dic = ic->next; dic; dic = dic->next)
3563 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3564 debugLog (" used on left\n");
3565 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3566 debugLog (" used on right\n");
3567 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3568 debugLog (" used on result\n");
3570 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3571 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3576 debugLog (" hey we can remove this unnecessary assign\n");
3578 /*-----------------------------------------------------------------*/
3579 /* packForPush - hueristics to reduce iCode for pushing */
3580 /*-----------------------------------------------------------------*/
3582 packForPush (iCode * ic, eBBlock * ebp)
3586 debugLog ("%s\n", __FUNCTION__);
3587 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3590 /* must have only definition & one usage */
3591 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3592 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3595 /* find the definition */
3596 if (!(dic = hTabItemWithKey (iCodehTab,
3597 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3600 if (dic->op != '=' || POINTER_SET (dic))
3603 /* we now we know that it has one & only one def & use
3604 and the that the definition is an assignment */
3605 IC_LEFT (ic) = IC_RIGHT (dic);
3607 remiCodeFromeBBlock (ebp, dic);
3608 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3609 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3612 void printSymType(char * str, sym_link *sl)
3615 debugLog (" %s Symbol type: ",str);
3616 printTypeChain( sl, debugF);
3621 /*-----------------------------------------------------------------*/
3622 /* some debug code to print the symbol S_TYPE. Note that
3623 * the function checkSClass in src/SDCCsymt.c dinks with
3624 * the S_TYPE in ways the PIC port doesn't fully like...*/
3625 /*-----------------------------------------------------------------*/
3626 void isData(sym_link *sl)
3630 // avoid garbage `data' and `sfr' output
3637 for ( ; sl; sl=sl->next) {
3639 switch (SPEC_SCLS(sl)) {
3641 case S_DATA: fprintf (of, "data "); break;
3642 case S_XDATA: fprintf (of, "xdata "); break;
3643 case S_SFR: fprintf (of, "sfr "); break;
3644 case S_SBIT: fprintf (of, "sbit "); break;
3645 case S_CODE: fprintf (of, "code "); break;
3646 case S_IDATA: fprintf (of, "idata "); break;
3647 case S_PDATA: fprintf (of, "pdata "); break;
3648 case S_LITERAL: fprintf (of, "literal "); break;
3649 case S_STACK: fprintf (of, "stack "); break;
3650 case S_XSTACK: fprintf (of, "xstack "); break;
3651 case S_BIT: fprintf (of, "bit "); break;
3652 case S_EEPROM: fprintf (of, "eeprom "); break;
3662 /*-----------------------------------------------------------------*/
3663 /* packRegisters - does some transformations to reduce register */
3665 /*-----------------------------------------------------------------*/
3667 packRegisters (eBBlock * ebp)
3672 debugLog ("%s\n", __FUNCTION__);
3678 /* look for assignments of the form */
3679 /* iTempNN = TRueSym (someoperation) SomeOperand */
3681 /* TrueSym := iTempNN:1 */
3682 for (ic = ebp->sch; ic; ic = ic->next)
3685 /* find assignment of the form TrueSym := iTempNN:1 */
3686 if (ic->op == '=' && !POINTER_SET (ic))
3687 change += packRegsForAssign (ic, ebp);
3691 if (POINTER_SET (ic))
3692 debugLog ("pointer is set\n");
3693 debugAopGet (" result:", IC_RESULT (ic));
3694 debugAopGet (" left:", IC_LEFT (ic));
3695 debugAopGet (" right:", IC_RIGHT (ic));
3704 for (ic = ebp->sch; ic; ic = ic->next) {
3706 if(IS_SYMOP ( IC_LEFT(ic))) {
3707 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3709 debugAopGet (" left:", IC_LEFT (ic));
3710 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3711 debugLog (" is a pointer\n");
3713 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3714 debugLog (" is volatile\n");
3718 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3721 if(IS_SYMOP ( IC_RIGHT(ic))) {
3722 debugAopGet (" right:", IC_RIGHT (ic));
3723 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3726 if(IS_SYMOP ( IC_RESULT(ic))) {
3727 debugAopGet (" result:", IC_RESULT (ic));
3728 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3731 if (POINTER_SET (ic))
3732 debugLog (" %d - Pointer set\n", __LINE__);
3735 /* Look for two subsequent iCodes with */
3737 /* _c = iTemp & op; */
3738 /* and replace them by */
3741 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3743 ic->prev->op == '=' &&
3744 IS_ITEMP (IC_LEFT (ic)) &&
3745 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3746 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3748 iCode* ic_prev = ic->prev;
3749 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3751 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3752 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3754 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3755 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3756 prev_result_sym->liveTo == ic->seq)
3758 prev_result_sym->liveTo = ic_prev->seq;
3761 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3763 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3765 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3767 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3768 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3769 remiCodeFromeBBlock (ebp, ic_prev);
3770 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3774 /* if this is an itemp & result of a address of a true sym
3775 then mark this as rematerialisable */
3776 if (ic->op == ADDRESS_OF &&
3777 IS_ITEMP (IC_RESULT (ic)) &&
3778 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3779 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3780 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3783 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3785 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3786 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3787 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3791 /* if straight assignment then carry remat flag if
3792 this is the only definition */
3793 if (ic->op == '=' &&
3794 !POINTER_SET (ic) &&
3795 IS_SYMOP (IC_RIGHT (ic)) &&
3796 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3797 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3799 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3801 OP_SYMBOL (IC_RESULT (ic))->remat =
3802 OP_SYMBOL (IC_RIGHT (ic))->remat;
3803 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3804 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3807 /* if this is a +/- operation with a rematerizable
3808 then mark this as rematerializable as well */
3809 if ((ic->op == '+' || ic->op == '-') &&
3810 (IS_SYMOP (IC_LEFT (ic)) &&
3811 IS_ITEMP (IC_RESULT (ic)) &&
3812 OP_SYMBOL (IC_LEFT (ic))->remat &&
3813 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3814 IS_OP_LITERAL (IC_RIGHT (ic))))
3816 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3818 operandLitValue (IC_RIGHT (ic));
3819 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3820 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3821 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3824 /* mark the pointer usages */
3825 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3827 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3828 debugLog (" marking as a pointer (set) =>");
3829 debugAopGet (" result:", IC_RESULT (ic));
3831 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3833 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3834 debugLog (" marking as a pointer (get) =>");
3835 debugAopGet (" left:", IC_LEFT (ic));
3840 /* if we are using a symbol on the stack
3841 then we should say pic14_ptrRegReq */
3842 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3843 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3844 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3845 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3846 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3847 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3850 if (IS_SYMOP (IC_LEFT (ic)))
3851 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3852 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3853 if (IS_SYMOP (IC_RIGHT (ic)))
3854 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3855 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3856 if (IS_SYMOP (IC_RESULT (ic)))
3857 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3858 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3861 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3865 /* if the condition of an if instruction
3866 is defined in the previous instruction then
3867 mark the itemp as a conditional */
3868 if ((IS_CONDITIONAL (ic) ||
3869 ((ic->op == BITWISEAND ||
3872 isBitwiseOptimizable (ic))) &&
3873 ic->next && ic->next->op == IFX &&
3874 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3875 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3878 debugLog (" %d\n", __LINE__);
3879 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3883 /* reduce for support function calls */
3884 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3885 packRegsForSupport (ic, ebp);
3887 /* if a parameter is passed, it's in W, so we may not
3888 need to place a copy in a register */
3889 if (ic->op == RECEIVE)
3890 packForReceive (ic, ebp);
3892 /* some cases the redundant moves can
3893 can be eliminated for return statements */
3894 if ((ic->op == RETURN || ic->op == SEND) &&
3895 !isOperandInFarSpace (IC_LEFT (ic)) &&
3897 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3899 /* if pointer set & left has a size more than
3900 one and right is not in far space */
3901 if (POINTER_SET (ic) &&
3902 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3903 IS_SYMOP(IC_RESULT(ic)) &&
3904 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3905 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3906 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3908 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3910 /* if pointer get */
3911 if (POINTER_GET (ic) &&
3912 !isOperandInFarSpace (IC_RESULT (ic)) &&
3913 IS_SYMOP(IC_LEFT(ic)) &&
3914 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3915 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3916 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3918 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3921 /* if this is cast for intergral promotion then
3922 check if only use of the definition of the
3923 operand being casted/ if yes then replace
3924 the result of that arithmetic operation with
3925 this result and get rid of the cast */
3926 if (ic->op == CAST) {
3928 sym_link *fromType = operandType (IC_RIGHT (ic));
3929 sym_link *toType = operandType (IC_LEFT (ic));
3931 debugLog (" %d - casting\n", __LINE__);
3933 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3934 getSize (fromType) != getSize (toType)) {
3937 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3940 if (IS_ARITHMETIC_OP (dic)) {
3942 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3943 IC_RESULT (dic) = IC_RESULT (ic);
3944 remiCodeFromeBBlock (ebp, ic);
3945 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3946 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3947 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3951 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3955 /* if the type from and type to are the same
3956 then if this is the only use then packit */
3957 if (compareType (operandType (IC_RIGHT (ic)),
3958 operandType (IC_LEFT (ic))) == 1) {
3960 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3963 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3964 IC_RESULT (dic) = IC_RESULT (ic);
3965 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3966 remiCodeFromeBBlock (ebp, ic);
3967 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3968 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3976 iTempNN := (some variable in farspace) V1
3981 if (ic->op == IPUSH)
3983 packForPush (ic, ebp);
3987 /* pack registers for accumulator use, when the
3988 result of an arithmetic or bit wise operation
3989 has only one use, that use is immediately following
3990 the defintion and the using iCode has only one
3991 operand or has two operands but one is literal &
3992 the result of that operation is not on stack then
3993 we can leave the result of this operation in acc:b
3995 if ((IS_ARITHMETIC_OP (ic)
3997 || IS_BITWISE_OP (ic)
3999 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4002 IS_ITEMP (IC_RESULT (ic)) &&
4003 getSize (operandType (IC_RESULT (ic))) <= 2)
4005 packRegsForAccUse (ic);
4011 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4015 if (!debug || !debugF)
4018 for (i = 0; i < count; i++)
4020 fprintf (debugF, "\n----------------------------------------------------------------\n");
4021 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4022 ebbs[i]->entryLabel->name,
4025 ebbs[i]->isLastInLoop);
4026 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4031 fprintf (debugF, "visited %d : hasFcall = %d\n",
4035 fprintf (debugF, "\ndefines bitVector :");
4036 bitVectDebugOn (ebbs[i]->defSet, debugF);
4037 fprintf (debugF, "\nlocal defines bitVector :");
4038 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4039 fprintf (debugF, "\npointers Set bitvector :");
4040 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4041 fprintf (debugF, "\nin pointers Set bitvector :");
4042 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4043 fprintf (debugF, "\ninDefs Set bitvector :");
4044 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4045 fprintf (debugF, "\noutDefs Set bitvector :");
4046 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4047 fprintf (debugF, "\nusesDefs Set bitvector :");
4048 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4049 fprintf (debugF, "\n----------------------------------------------------------------\n");
4050 printiCChain (ebbs[i]->sch, debugF);
4053 /*-----------------------------------------------------------------*/
4054 /* assignRegisters - assigns registers to each live range as need */
4055 /*-----------------------------------------------------------------*/
4057 pic14_assignRegisters (ebbIndex * ebbi)
4059 eBBlock ** ebbs = ebbi->bbOrder;
4060 int count = ebbi->count;
4064 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4065 debugLog ("ebbs before optimizing:\n");
4066 dumpEbbsToDebug (ebbs, count);
4068 setToNull ((void *) &_G.funcrUsed);
4069 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4072 /* change assignments this will remove some
4073 live ranges reducing some register pressure */
4074 for (i = 0; i < count; i++)
4075 packRegisters (ebbs[i]);
4082 debugLog("dir registers allocated so far:\n");
4083 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4086 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4087 reg = hTabNextItem(dynDirectRegNames, &hkey);
4092 if (options.dump_pack)
4093 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4095 /* first determine for each live range the number of
4096 registers & the type of registers required for each */
4099 /* and serially allocate registers */
4100 serialRegAssign (ebbs, count);
4102 /* if stack was extended then tell the user */
4105 /* werror(W_TOOMANY_SPILS,"stack", */
4106 /* _G.stackExtend,currFunc->name,""); */
4112 /* werror(W_TOOMANY_SPILS,"data space", */
4113 /* _G.dataExtend,currFunc->name,""); */
4117 /* after that create the register mask
4118 for each of the instruction */
4119 createRegMask (ebbs, count);
4121 /* redo that offsets for stacked automatic variables */
4122 redoStackOffsets ();
4124 if (options.dump_rassgn)
4125 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4127 /* now get back the chain */
4128 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4130 debugLog ("ebbs after optimizing:\n");
4131 dumpEbbsToDebug (ebbs, count);
4136 /* free up any _G.stackSpil locations allocated */
4137 applyToSet (_G.stackSpil, deallocStackSpil);
4139 setToNull ((void *) &_G.stackSpil);
4140 setToNull ((void *) &_G.spiltSet);
4141 /* mark all registers as free */
4142 //pic14_freeAllRegs ();
4144 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4145 pic14_debugLogClose ();