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 -------------------------------------------------------------------------*/
32 set *dynAllocRegs=NULL;
33 set *dynStackRegs=NULL;
34 set *dynProcessorRegs=NULL;
35 set *dynDirectRegs=NULL;
36 set *dynDirectBitRegs=NULL;
37 set *dynInternalRegs=NULL;
40 #define FENTRY2 1 ? (void)0 : printf
42 /* this should go in SDCCicode.h, but it doesn't. */
43 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
45 /*-----------------------------------------------------------------*/
46 /* At this point we start getting processor specific although */
47 /* some routines are non-processor specific & can be reused when */
48 /* targetting other processors. The decision for this will have */
49 /* to be made on a routine by routine basis */
50 /* routines used to pack registers are most definitely not reusable */
51 /* since the pack the registers depending strictly on the MCU */
52 /*-----------------------------------------------------------------*/
62 bitVect *funcrUsed; /* registers used in a function */
68 static int pic14_ptrRegReq; /* one byte pointer register required */
70 static hTab *dynDirectRegNames= NULL;
71 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
73 static int dynrIdx = 0x1000;
75 int Gstack_base_addr=0; /* The starting address of registers that
76 * are used to pass and return parameters */
77 static int Gstack_size = 0;
79 static int debug = 0; // should be 0 when committed, creates .d files
80 static FILE *debugF = NULL;
82 /*-----------------------------------------------------------------*/
83 /* debugLog - open a file for debugging information */
84 /*-----------------------------------------------------------------*/
86 debugLog (char *fmt,...)
88 static int append = 0; // First time through, open the file without append.
91 //char *bufferP=buffer;
94 if (!debug || !dstFileName)
100 /* create the file name */
101 strcpy (buffer, dstFileName);
102 strcat (buffer, ".d");
104 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
106 werror (E_FILE_OPEN_ERR, buffer);
109 append = 1; // Next time debugLog is called, we'll append the debug info
114 vsprintf (buffer, fmt, ap);
117 fprintf (debugF, "%s", buffer);
118 //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
125 fputc ('\n', debugF);
127 /*-----------------------------------------------------------------*/
128 /* pic14_debugLogClose - closes the debug log file (if opened) */
129 /*-----------------------------------------------------------------*/
131 pic14_debugLogClose (void)
141 debugAopGet (char *str, operand * op)
143 if (!debug) return NULL;
145 if (str) debugLog (str);
147 printOperand (op, debugF);
154 decodeOp (unsigned int op)
157 if (op < 128 && op > ' ')
159 buffer[0] = (op & 0xff);
166 case IDENTIFIER: return "IDENTIFIER";
167 case TYPE_NAME: return "TYPE_NAME";
168 case CONSTANT: return "CONSTANT";
169 case STRING_LITERAL: return "STRING_LITERAL";
170 case SIZEOF: return "SIZEOF";
171 case PTR_OP: return "PTR_OP";
172 case INC_OP: return "INC_OP";
173 case DEC_OP: return "DEC_OP";
174 case LEFT_OP: return "LEFT_OP";
175 case RIGHT_OP: return "RIGHT_OP";
176 case LE_OP: return "LE_OP";
177 case GE_OP: return "GE_OP";
178 case EQ_OP: return "EQ_OP";
179 case NE_OP: return "NE_OP";
180 case AND_OP: return "AND_OP";
181 case OR_OP: return "OR_OP";
182 case MUL_ASSIGN: return "MUL_ASSIGN";
183 case DIV_ASSIGN: return "DIV_ASSIGN";
184 case MOD_ASSIGN: return "MOD_ASSIGN";
185 case ADD_ASSIGN: return "ADD_ASSIGN";
186 case SUB_ASSIGN: return "SUB_ASSIGN";
187 case LEFT_ASSIGN: return "LEFT_ASSIGN";
188 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
189 case AND_ASSIGN: return "AND_ASSIGN";
190 case XOR_ASSIGN: return "XOR_ASSIGN";
191 case OR_ASSIGN: return "OR_ASSIGN";
192 case TYPEDEF: return "TYPEDEF";
193 case EXTERN: return "EXTERN";
194 case STATIC: return "STATIC";
195 case AUTO: return "AUTO";
196 case REGISTER: return "REGISTER";
197 case CODE: return "CODE";
198 case EEPROM: return "EEPROM";
199 case INTERRUPT: return "INTERRUPT";
200 case SFR: return "SFR";
201 case AT: return "AT";
202 case SBIT: return "SBIT";
203 case REENTRANT: return "REENTRANT";
204 case USING: return "USING";
205 case XDATA: return "XDATA";
206 case DATA: return "DATA";
207 case IDATA: return "IDATA";
208 case PDATA: return "PDATA";
209 case VAR_ARGS: return "VAR_ARGS";
210 case CRITICAL: return "CRITICAL";
211 case NONBANKED: return "NONBANKED";
212 case BANKED: return "BANKED";
213 case CHAR: return "CHAR";
214 case SHORT: return "SHORT";
215 case INT: return "INT";
216 case LONG: return "LONG";
217 case SIGNED: return "SIGNED";
218 case UNSIGNED: return "UNSIGNED";
219 case FLOAT: return "FLOAT";
220 case DOUBLE: return "DOUBLE";
221 case CONST: return "CONST";
222 case VOLATILE: return "VOLATILE";
223 case VOID: return "VOID";
224 case BIT: return "BIT";
225 case STRUCT: return "STRUCT";
226 case UNION: return "UNION";
227 case ENUM: return "ENUM";
228 case RANGE: return "RANGE";
229 case FAR: return "FAR";
230 case CASE: return "CASE";
231 case DEFAULT: return "DEFAULT";
232 case IF: return "IF";
233 case ELSE: return "ELSE";
234 case SWITCH: return "SWITCH";
235 case WHILE: return "WHILE";
236 case DO: return "DO";
237 case FOR: return "FOR";
238 case GOTO: return "GOTO";
239 case CONTINUE: return "CONTINUE";
240 case BREAK: return "BREAK";
241 case RETURN: return "RETURN";
242 case INLINEASM: return "INLINEASM";
243 case IFX: return "IFX";
244 case ADDRESS_OF: return "ADDRESS_OF";
245 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
246 case SPIL: return "SPIL";
247 case UNSPIL: return "UNSPIL";
248 case GETHBIT: return "GETHBIT";
249 case BITWISEAND: return "BITWISEAND";
250 case UNARYMINUS: return "UNARYMINUS";
251 case IPUSH: return "IPUSH";
252 case IPOP: return "IPOP";
253 case PCALL: return "PCALL";
254 case ENDFUNCTION: return "ENDFUNCTION";
255 case JUMPTABLE: return "JUMPTABLE";
256 case RRC: return "RRC";
257 case RLC: return "RLC";
258 case CAST: return "CAST";
259 case CALL: return "CALL";
260 case PARAM: return "PARAM ";
261 case NULLOP: return "NULLOP";
262 case BLOCK: return "BLOCK";
263 case LABEL: return "LABEL";
264 case RECEIVE: return "RECEIVE";
265 case SEND: return "SEND";
267 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
270 /*-----------------------------------------------------------------*/
271 /*-----------------------------------------------------------------*/
273 debugLogRegType (short type)
278 case REG_GPR: return "REG_GPR";
279 case REG_PTR: return "REG_PTR";
280 case REG_CND: return "REG_CND";
283 sprintf (buffer, "unknown reg type %d", type);
287 /*-----------------------------------------------------------------*/
288 /*-----------------------------------------------------------------*/
289 static int regname2key(char const *name)
298 key += (*name++) + 1;
302 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
306 /*-----------------------------------------------------------------*/
307 /* regWithIdx - Search through a set of registers that matches idx */
308 /*-----------------------------------------------------------------*/
310 regWithIdx (set *dRegs, int idx, int fixed)
314 for (dReg = setFirstItem(dRegs) ; dReg ;
315 dReg = setNextItem(dRegs)) {
317 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
318 while (dReg->reg_alias) dReg = dReg->reg_alias;
326 /*-----------------------------------------------------------------*/
327 /* newReg - allocate and init memory for a new register */
328 /*-----------------------------------------------------------------*/
329 static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
332 regs *dReg, *reg_alias;
334 /* check whether a matching register already exists */
335 dReg = dirregWithName( name );
337 //printf( "%s: already present: %s\n", __FUNCTION__, name );
341 // check whether a register at that location exists
342 reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
343 if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
345 // create a new register
346 dReg = Safe_calloc(1,sizeof(regs));
348 dReg->pc_type = pc_type;
351 dReg->name = Safe_strdup(name);
353 sprintf(buffer,"r0x%02X", dReg->rIdx);
354 dReg->name = Safe_strdup(buffer);
370 dReg->reg_alias = reg_alias;
371 dReg->reglives.usedpFlows = newSet();
372 dReg->reglives.assignedpFlows = newSet();
373 if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
374 debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
379 /*-----------------------------------------------------------------*/
380 /* regWithName - Search through a set of registers that matches name */
381 /*-----------------------------------------------------------------*/
383 regWithName (set *dRegs, const char *name)
387 for (dReg = setFirstItem(dRegs) ; dReg ;
388 dReg = setNextItem(dRegs)) {
390 if((strcmp(name,dReg->name)==0)) {
398 /*-----------------------------------------------------------------*/
399 /* regWithName - Search for a registers that matches name */
400 /*-----------------------------------------------------------------*/
402 regFindWithName (const char *name)
406 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
407 debugLog ("Found a Direct Register!\n");
410 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
411 debugLog ("Found a Direct Bit Register!\n");
415 if (*name=='_') name++; // Step passed '_'
417 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
418 debugLog ("Found a Dynamic Register!\n");
421 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
422 debugLog ("Found a Processor Register!\n");
425 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
426 debugLog ("Found an Internal Register!\n");
429 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
430 debugLog ("Found an Stack Register!\n");
437 /*-----------------------------------------------------------------*/
438 /* regFindFree - Search for a free register in a set of registers */
439 /*-----------------------------------------------------------------*/
441 regFindFree (set *dRegs)
445 for (dReg = setFirstItem(dRegs) ; dReg ;
446 dReg = setNextItem(dRegs)) {
454 /*-----------------------------------------------------------------*/
455 /* initStack - allocate registers for a pseudo stack */
456 /*-----------------------------------------------------------------*/
457 void initStack(int base_address, int size, int shared)
463 pic = pic14_getPIC();
464 Gstack_base_addr = base_address;
466 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
468 for(i = 0; i<size; i++) {
471 SNPRINTF(&buffer[0], 16, "STK%02d", i);
472 // multi-bank device, sharebank prohibited by user
473 r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
478 addSet(&dynStackRegs,r);
482 /*-----------------------------------------------------------------*
483 *-----------------------------------------------------------------*/
485 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
488 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
489 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
492 /*-----------------------------------------------------------------*
493 *-----------------------------------------------------------------*/
496 allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
498 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
500 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
503 return addSet(&dynInternalRegs,reg);
508 /*-----------------------------------------------------------------*/
509 /* allocReg - allocates register of given type */
510 /*-----------------------------------------------------------------*/
512 allocReg (short type)
516 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
517 //fprintf(stderr,"allocReg\n");
519 reg = pic14_findFreeReg (type);
527 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
532 /*-----------------------------------------------------------------*/
533 /* dirregWithName - search for register by name */
534 /*-----------------------------------------------------------------*/
536 dirregWithName (char *name)
544 /* hash the name to get a key */
546 hkey = regname2key(name);
548 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
552 if(STRCASECMP(reg->name, name) == 0) {
553 // handle registers with multiple names
554 while (reg->reg_alias) reg = reg->reg_alias;
558 reg = hTabNextItemWK (dynDirectRegNames);
562 return NULL; // name wasn't found in the hash table
565 /*-----------------------------------------------------------------*/
566 /* allocNewDirReg - allocates a new register of given type */
567 /*-----------------------------------------------------------------*/
569 allocNewDirReg (sym_link *symlnk,const char *name)
573 sym_link *spec = getSpec (symlnk);
575 /* if this is at an absolute address, then get the address. */
576 if (SPEC_ABSA (spec) ) {
577 address = SPEC_ADDR (spec);
578 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
581 /* Register wasn't found in hash, so let's create
582 * a new one and put it in the hash table AND in the
583 * dynDirectRegNames set */
584 if (IS_CONFIG_ADDRESS(address)) {
585 debugLog (" -- %s is declared at address 0x2007\n",name);
590 if (IS_BITVAR (spec))
597 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
598 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
600 if (SPEC_ABSA (spec) ) {
604 if (IS_BITVAR (spec)) {
605 addSet(&dynDirectBitRegs, reg);
608 addSet(&dynDirectRegs, reg);
610 if (!IS_STATIC (spec)) {
613 if (IS_EXTERN (spec)) {
619 if (address && reg) {
621 reg->address = address;
622 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
628 /*-----------------------------------------------------------------*/
629 /* allocDirReg - allocates register of given type */
630 /*-----------------------------------------------------------------*/
632 allocDirReg (operand *op )
639 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
643 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
645 /* If the symbol is at a fixed address, then remove the leading underscore
646 * from the name. This is hack to allow the .asm include file named registers
647 * to match the .c declared register names */
649 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
652 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
654 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
655 debugLog(" %d const char\n",__LINE__);
656 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
659 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
660 if (IS_CODE ( OP_SYM_ETYPE(op)) )
661 debugLog(" %d code space\n",__LINE__);
663 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
664 debugLog(" %d integral\n",__LINE__);
665 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
666 debugLog(" %d literal\n",__LINE__);
667 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
668 debugLog(" %d specifier\n",__LINE__);
669 debugAopGet(NULL, op);
672 if (IS_CODE ( OP_SYM_ETYPE(op)) )
675 /* First, search the hash table to see if there is a register with this name */
676 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
677 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
680 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
681 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
683 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
684 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
687 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
689 reg = dirregWithName(name);
696 /* if this is at an absolute address, then get the address. */
697 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
698 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
699 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
702 /* Register wasn't found in hash, so let's create
703 * a new one and put it in the hash table AND in the
704 * dynDirectRegNames set */
705 if(!IS_CONFIG_ADDRESS(address)) {
706 //fprintf(stderr,"allocating new reg %s\n",name);
708 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
709 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
711 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
713 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
715 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
719 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
720 addSet(&dynDirectBitRegs, reg);
723 addSet(&dynDirectRegs, reg);
725 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
728 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
734 debugLog (" -- %s is declared at address 0x2007\n",name);
739 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
741 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
742 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
747 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
749 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
750 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
753 allocNewDirReg (OP_SYM_TYPE(op),name);
760 /*-----------------------------------------------------------------*/
761 /* allocRegByName - allocates register with given name */
762 /*-----------------------------------------------------------------*/
764 allocRegByName (char *name, int size)
770 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
774 /* First, search the hash table to see if there is a register with this name */
775 reg = dirregWithName(name);
781 /* Register wasn't found in hash, so let's create
782 * a new one and put it in the hash table AND in the
783 * dynDirectRegNames set */
784 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
785 reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
786 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
787 if (strcmp(reg->name+1,sym->name)==0) {
788 unsigned a = SPEC_ADDR(sym->etype);
792 if (!IS_STATIC (sym->etype)) {
795 if (IS_EXTERN (sym->etype)) {
798 if (IS_BITVAR (sym->etype))
805 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
806 if (strcmp(reg->name+1,sym->name)==0) {
807 unsigned a = SPEC_ADDR(sym->etype);
809 if (!IS_STATIC (sym->etype)) {
812 if (IS_EXTERN (sym->etype)) {
815 if (IS_BITVAR (sym->etype))
823 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
825 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
826 if (reg->isBitField) {
827 addSet(&dynDirectBitRegs, reg);
829 addSet(&dynDirectRegs, reg);
835 /*-----------------------------------------------------------------*/
836 /* RegWithIdx - returns pointer to register with index number */
837 /*-----------------------------------------------------------------*/
839 typeRegWithIdx (int idx, int type, int fixed)
844 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
849 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
851 debugLog ("Found a Dynamic Register!\n");
854 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
855 debugLog ("Found a Direct Register!\n");
861 if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
862 debugLog ("Found a Stack Register!\n");
865 if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
866 debugLog ("Found a Stack Register!\n");
870 werror (E_STACK_OUT, "Register");
871 /* return an existing register just to avoid the SDCC crash */
872 return regWithIdx ( dynStackRegs, 0x7f, 0);
876 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
877 debugLog ("Found a Processor Register!\n");
891 /*-----------------------------------------------------------------*/
892 /* pic14_regWithIdx - returns pointer to register with index number*/
893 /*-----------------------------------------------------------------*/
895 pic14_regWithIdx (int idx)
899 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
902 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
908 /*-----------------------------------------------------------------*/
909 /* pic14_regWithIdx - returns pointer to register with index number */
910 /*-----------------------------------------------------------------*/
912 pic14_allocWithIdx (int idx)
917 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
919 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
921 debugLog ("Found a Dynamic Register!\n");
922 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
923 debugLog ("Found a Stack Register!\n");
924 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
925 debugLog ("Found a Processor Register!\n");
926 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
927 debugLog ("Found an Internal Register!\n");
928 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
929 debugLog ("Found an Internal Register!\n");
932 debugLog ("Dynamic Register not found\n");
935 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
936 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
937 "regWithIdx not found");
947 /*-----------------------------------------------------------------*/
948 /*-----------------------------------------------------------------*/
950 pic14_findFreeReg(short type)
957 if((dReg = regFindFree(dynAllocRegs)) != NULL)
959 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
963 if((dReg = regFindFree(dynStackRegs)) != NULL)
975 /*-----------------------------------------------------------------*/
976 /* freeReg - frees a register */
977 /*-----------------------------------------------------------------*/
981 debugLog ("%s\n", __FUNCTION__);
986 /*-----------------------------------------------------------------*/
987 /* nFreeRegs - returns number of free registers */
988 /*-----------------------------------------------------------------*/
992 /* dynamically allocate as many as we need and worry about
993 * fitting them into a PIC later */
1000 debugLog ("%s\n", __FUNCTION__);
1001 for (i = 0; i < pic14_nRegs; i++)
1002 if (regspic14[i].isFree && regspic14[i].type == type)
1008 /*-----------------------------------------------------------------*/
1009 /* nfreeRegsType - free registers with type */
1010 /*-----------------------------------------------------------------*/
1012 nfreeRegsType (int type)
1015 debugLog ("%s\n", __FUNCTION__);
1016 if (type == REG_PTR)
1018 if ((nfr = nFreeRegs (type)) == 0)
1019 return nFreeRegs (REG_GPR);
1022 return nFreeRegs (type);
1026 static void writeSetUsedRegs(FILE *of, set *dRegs)
1031 for (dReg = setFirstItem(dRegs) ; dReg ;
1032 dReg = setNextItem(dRegs)) {
1035 fprintf (of, "\t%s\n",dReg->name);
1041 static void packBits(set *bregs)
1045 regs *bitfield=NULL;
1046 regs *relocbitfield=NULL;
1052 for (regset = bregs ; regset ;
1053 regset = regset->next) {
1055 breg = regset->item;
1056 breg->isBitField = 1;
1057 //fprintf(stderr,"bit reg: %s\n",breg->name);
1060 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1062 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1063 breg->rIdx = breg->address & 7;
1064 breg->address >>= 3;
1067 //sprintf (buffer, "fbitfield%02x", breg->address);
1068 sprintf (buffer, "0x%02x", breg->address);
1069 //fprintf(stderr,"new bit field\n");
1070 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1071 bitfield->isBitField = 1;
1072 bitfield->isFixed = 1;
1073 bitfield->address = breg->address;
1074 //addSet(&dynDirectRegs,bitfield);
1075 addSet(&dynInternalRegs,bitfield);
1076 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1078 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1081 breg->reg_alias = bitfield;
1085 if(!relocbitfield || bit_no >7) {
1088 sprintf (buffer, "bitfield%d", byte_no);
1089 //fprintf(stderr,"new relocatable bit field\n");
1090 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
1091 relocbitfield->isBitField = 1;
1092 //addSet(&dynDirectRegs,relocbitfield);
1093 addSet(&dynInternalRegs,relocbitfield);
1094 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1098 breg->reg_alias = relocbitfield;
1099 breg->address = dynrIdx; /* byte_no; */
1100 breg->rIdx = bit_no++;
1108 static void bitEQUs(FILE *of, set *bregs)
1110 regs *breg,*bytereg;
1113 //fprintf(stderr," %s\n",__FUNCTION__);
1114 for (breg = setFirstItem(bregs) ; breg ;
1115 breg = setNextItem(bregs)) {
1117 //fprintf(stderr,"bit reg: %s\n",breg->name);
1119 bytereg = breg->reg_alias;
1121 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1124 breg->rIdx & 0x0007);
1127 //fprintf(stderr, "bit field is not assigned to a register\n");
1128 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1140 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1145 for (reg = setFirstItem(fregs) ; reg ;
1146 reg = setNextItem(fregs)) {
1150 fprintf (of, "%s\tEQU\t0x%03x\n",
1154 fprintf (of, "%s\tEQU\t0x%03x\n",
1163 void writeUsedRegs(FILE *of)
1166 packBits(dynDirectBitRegs);
1168 bitEQUs(of,dynDirectBitRegs);
1171 /*-----------------------------------------------------------------*/
1172 /* computeSpillable - given a point find the spillable live ranges */
1173 /*-----------------------------------------------------------------*/
1175 computeSpillable (iCode * ic)
1179 debugLog ("%s\n", __FUNCTION__);
1180 /* spillable live ranges are those that are live at this
1181 point . the following categories need to be subtracted
1183 a) - those that are already spilt
1184 b) - if being used by this one
1185 c) - defined by this one */
1187 spillable = bitVectCopy (ic->rlive);
1189 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1191 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1192 bitVectUnSetBit (spillable, ic->defKey);
1193 spillable = bitVectIntersect (spillable, _G.regAssigned);
1198 /*-----------------------------------------------------------------*/
1199 /* noSpilLoc - return true if a variable has no spil location */
1200 /*-----------------------------------------------------------------*/
1202 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1204 debugLog ("%s\n", __FUNCTION__);
1205 return (sym->usl.spillLoc ? 0 : 1);
1208 /*-----------------------------------------------------------------*/
1209 /* hasSpilLoc - will return 1 if the symbol has spil location */
1210 /*-----------------------------------------------------------------*/
1212 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1214 debugLog ("%s\n", __FUNCTION__);
1215 return (sym->usl.spillLoc ? 1 : 0);
1218 /*-----------------------------------------------------------------*/
1219 /* directSpilLoc - will return 1 if the splilocation is in direct */
1220 /*-----------------------------------------------------------------*/
1222 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1224 debugLog ("%s\n", __FUNCTION__);
1225 if (sym->usl.spillLoc &&
1226 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1232 /*-----------------------------------------------------------------*/
1233 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1234 /* but is not used as a pointer */
1235 /*-----------------------------------------------------------------*/
1237 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1239 debugLog ("%s\n", __FUNCTION__);
1240 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1243 /*-----------------------------------------------------------------*/
1244 /* rematable - will return 1 if the remat flag is set */
1245 /*-----------------------------------------------------------------*/
1247 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1249 debugLog ("%s\n", __FUNCTION__);
1253 /*-----------------------------------------------------------------*/
1254 /* notUsedInRemaining - not used or defined in remain of the block */
1255 /*-----------------------------------------------------------------*/
1257 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1259 debugLog ("%s\n", __FUNCTION__);
1260 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1261 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1264 /*-----------------------------------------------------------------*/
1265 /* allLRs - return true for all */
1266 /*-----------------------------------------------------------------*/
1268 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1270 debugLog ("%s\n", __FUNCTION__);
1274 /*-----------------------------------------------------------------*/
1275 /* liveRangesWith - applies function to a given set of live range */
1276 /*-----------------------------------------------------------------*/
1278 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1279 eBBlock * ebp, iCode * ic)
1284 debugLog ("%s\n", __FUNCTION__);
1285 if (!lrs || !lrs->size)
1288 for (i = 1; i < lrs->size; i++)
1291 if (!bitVectBitValue (lrs, i))
1294 /* if we don't find it in the live range
1295 hash table we are in serious trouble */
1296 if (!(sym = hTabItemWithKey (liveRanges, i)))
1298 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1299 "liveRangesWith could not find liveRange");
1303 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1304 addSetHead (&rset, sym);
1311 /*-----------------------------------------------------------------*/
1312 /* leastUsedLR - given a set determines which is the least used */
1313 /*-----------------------------------------------------------------*/
1315 leastUsedLR (set * sset)
1317 symbol *sym = NULL, *lsym = NULL;
1319 debugLog ("%s\n", __FUNCTION__);
1320 sym = lsym = setFirstItem (sset);
1325 for (; lsym; lsym = setNextItem (sset))
1328 /* if usage is the same then prefer
1329 the spill the smaller of the two */
1330 if (lsym->used == sym->used)
1331 if (getSize (lsym->type) < getSize (sym->type))
1335 if (lsym->used < sym->used)
1340 setToNull ((void *) &sset);
1345 /*-----------------------------------------------------------------*/
1346 /* noOverLap - will iterate through the list looking for over lap */
1347 /*-----------------------------------------------------------------*/
1349 noOverLap (set * itmpStack, symbol * fsym)
1352 debugLog ("%s\n", __FUNCTION__);
1355 for (sym = setFirstItem (itmpStack); sym;
1356 sym = setNextItem (itmpStack))
1358 if (sym->liveTo > fsym->liveFrom)
1366 /*-----------------------------------------------------------------*/
1367 /* isFree - will return 1 if the a free spil location is found */
1368 /*-----------------------------------------------------------------*/
1373 V_ARG (symbol **, sloc);
1374 V_ARG (symbol *, fsym);
1376 debugLog ("%s\n", __FUNCTION__);
1377 /* if already found */
1381 /* if it is free && and the itmp assigned to
1382 this does not have any overlapping live ranges
1383 with the one currently being assigned and
1384 the size can be accomodated */
1386 noOverLap (sym->usl.itmpStack, fsym) &&
1387 getSize (sym->type) >= getSize (fsym->type))
1396 /*-----------------------------------------------------------------*/
1397 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1398 /*-----------------------------------------------------------------*/
1400 spillLRWithPtrReg (symbol * forSym)
1405 debugLog ("%s\n", __FUNCTION__);
1406 if (!_G.regAssigned ||
1407 bitVectIsZero (_G.regAssigned))
1410 /* for all live ranges */
1411 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1412 lrsym = hTabNextItem (liveRanges, &k))
1414 /* if no registers assigned to it or
1416 /* if it does not overlap with this then
1417 not need to spill it */
1419 if (lrsym->isspilt || !lrsym->nRegs ||
1420 (lrsym->liveTo < forSym->liveFrom))
1427 /*-----------------------------------------------------------------*/
1428 /* createStackSpil - create a location on the stack to spil */
1429 /*-----------------------------------------------------------------*/
1431 createStackSpil (symbol * sym)
1433 symbol *sloc = NULL;
1434 int useXstack, model, noOverlay;
1436 char slocBuffer[30];
1437 debugLog ("%s\n", __FUNCTION__);
1441 /* first go try and find a free one that is already
1442 existing on the stack */
1443 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1445 /* found a free one : just update & return */
1446 sym->usl.spillLoc = sloc;
1449 addSetHead (&sloc->usl.itmpStack, sym);
1453 /* could not then have to create one , this is the hard part
1454 we need to allocate this on the stack : this is really a
1455 hack!! but cannot think of anything better at this time */
1457 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1459 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1460 __FILE__, __LINE__);
1464 sloc = newiTemp (slocBuffer);
1466 /* set the type to the spilling symbol */
1467 sloc->type = copyLinkChain (sym->type);
1468 sloc->etype = getSpec (sloc->type);
1469 SPEC_SCLS (sloc->etype) = S_DATA;
1470 SPEC_EXTR (sloc->etype) = 0;
1471 SPEC_STAT (sloc->etype) = 0;
1473 /* we don't allow it to be allocated`
1474 onto the external stack since : so we
1475 temporarily turn it off ; we also
1476 turn off memory model to prevent
1477 the spil from going to the external storage
1478 and turn off overlaying
1481 useXstack = options.useXstack;
1482 model = options.model;
1483 noOverlay = options.noOverlay;
1484 options.noOverlay = 1;
1485 options.model = options.useXstack = 0;
1489 options.useXstack = useXstack;
1490 options.model = model;
1491 options.noOverlay = noOverlay;
1492 sloc->isref = 1; /* to prevent compiler warning */
1494 /* if it is on the stack then update the stack */
1495 if (IN_STACK (sloc->etype))
1497 currFunc->stack += getSize (sloc->type);
1498 _G.stackExtend += getSize (sloc->type);
1501 _G.dataExtend += getSize (sloc->type);
1503 /* add it to the _G.stackSpil set */
1504 addSetHead (&_G.stackSpil, sloc);
1505 sym->usl.spillLoc = sloc;
1508 /* add it to the set of itempStack set
1509 of the spill location */
1510 addSetHead (&sloc->usl.itmpStack, sym);
1514 /*-----------------------------------------------------------------*/
1515 /* isSpiltOnStack - returns true if the spil location is on stack */
1516 /*-----------------------------------------------------------------*/
1518 isSpiltOnStack (symbol * sym)
1522 debugLog ("%s\n", __FUNCTION__);
1531 /* if (sym->_G.stackSpil) */
1534 if (!sym->usl.spillLoc)
1537 etype = getSpec (sym->usl.spillLoc->type);
1538 if (IN_STACK (etype))
1544 /*-----------------------------------------------------------------*/
1545 /* spillThis - spils a specific operand */
1546 /*-----------------------------------------------------------------*/
1548 spillThis (symbol * sym)
1551 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1552 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1554 /* if this is rematerializable or has a spillLocation
1555 we are okay, else we need to create a spillLocation
1557 if (!(sym->remat || sym->usl.spillLoc))
1558 createStackSpil (sym);
1561 /* mark it has spilt & put it in the spilt set */
1563 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1565 bitVectUnSetBit (_G.regAssigned, sym->key);
1567 for (i = 0; i < sym->nRegs; i++)
1571 freeReg (sym->regs[i]);
1572 sym->regs[i] = NULL;
1576 /* if spilt on stack then free up r0 & r1
1577 if they could have been assigned to some
1579 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1582 spillLRWithPtrReg (sym);
1585 if (sym->usl.spillLoc && !sym->remat)
1586 sym->usl.spillLoc->allocreq = 1;
1591 /*-----------------------------------------------------------------*/
1592 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1593 /*-----------------------------------------------------------------*/
1595 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1597 bitVect *lrcs = NULL;
1601 debugLog ("%s\n", __FUNCTION__);
1603 /* get the spillable live ranges */
1604 lrcs = computeSpillable (ic);
1607 /* get all live ranges that are rematerizable */
1608 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1610 /* return the least used of these */
1611 return leastUsedLR (selectS);
1614 /* get live ranges with spillLocations in direct space */
1615 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1617 sym = leastUsedLR (selectS);
1618 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1619 sym->usl.spillLoc->rname :
1620 sym->usl.spillLoc->name));
1622 /* mark it as allocation required */
1623 sym->usl.spillLoc->allocreq = 1;
1627 /* if the symbol is local to the block then */
1628 if (forSym->liveTo < ebp->lSeq)
1631 /* check if there are any live ranges allocated
1632 to registers that are not used in this block */
1633 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1635 sym = leastUsedLR (selectS);
1636 /* if this is not rematerializable */
1645 /* check if there are any live ranges that not
1646 used in the remainder of the block */
1647 if (!_G.blockSpil &&
1648 !isiCodeInFunctionCall (ic) &&
1649 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1651 sym = leastUsedLR (selectS);
1654 sym->remainSpil = 1;
1661 /* find live ranges with spillocation && not used as pointers */
1662 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1665 sym = leastUsedLR (selectS);
1666 /* mark this as allocation required */
1667 sym->usl.spillLoc->allocreq = 1;
1671 /* find live ranges with spillocation */
1672 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1675 sym = leastUsedLR (selectS);
1676 sym->usl.spillLoc->allocreq = 1;
1680 /* couldn't find then we need to create a spil
1681 location on the stack , for which one? the least
1683 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1686 /* return a created spil location */
1687 sym = createStackSpil (leastUsedLR (selectS));
1688 sym->usl.spillLoc->allocreq = 1;
1692 /* this is an extreme situation we will spill
1693 this one : happens very rarely but it does happen */
1699 /*-----------------------------------------------------------------*/
1700 /* spilSomething - spil some variable & mark registers as free */
1701 /*-----------------------------------------------------------------*/
1703 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1708 debugLog ("%s\n", __FUNCTION__);
1709 /* get something we can spil */
1710 ssym = selectSpil (ic, ebp, forSym);
1712 /* mark it as spilt */
1714 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1716 /* mark it as not register assigned &
1717 take it away from the set */
1718 bitVectUnSetBit (_G.regAssigned, ssym->key);
1720 /* mark the registers as free */
1721 for (i = 0; i < ssym->nRegs; i++)
1723 freeReg (ssym->regs[i]);
1725 /* if spilt on stack then free up r0 & r1
1726 if they could have been assigned to as gprs */
1727 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1730 spillLRWithPtrReg (ssym);
1733 /* if this was a block level spil then insert push & pop
1734 at the start & end of block respectively */
1735 if (ssym->blockSpil)
1737 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1738 /* add push to the start of the block */
1739 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1740 ebp->sch->next : ebp->sch));
1741 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1742 /* add pop to the end of the block */
1743 addiCodeToeBBlock (ebp, nic, NULL);
1746 /* if spilt because not used in the remainder of the
1747 block then add a push before this instruction and
1748 a pop at the end of the block */
1749 if (ssym->remainSpil)
1752 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1753 /* add push just before this instruction */
1754 addiCodeToeBBlock (ebp, nic, ic);
1756 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1757 /* add pop to the end of the block */
1758 addiCodeToeBBlock (ebp, nic, NULL);
1767 /*-----------------------------------------------------------------*/
1768 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1769 /*-----------------------------------------------------------------*/
1771 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1776 debugLog ("%s\n", __FUNCTION__);
1778 /* try for a ptr type */
1779 if ((reg = allocReg (REG_PTR)))
1782 /* try for gpr type */
1783 if ((reg = allocReg (REG_GPR)))
1786 /* we have to spil */
1787 if (!spilSomething (ic, ebp, sym))
1790 /* make sure partially assigned registers aren't reused */
1791 for (j=0; j<=sym->nRegs; j++)
1793 sym->regs[j]->isFree = 0;
1795 /* this looks like an infinite loop but
1796 in really selectSpil will abort */
1800 /*-----------------------------------------------------------------*/
1801 /* getRegGpr - will try for GPR if not spil */
1802 /*-----------------------------------------------------------------*/
1804 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1809 debugLog ("%s\n", __FUNCTION__);
1811 /* try for gpr type */
1812 if ((reg = allocReg (REG_GPR)))
1815 if (!pic14_ptrRegReq)
1816 if ((reg = allocReg (REG_PTR)))
1819 /* we have to spil */
1820 if (!spilSomething (ic, ebp, sym))
1823 /* make sure partially assigned registers aren't reused */
1824 for (j=0; j<=sym->nRegs; j++)
1826 sym->regs[j]->isFree = 0;
1828 /* this looks like an infinite loop but
1829 in really selectSpil will abort */
1833 /*-----------------------------------------------------------------*/
1834 /* symHasReg - symbol has a given register */
1835 /*-----------------------------------------------------------------*/
1837 symHasReg (symbol * sym, regs * reg)
1841 debugLog ("%s\n", __FUNCTION__);
1842 for (i = 0; i < sym->nRegs; i++)
1843 if (sym->regs[i] == reg)
1849 /*-----------------------------------------------------------------*/
1850 /* deassignLRs - check the live to and if they have registers & are */
1851 /* not spilt then free up the registers */
1852 /*-----------------------------------------------------------------*/
1854 deassignLRs (iCode * ic, eBBlock * ebp)
1860 debugLog ("%s\n", __FUNCTION__);
1861 for (sym = hTabFirstItem (liveRanges, &k); sym;
1862 sym = hTabNextItem (liveRanges, &k))
1865 symbol *psym = NULL;
1866 /* if it does not end here */
1867 if (sym->liveTo > ic->seq)
1870 /* Prevent the result from being assigned the same registers as (one)
1871 * operand as many genXXX-functions fail otherwise.
1872 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1873 * are known to fail. */
1874 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1878 case '=': /* assignment */
1879 case BITWISEAND: /* bitwise AND */
1880 case '|': /* bitwise OR */
1881 case '^': /* bitwise XOR */
1882 case '~': /* bitwise negate */
1883 case RLC: /* rotate through carry */
1886 case '+': /* addition */
1887 case '-': /* subtraction */
1888 /* go ahead, these are safe to use with
1889 * non-disjoint register sets */
1893 /* do not release operand registers */
1894 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1899 /* if it was spilt on stack then we can
1900 mark the stack spil location as free */
1905 sym->usl.spillLoc->isFree = 1;
1911 if (!bitVectBitValue (_G.regAssigned, sym->key))
1913 /* special case check if this is an IFX &
1914 the privious one was a pop and the
1915 previous one was not spilt then keep track
1917 if (ic->op == IFX && ic->prev &&
1918 ic->prev->op == IPOP &&
1919 !ic->prev->parmPush &&
1920 IS_SYMOP(IC_LEFT (ic->prev)) &&
1921 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1922 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1928 bitVectUnSetBit (_G.regAssigned, sym->key);
1930 /* if the result of this one needs registers
1931 and does not have it then assign it right
1933 if (IC_RESULT (ic) &&
1934 !(SKIP_IC2 (ic) || /* not a special icode */
1935 ic->op == JUMPTABLE ||
1940 POINTER_SET (ic)) &&
1941 IS_SYMOP (IC_RESULT (ic)) &&
1942 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1943 result->liveTo > ic->seq && /* and will live beyond this */
1944 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1945 result->liveFrom == ic->seq && /* does not start before here */
1946 result->regType == sym->regType && /* same register types */
1947 result->regType == sym->regType && /* same register types */
1948 result->nRegs && /* which needs registers */
1949 !result->isspilt && /* and does not already have them */
1951 !bitVectBitValue (_G.regAssigned, result->key) &&
1952 /* the number of free regs + number of regs in this LR
1953 can accomodate the what result Needs */
1954 ((nfreeRegsType (result->regType) +
1955 sym->nRegs) >= result->nRegs)
1959 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1961 result->regs[i] = sym->regs[i];
1963 result->regs[i] = getRegGpr (ic, ebp, result);
1965 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1969 /* free the remaining */
1970 for (; i < sym->nRegs; i++)
1974 if (!symHasReg (psym, sym->regs[i]))
1975 freeReg (sym->regs[i]);
1978 freeReg (sym->regs[i]);
1985 /*-----------------------------------------------------------------*/
1986 /* reassignLR - reassign this to registers */
1987 /*-----------------------------------------------------------------*/
1989 reassignLR (operand * op)
1991 symbol *sym = OP_SYMBOL (op);
1994 debugLog ("%s\n", __FUNCTION__);
1995 /* not spilt any more */
1996 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1997 bitVectUnSetBit (_G.spiltSet, sym->key);
1999 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2003 for (i = 0; i < sym->nRegs; i++)
2004 sym->regs[i]->isFree = 0;
2007 /*-----------------------------------------------------------------*/
2008 /* willCauseSpill - determines if allocating will cause a spill */
2009 /*-----------------------------------------------------------------*/
2011 willCauseSpill (int nr, int rt)
2013 debugLog ("%s\n", __FUNCTION__);
2014 /* first check if there are any avlb registers
2015 of te type required */
2018 /* special case for pointer type
2019 if pointer type not avlb then
2020 check for type gpr */
2021 if (nFreeRegs (rt) >= nr)
2023 if (nFreeRegs (REG_GPR) >= nr)
2028 if (pic14_ptrRegReq)
2030 if (nFreeRegs (rt) >= nr)
2035 if (nFreeRegs (REG_PTR) +
2036 nFreeRegs (REG_GPR) >= nr)
2041 debugLog (" ... yep it will (cause a spill)\n");
2042 /* it will cause a spil */
2046 /*-----------------------------------------------------------------*/
2047 /* positionRegs - the allocator can allocate same registers to res- */
2048 /* ult and operand, if this happens make sure they are in the same */
2049 /* position as the operand otherwise chaos results */
2050 /*-----------------------------------------------------------------*/
2052 positionRegs (symbol * result, symbol * opsym, int lineno)
2054 int count = min (result->nRegs, opsym->nRegs);
2055 int i, j = 0, shared = 0;
2057 debugLog ("%s\n", __FUNCTION__);
2058 /* if the result has been spilt then cannot share */
2063 /* first make sure that they actually share */
2064 for (i = 0; i < count; i++)
2066 for (j = 0; j < count; j++)
2068 if (result->regs[i] == opsym->regs[j] && i != j)
2078 regs *tmp = result->regs[i];
2079 result->regs[i] = result->regs[j];
2080 result->regs[j] = tmp;
2085 /*------------------------------------------------------------------*/
2086 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2087 /* it should either have registers or have beed spilled. Otherwise, */
2088 /* there was an uninitialized variable, so just spill this to get */
2089 /* the operand in a valid state. */
2090 /*------------------------------------------------------------------*/
2092 verifyRegsAssigned (operand *op, iCode * ic)
2097 if (!IS_ITEMP (op)) return;
2099 sym = OP_SYMBOL (op);
2100 if (sym->isspilt) return;
2101 if (!sym->nRegs) return;
2102 if (sym->regs[0]) return;
2104 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2105 sym->prereqv ? sym->prereqv->name : sym->name);
2110 /*-----------------------------------------------------------------*/
2111 /* serialRegAssign - serially allocate registers to the variables */
2112 /*-----------------------------------------------------------------*/
2114 serialRegAssign (eBBlock ** ebbs, int count)
2118 debugLog ("%s\n", __FUNCTION__);
2119 /* for all blocks */
2120 for (i = 0; i < count; i++)
2125 if (ebbs[i]->noPath &&
2126 (ebbs[i]->entryLabel != entryLabel &&
2127 ebbs[i]->entryLabel != returnLabel))
2130 /* of all instructions do */
2131 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2133 debugLog (" op: %s\n", decodeOp (ic->op));
2135 /* if this is an ipop that means some live
2136 range will have to be assigned again */
2138 reassignLR (IC_LEFT (ic));
2140 /* if result is present && is a true symbol */
2141 if (IC_RESULT (ic) && ic->op != IFX &&
2142 IS_TRUE_SYMOP (IC_RESULT (ic)))
2143 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2145 /* take away registers from live
2146 ranges that end at this instruction */
2147 deassignLRs (ic, ebbs[i]);
2149 /* some don't need registers */
2150 if (SKIP_IC2 (ic) ||
2151 ic->op == JUMPTABLE ||
2155 (IC_RESULT (ic) && POINTER_SET (ic)))
2158 /* now we need to allocate registers
2159 only for the result */
2160 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2162 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2168 /* Make sure any spill location is definately allocated */
2169 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2170 !sym->usl.spillLoc->allocreq)
2172 sym->usl.spillLoc->allocreq++;
2175 /* if it does not need or is spilt
2176 or is already assigned to registers
2177 or will not live beyond this instructions */
2180 bitVectBitValue (_G.regAssigned, sym->key) ||
2181 sym->liveTo <= ic->seq)
2184 /* if some liverange has been spilt at the block level
2185 and this one live beyond this block then spil this
2187 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2192 /* if trying to allocate this will cause
2193 a spill and there is nothing to spill
2194 or this one is rematerializable then
2196 willCS = willCauseSpill (sym->nRegs, sym->regType);
2197 spillable = computeSpillable (ic);
2199 (willCS && bitVectIsZero (spillable)))
2207 /* If the live range preceeds the point of definition
2208 then ideally we must take into account registers that
2209 have been allocated after sym->liveFrom but freed
2210 before ic->seq. This is complicated, so spill this
2211 symbol instead and let fillGaps handle the allocation. */
2212 if (sym->liveFrom < ic->seq)
2218 /* if it has a spillocation & is used less than
2219 all other live ranges then spill this */
2221 if (sym->usl.spillLoc) {
2222 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2223 allLRs, ebbs[i], ic));
2224 if (leastUsed && leastUsed->used > sym->used) {
2229 /* if none of the liveRanges have a spillLocation then better
2230 to spill this one than anything else already assigned to registers */
2231 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2232 /* if this is local to this block then we might find a block spil */
2233 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2241 if (ic->op == RECEIVE)
2242 debugLog ("When I get clever, I'll optimize the receive logic\n");
2244 /* if we need ptr regs for the right side
2246 if (POINTER_GET (ic)
2247 && IS_SYMOP(IC_LEFT(ic))
2248 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2249 <= (unsigned) PTRSIZE)
2254 /* else we assign registers to it */
2255 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2257 debugLog (" %d - \n", __LINE__);
2259 bitVectDebugOn(_G.regAssigned, debugF);
2260 for (j = 0; j < sym->nRegs; j++)
2262 if (sym->regType == REG_PTR)
2263 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2265 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2267 /* if the allocation failed which means
2268 this was spilt then break */
2272 debugLog (" %d - \n", __LINE__);
2274 /* if it shares registers with operands make sure
2275 that they are in the same position */
2276 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2277 IS_SYMOP(IC_RESULT(ic)) &&
2278 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2279 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2280 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2281 /* do the same for the right operand */
2282 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2283 IS_SYMOP(IC_RESULT(ic)) &&
2284 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2285 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2286 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2288 debugLog (" %d - \n", __LINE__);
2291 debugLog (" %d - \n", __LINE__);
2300 /* Check for and fix any problems with uninitialized operands */
2301 for (i = 0; i < count; i++)
2305 if (ebbs[i]->noPath &&
2306 (ebbs[i]->entryLabel != entryLabel &&
2307 ebbs[i]->entryLabel != returnLabel))
2310 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2317 verifyRegsAssigned (IC_COND (ic), ic);
2321 if (ic->op == JUMPTABLE)
2323 verifyRegsAssigned (IC_JTCOND (ic), ic);
2327 verifyRegsAssigned (IC_RESULT (ic), ic);
2328 verifyRegsAssigned (IC_LEFT (ic), ic);
2329 verifyRegsAssigned (IC_RIGHT (ic), ic);
2335 /*-----------------------------------------------------------------*/
2336 /* rUmaskForOp :- returns register mask for an operand */
2337 /*-----------------------------------------------------------------*/
2339 rUmaskForOp (operand * op)
2345 debugLog ("%s\n", __FUNCTION__);
2346 /* only temporaries are assigned registers */
2350 sym = OP_SYMBOL (op);
2352 /* if spilt or no registers assigned to it
2354 if (sym->isspilt || !sym->nRegs)
2357 rumask = newBitVect (pic14_nRegs);
2359 for (j = 0; j < sym->nRegs; j++)
2361 rumask = bitVectSetBit (rumask,
2362 sym->regs[j]->rIdx);
2368 /*-----------------------------------------------------------------*/
2369 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2370 /*-----------------------------------------------------------------*/
2372 regsUsedIniCode (iCode * ic)
2374 bitVect *rmask = newBitVect (pic14_nRegs);
2376 debugLog ("%s\n", __FUNCTION__);
2377 /* do the special cases first */
2380 rmask = bitVectUnion (rmask,
2381 rUmaskForOp (IC_COND (ic)));
2385 /* for the jumptable */
2386 if (ic->op == JUMPTABLE)
2388 rmask = bitVectUnion (rmask,
2389 rUmaskForOp (IC_JTCOND (ic)));
2394 /* of all other cases */
2396 rmask = bitVectUnion (rmask,
2397 rUmaskForOp (IC_LEFT (ic)));
2401 rmask = bitVectUnion (rmask,
2402 rUmaskForOp (IC_RIGHT (ic)));
2405 rmask = bitVectUnion (rmask,
2406 rUmaskForOp (IC_RESULT (ic)));
2412 /*-----------------------------------------------------------------*/
2413 /* createRegMask - for each instruction will determine the regsUsed */
2414 /*-----------------------------------------------------------------*/
2416 createRegMask (eBBlock ** ebbs, int count)
2420 debugLog ("%s\n", __FUNCTION__);
2421 /* for all blocks */
2422 for (i = 0; i < count; i++)
2426 if (ebbs[i]->noPath &&
2427 (ebbs[i]->entryLabel != entryLabel &&
2428 ebbs[i]->entryLabel != returnLabel))
2431 /* for all instructions */
2432 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2437 if (SKIP_IC2 (ic) || !ic->rlive)
2440 /* first mark the registers used in this
2442 ic->rUsed = regsUsedIniCode (ic);
2443 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2445 /* now create the register mask for those
2446 registers that are in use : this is a
2447 super set of ic->rUsed */
2448 ic->rMask = newBitVect (pic14_nRegs + 1);
2450 /* for all live Ranges alive at this point */
2451 for (j = 1; j < ic->rlive->size; j++)
2456 /* if not alive then continue */
2457 if (!bitVectBitValue (ic->rlive, j))
2460 /* find the live range we are interested in */
2461 if (!(sym = hTabItemWithKey (liveRanges, j)))
2463 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2464 "createRegMask cannot find live range");
2468 /* if no register assigned to it */
2469 if (!sym->nRegs || sym->isspilt)
2472 /* for all the registers allocated to it */
2473 for (k = 0; k < sym->nRegs; k++)
2476 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2482 /* This was the active version */
2483 /*-----------------------------------------------------------------*/
2484 /* rematStr - returns the rematerialized string for a remat var */
2485 /*-----------------------------------------------------------------*/
2487 rematStr (symbol * sym)
2490 iCode *ic = sym->rematiCode;
2491 symbol *psym = NULL;
2493 debugLog ("%s\n", __FUNCTION__);
2495 //printf ("%s\n", s);
2497 /* if plus or minus print the right hand side */
2499 if (ic->op == '+' || ic->op == '-') {
2501 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2503 sprintf (s, "(%s %c 0x%04x)",
2504 OP_SYMBOL (IC_LEFT (ric))->rname,
2506 (int) operandLitValue (IC_RIGHT (ic)));
2509 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2511 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2512 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2517 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2518 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2520 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2526 /* deprecated version */
2527 /*-----------------------------------------------------------------*/
2528 /* rematStr - returns the rematerialized string for a remat var */
2529 /*-----------------------------------------------------------------*/
2531 rematStr (symbol * sym)
2534 iCode *ic = sym->rematiCode;
2536 debugLog ("%s\n", __FUNCTION__);
2541 /* if plus or minus print the right hand side */
2543 if (ic->op == '+' || ic->op == '-') {
2544 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2547 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2551 if (ic->op == '+' || ic->op == '-')
2553 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2554 sprintf (s, "(%s %c 0x%04x)",
2555 OP_SYMBOL (IC_LEFT (ric))->rname,
2557 (int) operandLitValue (IC_RIGHT (ic)));
2560 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2562 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2566 /* we reached the end */
2567 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2571 printf ("%s\n", buffer);
2576 /*-----------------------------------------------------------------*/
2577 /* regTypeNum - computes the type & number of registers required */
2578 /*-----------------------------------------------------------------*/
2586 debugLog ("%s\n", __FUNCTION__);
2587 /* for each live range do */
2588 for (sym = hTabFirstItem (liveRanges, &k); sym;
2589 sym = hTabNextItem (liveRanges, &k)) {
2591 debugLog (" %d - %s\n", __LINE__, sym->rname);
2593 /* if used zero times then no registers needed */
2594 if ((sym->liveTo - sym->liveFrom) == 0)
2598 /* if the live range is a temporary */
2601 debugLog (" %d - itemp register\n", __LINE__);
2603 /* if the type is marked as a conditional */
2604 if (sym->regType == REG_CND)
2607 /* if used in return only then we don't
2610 if (IS_AGGREGATE (sym->type) || sym->isptr)
2611 sym->type = aggrToPtr (sym->type, FALSE);
2612 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2618 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2619 // sym->type = aggrToPtr (sym->type, FALSE);
2620 debugLog (" %d - used as a return\n", __LINE__);
2625 /* if the symbol has only one definition &
2626 that definition is a get_pointer and the
2627 pointer we are getting is rematerializable and
2631 if (bitVectnBitsOn (sym->defs) == 1 &&
2632 (ic = hTabItemWithKey (iCodehTab,
2633 bitVectFirstBit (sym->defs))) &&
2635 !IS_BITVAR (sym->etype) &&
2636 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2638 if (ptrPseudoSymSafe (sym, ic)) {
2642 debugLog (" %d - \n", __LINE__);
2644 /* create a pseudo symbol & force a spil */
2645 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2646 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2647 psym->type = sym->type;
2648 psym->etype = sym->etype;
2649 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2650 strcpy (psym->rname, psym->name);
2652 sym->usl.spillLoc = psym;
2656 /* if in data space or idata space then try to
2657 allocate pointer register */
2662 /* if not then we require registers */
2663 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2664 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2665 getSize (sym->type));
2668 if(IS_PTR_CONST (sym->type)) {
2669 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2673 if (sym->nRegs > 4) {
2674 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2675 printTypeChain (sym->type, stderr);
2676 fprintf (stderr, "\n");
2679 /* determine the type of register required */
2680 if (sym->nRegs == 1 &&
2681 IS_PTR (sym->type) &&
2683 sym->regType = REG_PTR;
2685 sym->regType = REG_GPR;
2688 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2692 /* for the first run we don't provide */
2693 /* registers for true symbols we will */
2694 /* see how things go */
2702 DEFSETFUNC (markRegFree)
2704 ((regs *)item)->isFree = 1;
2710 DEFSETFUNC (deallocReg)
2712 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2713 ((regs *)item)->isFree = 1;
2714 ((regs *)item)->wasUsed = 0;
2719 /*-----------------------------------------------------------------*/
2720 /* freeAllRegs - mark all registers as free */
2721 /*-----------------------------------------------------------------*/
2723 pic14_freeAllRegs ()
2727 debugLog ("%s\n", __FUNCTION__);
2729 applyToSet(dynAllocRegs,markRegFree);
2730 applyToSet(dynStackRegs,markRegFree);
2733 for (i = 0; i < pic14_nRegs; i++)
2734 regspic14[i].isFree = 1;
2738 /*-----------------------------------------------------------------*/
2739 /*-----------------------------------------------------------------*/
2741 pic14_deallocateAllRegs ()
2745 debugLog ("%s\n", __FUNCTION__);
2747 applyToSet(dynAllocRegs,deallocReg);
2750 for (i = 0; i < pic14_nRegs; i++) {
2751 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2752 regspic14[i].isFree = 1;
2753 regspic14[i].wasUsed = 0;
2761 /*-----------------------------------------------------------------*/
2762 /* deallocStackSpil - this will set the stack pointer back */
2763 /*-----------------------------------------------------------------*/
2765 DEFSETFUNC (deallocStackSpil)
2769 debugLog ("%s\n", __FUNCTION__);
2774 /*-----------------------------------------------------------------*/
2775 /* farSpacePackable - returns the packable icode for far variables */
2776 /*-----------------------------------------------------------------*/
2778 farSpacePackable (iCode * ic)
2782 debugLog ("%s\n", __FUNCTION__);
2783 /* go thru till we find a definition for the
2784 symbol on the right */
2785 for (dic = ic->prev; dic; dic = dic->prev)
2788 /* if the definition is a call then no */
2789 if ((dic->op == CALL || dic->op == PCALL) &&
2790 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2795 /* if shift by unknown amount then not */
2796 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2797 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2800 /* if pointer get and size > 1 */
2801 if (POINTER_GET (dic) &&
2802 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2805 if (POINTER_SET (dic) &&
2806 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2809 /* if any three is a true symbol in far space */
2810 if (IC_RESULT (dic) &&
2811 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2812 isOperandInFarSpace (IC_RESULT (dic)))
2815 if (IC_RIGHT (dic) &&
2816 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2817 isOperandInFarSpace (IC_RIGHT (dic)) &&
2818 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2821 if (IC_LEFT (dic) &&
2822 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2823 isOperandInFarSpace (IC_LEFT (dic)) &&
2824 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2827 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2829 if ((dic->op == LEFT_OP ||
2830 dic->op == RIGHT_OP ||
2832 IS_OP_LITERAL (IC_RIGHT (dic)))
2842 /*-----------------------------------------------------------------*/
2843 /* packRegsForAssign - register reduction for assignment */
2844 /*-----------------------------------------------------------------*/
2846 packRegsForAssign (iCode * ic, eBBlock * ebp)
2851 debugLog ("%s\n", __FUNCTION__);
2853 debugAopGet (" result:", IC_RESULT (ic));
2854 debugAopGet (" left:", IC_LEFT (ic));
2855 debugAopGet (" right:", IC_RIGHT (ic));
2857 /* if this is at an absolute address, then get the address. */
2858 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2859 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2860 debugLog (" %d - found config word declaration\n", __LINE__);
2861 if(IS_VALOP(IC_RIGHT(ic))) {
2862 debugLog (" setting config word to %x\n",
2863 (int) ulFromVal (IC_RIGHT(ic)->operand.valOperand));
2864 pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2865 (int) ulFromVal (IC_RIGHT(ic)->operand.valOperand));
2868 /* remove the assignment from the iCode chain. */
2870 remiCodeFromeBBlock (ebp, ic);
2871 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2872 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2879 if (!IS_ITEMP (IC_RESULT (ic))) {
2880 allocDirReg(IC_RESULT (ic));
2881 debugLog (" %d - result is not temp\n", __LINE__);
2884 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2885 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2886 allocDirReg(IC_LEFT (ic));
2890 if (!IS_ITEMP (IC_RIGHT (ic))) {
2891 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2893 /* only pack if this is not a function pointer */
2894 if (!IS_REF (IC_RIGHT (ic)))
2895 allocDirReg(IC_RIGHT (ic));
2899 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2900 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2902 debugLog (" %d - not packing - right side fails \n", __LINE__);
2906 /* if the true symbol is defined in far space or on stack
2907 then we should not since this will increase register pressure */
2908 if (isOperandInFarSpace (IC_RESULT (ic)))
2910 if ((dic = farSpacePackable (ic)))
2916 /* find the definition of iTempNN scanning backwards if we find a
2917 a use of the true symbol before we find the definition then
2919 for (dic = ic->prev; dic; dic = dic->prev)
2922 /* if there is a function call and this is
2923 a parameter & not my parameter then don't pack it */
2924 if ((dic->op == CALL || dic->op == PCALL) &&
2925 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2926 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2928 debugLog (" %d - \n", __LINE__);
2936 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2937 IS_OP_VOLATILE (IC_RESULT (dic)))
2939 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2944 if (IS_SYMOP (IC_RESULT (dic)) &&
2945 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2947 /* A previous result was assigned to the same register - we'll our definition */
2948 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2949 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2950 if (POINTER_SET (dic))
2956 if (IS_SYMOP (IC_RIGHT (dic)) &&
2957 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2958 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2960 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2965 if (IS_SYMOP (IC_LEFT (dic)) &&
2966 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2967 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2969 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2974 if (POINTER_SET (dic) &&
2975 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2977 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2985 return 0; /* did not find */
2987 /* if assignment then check that right is not a bit */
2988 if (ASSIGNMENT (ic) && !POINTER_SET (ic))
2990 sym_link *etype = operandType (IC_RESULT (dic));
2991 if (IS_BITFIELD (etype))
2993 /* if result is a bit too then it's ok */
2994 etype = operandType (IC_RESULT (ic));
2995 if (!IS_BITFIELD (etype))
3000 /* if the result is on stack or iaccess then it must be
3001 the same at least one of the operands */
3002 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3003 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3006 /* the operation has only one symbol
3007 operator then we can pack */
3008 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3009 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3012 if (!((IC_LEFT (dic) &&
3013 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3015 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3019 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3020 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3021 /* found the definition */
3022 /* replace the result with the result of */
3023 /* this assignment and remove this assignment */
3024 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3025 IC_RESULT (dic) = IC_RESULT (ic);
3027 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3029 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3031 /* delete from liverange table also
3032 delete from all the points inbetween and the new
3034 for (sic = dic; sic != ic; sic = sic->next)
3036 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3037 if (IS_ITEMP (IC_RESULT (dic)))
3038 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3041 remiCodeFromeBBlock (ebp, ic);
3042 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3043 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3044 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3050 /*-----------------------------------------------------------------*/
3051 /* findAssignToSym : scanning backwards looks for first assig found */
3052 /*-----------------------------------------------------------------*/
3054 findAssignToSym (operand * op, iCode * ic)
3058 debugLog ("%s\n", __FUNCTION__);
3059 for (dic = ic->prev; dic; dic = dic->prev)
3062 /* if definition by assignment */
3063 if (dic->op == '=' &&
3064 !POINTER_SET (dic) &&
3065 IC_RESULT (dic)->key == op->key
3066 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3070 /* we are interested only if defined in far space */
3071 /* or in stack space in case of + & - */
3073 /* if assigned to a non-symbol then return
3075 if (!IS_SYMOP (IC_RIGHT (dic)))
3078 /* if the symbol is in far space then
3080 if (isOperandInFarSpace (IC_RIGHT (dic)))
3083 /* for + & - operations make sure that
3084 if it is on the stack it is the same
3085 as one of the three operands */
3086 if ((ic->op == '+' || ic->op == '-') &&
3087 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3090 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3091 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3092 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3100 /* if we find an usage then we cannot delete it */
3101 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3104 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3107 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3111 /* now make sure that the right side of dic
3112 is not defined between ic & dic */
3115 iCode *sic = dic->next;
3117 for (; sic != ic; sic = sic->next)
3118 if (IC_RESULT (sic) &&
3119 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3128 /*-----------------------------------------------------------------*/
3129 /* packRegsForSupport :- reduce some registers for support calls */
3130 /*-----------------------------------------------------------------*/
3132 packRegsForSupport (iCode * ic, eBBlock * ebp)
3136 debugLog ("%s\n", __FUNCTION__);
3137 /* for the left & right operand :- look to see if the
3138 left was assigned a true symbol in far space in that
3139 case replace them */
3140 if (IS_ITEMP (IC_LEFT (ic)) &&
3141 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3143 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3149 debugAopGet ("removing left:", IC_LEFT (ic));
3151 /* found it we need to remove it from the
3153 for (sic = dic; sic != ic; sic = sic->next)
3154 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3156 IC_LEFT (ic)->operand.symOperand =
3157 IC_RIGHT (dic)->operand.symOperand;
3158 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3159 remiCodeFromeBBlock (ebp, dic);
3160 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3161 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3165 /* do the same for the right operand */
3168 IS_ITEMP (IC_RIGHT (ic)) &&
3169 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3171 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3177 /* if this is a subtraction & the result
3178 is a true symbol in far space then don't pack */
3179 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3181 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3182 if (IN_FARSPACE (SPEC_OCLS (etype)))
3186 debugAopGet ("removing right:", IC_RIGHT (ic));
3188 /* found it we need to remove it from the
3190 for (sic = dic; sic != ic; sic = sic->next)
3191 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3193 IC_RIGHT (ic)->operand.symOperand =
3194 IC_RIGHT (dic)->operand.symOperand;
3195 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3197 remiCodeFromeBBlock (ebp, dic);
3198 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3199 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3207 /*-----------------------------------------------------------------*/
3208 /* packRegsForOneuse : - will reduce some registers for single Use */
3209 /*-----------------------------------------------------------------*/
3211 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3216 debugLog ("%s\n", __FUNCTION__);
3217 /* if returning a literal then do nothing */
3221 /* only upto 2 bytes since we cannot predict
3222 the usage of b, & acc */
3223 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3228 /* this routine will mark the a symbol as used in one
3229 instruction use only && if the definition is local
3230 (ie. within the basic block) && has only one definition &&
3231 that definition is either a return value from a
3232 function or does not contain any variables in
3234 uses = bitVectCopy (OP_USES (op));
3235 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3236 if (!bitVectIsZero (uses)) /* has other uses */
3239 /* if it has only one defintion */
3240 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3241 return NULL; /* has more than one definition */
3243 /* get that definition */
3245 hTabItemWithKey (iCodehTab,
3246 bitVectFirstBit (OP_DEFS (op)))))
3249 /* found the definition now check if it is local */
3250 if (dic->seq < ebp->fSeq ||
3251 dic->seq > ebp->lSeq)
3252 return NULL; /* non-local */
3254 /* now check if it is the return from
3256 if (dic->op == CALL || dic->op == PCALL)
3258 if (ic->op != SEND && ic->op != RETURN &&
3259 !POINTER_SET(ic) && !POINTER_GET(ic))
3261 OP_SYMBOL (op)->ruonly = 1;
3268 /* otherwise check that the definition does
3269 not contain any symbols in far space */
3270 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3271 isOperandInFarSpace (IC_RIGHT (dic)) ||
3272 IS_OP_RUONLY (IC_LEFT (ic)) ||
3273 IS_OP_RUONLY (IC_RIGHT (ic)))
3278 /* if pointer set then make sure the pointer
3280 if (POINTER_SET (dic) &&
3281 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3284 if (POINTER_GET (dic) &&
3285 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3290 /* also make sure the intervenening instructions
3291 don't have any thing in far space */
3292 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3295 /* if there is an intervening function call then no */
3296 if (dic->op == CALL || dic->op == PCALL)
3298 /* if pointer set then make sure the pointer
3300 if (POINTER_SET (dic) &&
3301 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3304 if (POINTER_GET (dic) &&
3305 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3308 /* if address of & the result is remat then okay */
3309 if (dic->op == ADDRESS_OF &&
3310 OP_SYMBOL (IC_RESULT (dic))->remat)
3313 /* if operand has size of three or more & this
3314 operation is a '*','/' or '%' then 'b' may
3316 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3317 getSize (operandType (op)) >= 3)
3320 /* if left or right or result is in far space */
3321 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3322 isOperandInFarSpace (IC_RIGHT (dic)) ||
3323 isOperandInFarSpace (IC_RESULT (dic)) ||
3324 IS_OP_RUONLY (IC_LEFT (dic)) ||
3325 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3326 IS_OP_RUONLY (IC_RESULT (dic)))
3332 OP_SYMBOL (op)->ruonly = 1;
3337 /*-----------------------------------------------------------------*/
3338 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3339 /*-----------------------------------------------------------------*/
3341 isBitwiseOptimizable (iCode * ic)
3343 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3344 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3346 debugLog ("%s\n", __FUNCTION__);
3347 /* bitwise operations are considered optimizable
3348 under the following conditions (Jean-Louis VERN)
3360 if (IS_LITERAL (rtype) ||
3361 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3367 /*-----------------------------------------------------------------*/
3368 /* packRegsForAccUse - pack registers for acc use */
3369 /*-----------------------------------------------------------------*/
3371 packRegsForAccUse (iCode * ic)
3375 debugLog ("%s\n", __FUNCTION__);
3377 /* result too large for WREG? */
3378 if (getSize (operandType (IC_RESULT (ic))) > 1)
3381 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3382 * is never used as an operand to an instruction that
3383 * cannot have WREG as an operand (e.g. BTFSx cannot
3384 * operate on WREG...
3385 * For now, store all results into proper registers. */
3389 /* if this is an aggregate, e.g. a one byte char array */
3390 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3393 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3395 /* if + or - then it has to be one byte result */
3396 if ((ic->op == '+' || ic->op == '-')
3397 && getSize (operandType (IC_RESULT (ic))) > 1)
3400 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3401 /* if shift operation make sure right side is not a literal */
3402 if (ic->op == RIGHT_OP &&
3403 (isOperandLiteral (IC_RIGHT (ic)) ||
3404 getSize (operandType (IC_RESULT (ic))) > 1))
3407 if (ic->op == LEFT_OP &&
3408 (isOperandLiteral (IC_RIGHT (ic)) ||
3409 getSize (operandType (IC_RESULT (ic))) > 1))
3412 if (IS_BITWISE_OP (ic) &&
3413 getSize (operandType (IC_RESULT (ic))) > 1)
3417 /* has only one definition */
3418 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3421 /* has only one use */
3422 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3425 /* and the usage immediately follows this iCode */
3426 if (!(uic = hTabItemWithKey (iCodehTab,
3427 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3430 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3431 if (ic->next != uic)
3434 /* if it is a conditional branch then we definitely can */
3438 if (uic->op == JUMPTABLE)
3441 /* if the usage is not is an assignment
3442 or an arithmetic / bitwise / shift operation then not */
3443 if (POINTER_SET (uic) &&
3444 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3447 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3448 if (uic->op != '=' &&
3449 !IS_ARITHMETIC_OP (uic) &&
3450 !IS_BITWISE_OP (uic) &&
3451 uic->op != LEFT_OP &&
3452 uic->op != RIGHT_OP)
3455 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3456 /* if used in ^ operation then make sure right is not a
3458 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3461 /* if shift operation make sure right side is not a literal */
3462 if (uic->op == RIGHT_OP &&
3463 (isOperandLiteral (IC_RIGHT (uic)) ||
3464 getSize (operandType (IC_RESULT (uic))) > 1))
3467 if (uic->op == LEFT_OP &&
3468 (isOperandLiteral (IC_RIGHT (uic)) ||
3469 getSize (operandType (IC_RESULT (uic))) > 1))
3472 /* make sure that the result of this icode is not on the
3473 stack, since acc is used to compute stack offset */
3474 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3475 OP_SYMBOL (IC_RESULT (uic))->onStack)
3478 /* if either one of them in far space then we cannot */
3479 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3480 isOperandInFarSpace (IC_LEFT (uic))) ||
3481 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3482 isOperandInFarSpace (IC_RIGHT (uic))))
3485 /* if the usage has only one operand then we can */
3486 if (IC_LEFT (uic) == NULL ||
3487 IC_RIGHT (uic) == NULL)
3490 /* make sure this is on the left side if not
3491 a '+' since '+' is commutative */
3492 if (ic->op != '+' &&
3493 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3496 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3497 /* if one of them is a literal then we can */
3498 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3499 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3500 (getSize (operandType (IC_RESULT (uic))) <= 1))
3502 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3506 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3507 /* if the other one is not on stack then we can */
3508 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3509 (IS_ITEMP (IC_RIGHT (uic)) ||
3510 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3511 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3514 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3515 (IS_ITEMP (IC_LEFT (uic)) ||
3516 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3517 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3523 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3524 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3528 /*-----------------------------------------------------------------*/
3529 /* packForPush - hueristics to reduce iCode for pushing */
3530 /*-----------------------------------------------------------------*/
3532 packForReceive (iCode * ic, eBBlock * ebp)
3536 debugLog ("%s\n", __FUNCTION__);
3537 debugAopGet (" result:", IC_RESULT (ic));
3538 debugAopGet (" left:", IC_LEFT (ic));
3539 debugAopGet (" right:", IC_RIGHT (ic));
3544 for (dic = ic->next; dic; dic = dic->next)
3549 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3550 debugLog (" used on left\n");
3551 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3552 debugLog (" used on right\n");
3553 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3554 debugLog (" used on result\n");
3556 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3557 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3562 debugLog (" hey we can remove this unnecessary assign\n");
3564 /*-----------------------------------------------------------------*/
3565 /* packForPush - hueristics to reduce iCode for pushing */
3566 /*-----------------------------------------------------------------*/
3568 packForPush (iCode * ic, eBBlock * ebp)
3572 debugLog ("%s\n", __FUNCTION__);
3573 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3576 /* must have only definition & one usage */
3577 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3578 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3581 /* find the definition */
3582 if (!(dic = hTabItemWithKey (iCodehTab,
3583 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3586 if (dic->op != '=' || POINTER_SET (dic))
3589 /* we now we know that it has one & only one def & use
3590 and the that the definition is an assignment */
3591 IC_LEFT (ic) = IC_RIGHT (dic);
3593 remiCodeFromeBBlock (ebp, dic);
3594 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3595 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3598 static void printSymType(char * str, sym_link *sl)
3601 debugLog (" %s Symbol type: ",str);
3602 printTypeChain( sl, debugF);
3607 /*-----------------------------------------------------------------*/
3608 /* some debug code to print the symbol S_TYPE. Note that
3609 * the function checkSClass in src/SDCCsymt.c dinks with
3610 * the S_TYPE in ways the PIC port doesn't fully like...*/
3611 /*-----------------------------------------------------------------*/
3612 static void isData(sym_link *sl)
3616 // avoid garbage `data' and `sfr' output
3623 for ( ; sl; sl=sl->next) {
3625 switch (SPEC_SCLS(sl)) {
3627 case S_DATA: fprintf (of, "data "); break;
3628 case S_XDATA: fprintf (of, "xdata "); break;
3629 case S_SFR: fprintf (of, "sfr "); break;
3630 case S_SBIT: fprintf (of, "sbit "); break;
3631 case S_CODE: fprintf (of, "code "); break;
3632 case S_IDATA: fprintf (of, "idata "); break;
3633 case S_PDATA: fprintf (of, "pdata "); break;
3634 case S_LITERAL: fprintf (of, "literal "); break;
3635 case S_STACK: fprintf (of, "stack "); break;
3636 case S_XSTACK: fprintf (of, "xstack "); break;
3637 case S_BIT: fprintf (of, "bit "); break;
3638 case S_EEPROM: fprintf (of, "eeprom "); break;
3648 /*-----------------------------------------------------------------*/
3649 /* packRegisters - does some transformations to reduce register */
3651 /*-----------------------------------------------------------------*/
3653 packRegisters (eBBlock * ebp)
3658 debugLog ("%s\n", __FUNCTION__);
3664 /* look for assignments of the form */
3665 /* iTempNN = TRueSym (someoperation) SomeOperand */
3667 /* TrueSym := iTempNN:1 */
3668 for (ic = ebp->sch; ic; ic = ic->next)
3671 /* find assignment of the form TrueSym := iTempNN:1 */
3672 if (ic->op == '=' && !POINTER_SET (ic))
3673 change += packRegsForAssign (ic, ebp);
3677 if (POINTER_SET (ic))
3678 debugLog ("pointer is set\n");
3679 debugAopGet (" result:", IC_RESULT (ic));
3680 debugAopGet (" left:", IC_LEFT (ic));
3681 debugAopGet (" right:", IC_RIGHT (ic));
3690 for (ic = ebp->sch; ic; ic = ic->next) {
3692 if(IS_SYMOP ( IC_LEFT(ic))) {
3693 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3695 debugAopGet (" left:", IC_LEFT (ic));
3696 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3697 debugLog (" is a pointer\n");
3699 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3700 debugLog (" is volatile\n");
3704 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3707 if(IS_SYMOP ( IC_RIGHT(ic))) {
3708 debugAopGet (" right:", IC_RIGHT (ic));
3709 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3712 if(IS_SYMOP ( IC_RESULT(ic))) {
3713 debugAopGet (" result:", IC_RESULT (ic));
3714 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3717 if (POINTER_SET (ic))
3718 debugLog (" %d - Pointer set\n", __LINE__);
3721 /* Look for two subsequent iCodes with */
3723 /* _c = iTemp & op; */
3724 /* and replace them by */
3727 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3729 ic->prev->op == '=' &&
3730 IS_ITEMP (IC_LEFT (ic)) &&
3731 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3732 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3734 iCode* ic_prev = ic->prev;
3735 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3737 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3738 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3740 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3741 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3742 prev_result_sym->liveTo == ic->seq)
3744 prev_result_sym->liveTo = ic_prev->seq;
3747 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3749 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3751 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3753 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3754 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3755 remiCodeFromeBBlock (ebp, ic_prev);
3756 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3760 /* if this is an itemp & result of a address of a true sym
3761 then mark this as rematerialisable */
3762 if (ic->op == ADDRESS_OF &&
3763 IS_ITEMP (IC_RESULT (ic)) &&
3764 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3765 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3766 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3769 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3771 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3772 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3773 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3777 /* if straight assignment then carry remat flag if
3778 this is the only definition */
3779 if (ic->op == '=' &&
3780 !POINTER_SET (ic) &&
3781 IS_SYMOP (IC_RIGHT (ic)) &&
3782 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3783 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3785 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3787 OP_SYMBOL (IC_RESULT (ic))->remat =
3788 OP_SYMBOL (IC_RIGHT (ic))->remat;
3789 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3790 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3793 /* if this is a +/- operation with a rematerizable
3794 then mark this as rematerializable as well */
3795 if ((ic->op == '+' || ic->op == '-') &&
3796 (IS_SYMOP (IC_LEFT (ic)) &&
3797 IS_ITEMP (IC_RESULT (ic)) &&
3798 OP_SYMBOL (IC_LEFT (ic))->remat &&
3799 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3800 IS_OP_LITERAL (IC_RIGHT (ic))))
3802 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3804 operandLitValue (IC_RIGHT (ic));
3805 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3806 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3807 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3810 /* mark the pointer usages */
3811 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3813 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3814 debugLog (" marking as a pointer (set) =>");
3815 debugAopGet (" result:", IC_RESULT (ic));
3817 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3819 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3820 debugLog (" marking as a pointer (get) =>");
3821 debugAopGet (" left:", IC_LEFT (ic));
3826 /* if we are using a symbol on the stack
3827 then we should say pic14_ptrRegReq */
3828 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3829 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3830 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3831 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3832 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3833 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3836 if (IS_SYMOP (IC_LEFT (ic)))
3837 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3838 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3839 if (IS_SYMOP (IC_RIGHT (ic)))
3840 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3841 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3842 if (IS_SYMOP (IC_RESULT (ic)))
3843 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3844 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3847 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3851 /* if the condition of an if instruction
3852 is defined in the previous instruction then
3853 mark the itemp as a conditional */
3854 if ((IS_CONDITIONAL (ic) ||
3855 ((ic->op == BITWISEAND ||
3858 isBitwiseOptimizable (ic))) &&
3859 ic->next && ic->next->op == IFX &&
3860 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3861 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3864 debugLog (" %d\n", __LINE__);
3865 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3869 /* reduce for support function calls */
3870 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3871 packRegsForSupport (ic, ebp);
3873 /* if a parameter is passed, it's in W, so we may not
3874 need to place a copy in a register */
3875 if (ic->op == RECEIVE)
3876 packForReceive (ic, ebp);
3878 /* some cases the redundant moves can
3879 can be eliminated for return statements */
3880 if ((ic->op == RETURN || ic->op == SEND) &&
3881 !isOperandInFarSpace (IC_LEFT (ic)) &&
3883 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3885 /* if pointer set & left has a size more than
3886 one and right is not in far space */
3887 if (POINTER_SET (ic) &&
3888 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3889 IS_SYMOP(IC_RESULT(ic)) &&
3890 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3891 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3892 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3894 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3896 /* if pointer get */
3897 if (POINTER_GET (ic) &&
3898 !isOperandInFarSpace (IC_RESULT (ic)) &&
3899 IS_SYMOP(IC_LEFT(ic)) &&
3900 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3901 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3902 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3904 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3907 /* if this is cast for intergral promotion then
3908 check if only use of the definition of the
3909 operand being casted/ if yes then replace
3910 the result of that arithmetic operation with
3911 this result and get rid of the cast */
3912 if (ic->op == CAST) {
3914 sym_link *fromType = operandType (IC_RIGHT (ic));
3915 sym_link *toType = operandType (IC_LEFT (ic));
3917 debugLog (" %d - casting\n", __LINE__);
3919 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3920 getSize (fromType) != getSize (toType)) {
3923 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3926 if (IS_ARITHMETIC_OP (dic)) {
3928 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3929 IC_RESULT (dic) = IC_RESULT (ic);
3930 remiCodeFromeBBlock (ebp, ic);
3931 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3932 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3933 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3937 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3941 /* if the type from and type to are the same
3942 then if this is the only use then packit */
3943 if (compareType (operandType (IC_RIGHT (ic)),
3944 operandType (IC_LEFT (ic))) == 1) {
3946 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3949 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3950 IC_RESULT (dic) = IC_RESULT (ic);
3951 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3952 remiCodeFromeBBlock (ebp, ic);
3953 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3954 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3962 iTempNN := (some variable in farspace) V1
3967 if (ic->op == IPUSH)
3969 packForPush (ic, ebp);
3973 /* pack registers for accumulator use, when the
3974 result of an arithmetic or bit wise operation
3975 has only one use, that use is immediately following
3976 the defintion and the using iCode has only one
3977 operand or has two operands but one is literal &
3978 the result of that operation is not on stack then
3979 we can leave the result of this operation in acc:b
3981 if ((IS_ARITHMETIC_OP (ic)
3983 || IS_BITWISE_OP (ic)
3985 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3988 IS_ITEMP (IC_RESULT (ic)) &&
3989 getSize (operandType (IC_RESULT (ic))) <= 2)
3991 packRegsForAccUse (ic);
3997 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4001 if (!debug || !debugF)
4004 for (i = 0; i < count; i++)
4006 fprintf (debugF, "\n----------------------------------------------------------------\n");
4007 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4008 ebbs[i]->entryLabel->name,
4011 ebbs[i]->isLastInLoop);
4012 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4017 fprintf (debugF, "visited %d : hasFcall = %d\n",
4021 fprintf (debugF, "\ndefines bitVector :");
4022 bitVectDebugOn (ebbs[i]->defSet, debugF);
4023 fprintf (debugF, "\nlocal defines bitVector :");
4024 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4025 fprintf (debugF, "\npointers Set bitvector :");
4026 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4027 fprintf (debugF, "\nin pointers Set bitvector :");
4028 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4029 fprintf (debugF, "\ninDefs Set bitvector :");
4030 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4031 fprintf (debugF, "\noutDefs Set bitvector :");
4032 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4033 fprintf (debugF, "\nusesDefs Set bitvector :");
4034 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4035 fprintf (debugF, "\n----------------------------------------------------------------\n");
4036 printiCChain (ebbs[i]->sch, debugF);
4039 /*-----------------------------------------------------------------*/
4040 /* assignRegisters - assigns registers to each live range as need */
4041 /*-----------------------------------------------------------------*/
4043 pic14_assignRegisters (ebbIndex * ebbi)
4045 eBBlock ** ebbs = ebbi->bbOrder;
4046 int count = ebbi->count;
4050 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
4051 debugLog ("ebbs before optimizing:\n");
4052 dumpEbbsToDebug (ebbs, count);
4054 setToNull ((void *) &_G.funcrUsed);
4055 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4058 /* change assignments this will remove some
4059 live ranges reducing some register pressure */
4060 for (i = 0; i < count; i++)
4061 packRegisters (ebbs[i]);
4068 debugLog("dir registers allocated so far:\n");
4069 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4072 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4073 reg = hTabNextItem(dynDirectRegNames, &hkey);
4078 if (options.dump_pack)
4079 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4081 /* first determine for each live range the number of
4082 registers & the type of registers required for each */
4085 /* and serially allocate registers */
4086 serialRegAssign (ebbs, count);
4088 /* if stack was extended then tell the user */
4091 /* werror(W_TOOMANY_SPILS,"stack", */
4092 /* _G.stackExtend,currFunc->name,""); */
4098 /* werror(W_TOOMANY_SPILS,"data space", */
4099 /* _G.dataExtend,currFunc->name,""); */
4103 /* after that create the register mask
4104 for each of the instruction */
4105 createRegMask (ebbs, count);
4107 /* redo that offsets for stacked automatic variables */
4108 redoStackOffsets ();
4110 if (options.dump_rassgn)
4111 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4113 /* now get back the chain */
4114 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4116 debugLog ("ebbs after optimizing:\n");
4117 dumpEbbsToDebug (ebbs, count);
4122 /* free up any _G.stackSpil locations allocated */
4123 applyToSet (_G.stackSpil, deallocStackSpil);
4125 setToNull ((void *) &_G.stackSpil);
4126 setToNull ((void *) &_G.spiltSet);
4127 /* mark all registers as free */
4128 //pic14_freeAllRegs ();
4130 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4131 pic14_debugLogClose ();