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 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
35 #define FENTRY2 1 ? (void)0 : printf
37 #define STRCASECMP strcasecmp
38 //#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0)
39 #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 /*-----------------------------------------------------------------*/
54 extern void genpic14Code (iCode *);
55 extern void assignConfigWordValue(int address, int value);
65 bitVect *funcrUsed; /* registers used in a function */
71 /* Shared with gen.c */
72 int pic14_ptrRegReq; /* one byte pointer register required */
75 set *dynAllocRegs=NULL;
76 set *dynStackRegs=NULL;
77 set *dynProcessorRegs=NULL;
78 set *dynDirectRegs=NULL;
79 set *dynDirectBitRegs=NULL;
80 set *dynInternalRegs=NULL;
82 static hTab *dynDirectRegNames= NULL;
83 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 static int dynrIdx=0x20;
86 static int rDirectIdx=0;
88 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
90 int Gstack_base_addr=0; /* The starting address of registers that
91 * are used to pass and return parameters */
97 static void spillThis (symbol *);
99 static FILE *debugF = NULL;
100 /*-----------------------------------------------------------------*/
101 /* debugLog - open a file for debugging information */
102 /*-----------------------------------------------------------------*/
103 //static void debugLog(char *inst,char *fmt, ...)
105 debugLog (char *fmt,...)
107 static int append = 0; // First time through, open the file without append.
110 //char *bufferP=buffer;
113 if (!debug || !dstFileName)
119 /* create the file name */
120 strcpy (buffer, dstFileName);
121 strcat (buffer, ".d");
123 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
125 werror (E_FILE_OPEN_ERR, buffer);
128 append = 1; // Next time debubLog is called, we'll append the debug info
134 vsprintf (buffer, fmt, ap);
136 fprintf (debugF, "%s", buffer);
138 while (isspace((unsigned char)*bufferP)) bufferP++;
140 if (bufferP && *bufferP)
141 lineCurr = (lineCurr ?
142 connectLine(lineCurr,newLineNode(lb)) :
143 (lineHead = newLineNode(lb)));
144 lineCurr->isInline = _G.inLine;
145 lineCurr->isDebug = _G.debugLine;
155 fputc ('\n', debugF);
157 /*-----------------------------------------------------------------*/
158 /* debugLogClose - closes the debug log file (if opened) */
159 /*-----------------------------------------------------------------*/
169 #define AOP(op) op->aop
172 debugAopGet (char *str, operand * op)
177 printOperand (op, debugF);
185 decodeOp (unsigned int op)
188 if (op < 128 && op > ' ')
190 buffer[0] = (op & 0xff);
197 case IDENTIFIER: return "IDENTIFIER";
198 case TYPE_NAME: return "TYPE_NAME";
199 case CONSTANT: return "CONSTANT";
200 case STRING_LITERAL: return "STRING_LITERAL";
201 case SIZEOF: return "SIZEOF";
202 case PTR_OP: return "PTR_OP";
203 case INC_OP: return "INC_OP";
204 case DEC_OP: return "DEC_OP";
205 case LEFT_OP: return "LEFT_OP";
206 case RIGHT_OP: return "RIGHT_OP";
207 case LE_OP: return "LE_OP";
208 case GE_OP: return "GE_OP";
209 case EQ_OP: return "EQ_OP";
210 case NE_OP: return "NE_OP";
211 case AND_OP: return "AND_OP";
212 case OR_OP: return "OR_OP";
213 case MUL_ASSIGN: return "MUL_ASSIGN";
214 case DIV_ASSIGN: return "DIV_ASSIGN";
215 case MOD_ASSIGN: return "MOD_ASSIGN";
216 case ADD_ASSIGN: return "ADD_ASSIGN";
217 case SUB_ASSIGN: return "SUB_ASSIGN";
218 case LEFT_ASSIGN: return "LEFT_ASSIGN";
219 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
220 case AND_ASSIGN: return "AND_ASSIGN";
221 case XOR_ASSIGN: return "XOR_ASSIGN";
222 case OR_ASSIGN: return "OR_ASSIGN";
223 case TYPEDEF: return "TYPEDEF";
224 case EXTERN: return "EXTERN";
225 case STATIC: return "STATIC";
226 case AUTO: return "AUTO";
227 case REGISTER: return "REGISTER";
228 case CODE: return "CODE";
229 case EEPROM: return "EEPROM";
230 case INTERRUPT: return "INTERRUPT";
231 case SFR: return "SFR";
232 case AT: return "AT";
233 case SBIT: return "SBIT";
234 case REENTRANT: return "REENTRANT";
235 case USING: return "USING";
236 case XDATA: return "XDATA";
237 case DATA: return "DATA";
238 case IDATA: return "IDATA";
239 case PDATA: return "PDATA";
240 case VAR_ARGS: return "VAR_ARGS";
241 case CRITICAL: return "CRITICAL";
242 case NONBANKED: return "NONBANKED";
243 case BANKED: return "BANKED";
244 case CHAR: return "CHAR";
245 case SHORT: return "SHORT";
246 case INT: return "INT";
247 case LONG: return "LONG";
248 case SIGNED: return "SIGNED";
249 case UNSIGNED: return "UNSIGNED";
250 case FLOAT: return "FLOAT";
251 case DOUBLE: return "DOUBLE";
252 case CONST: return "CONST";
253 case VOLATILE: return "VOLATILE";
254 case VOID: return "VOID";
255 case BIT: return "BIT";
256 case STRUCT: return "STRUCT";
257 case UNION: return "UNION";
258 case ENUM: return "ENUM";
259 case ELIPSIS: return "ELIPSIS";
260 case RANGE: return "RANGE";
261 case FAR: return "FAR";
262 case CASE: return "CASE";
263 case DEFAULT: return "DEFAULT";
264 case IF: return "IF";
265 case ELSE: return "ELSE";
266 case SWITCH: return "SWITCH";
267 case WHILE: return "WHILE";
268 case DO: return "DO";
269 case FOR: return "FOR";
270 case GOTO: return "GOTO";
271 case CONTINUE: return "CONTINUE";
272 case BREAK: return "BREAK";
273 case RETURN: return "RETURN";
274 case INLINEASM: return "INLINEASM";
275 case IFX: return "IFX";
276 case ADDRESS_OF: return "ADDRESS_OF";
277 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
278 case SPIL: return "SPIL";
279 case UNSPIL: return "UNSPIL";
280 case GETHBIT: return "GETHBIT";
281 case BITWISEAND: return "BITWISEAND";
282 case UNARYMINUS: return "UNARYMINUS";
283 case IPUSH: return "IPUSH";
284 case IPOP: return "IPOP";
285 case PCALL: return "PCALL";
286 case ENDFUNCTION: return "ENDFUNCTION";
287 case JUMPTABLE: return "JUMPTABLE";
288 case RRC: return "RRC";
289 case RLC: return "RLC";
290 case CAST: return "CAST";
291 case CALL: return "CALL";
292 case PARAM: return "PARAM ";
293 case NULLOP: return "NULLOP";
294 case BLOCK: return "BLOCK";
295 case LABEL: return "LABEL";
296 case RECEIVE: return "RECEIVE";
297 case SEND: return "SEND";
299 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
302 /*-----------------------------------------------------------------*/
303 /*-----------------------------------------------------------------*/
305 debugLogRegType (short type)
310 case REG_GPR: return "REG_GPR";
311 case REG_PTR: return "REG_PTR";
312 case REG_CND: return "REG_CND";
315 sprintf (buffer, "unknown reg type %d", type);
319 /*-----------------------------------------------------------------*/
320 /*-----------------------------------------------------------------*/
321 static int regname2key(char const *name)
330 key += (*name++) + 1;
334 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
338 /*-----------------------------------------------------------------*/
339 /* newReg - allocate and init memory for a new register */
340 /*-----------------------------------------------------------------*/
341 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
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 = NULL;
371 dReg->reglives.usedpFlows = newSet();
372 dReg->reglives.assignedpFlows = newSet();
374 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
379 /*-----------------------------------------------------------------*/
380 /* regWithIdx - Search through a set of registers that matches idx */
381 /*-----------------------------------------------------------------*/
383 regWithIdx (set *dRegs, int idx, int fixed)
387 for (dReg = setFirstItem(dRegs) ; dReg ;
388 dReg = setNextItem(dRegs)) {
390 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
398 /*-----------------------------------------------------------------*/
399 /* regWithName - Search through a set of registers that matches name */
400 /*-----------------------------------------------------------------*/
402 regWithName (set *dRegs, const char *name)
406 for (dReg = setFirstItem(dRegs) ; dReg ;
407 dReg = setNextItem(dRegs)) {
409 if((strcmp(name,dReg->name)==0)) {
417 /*-----------------------------------------------------------------*/
418 /* regWithName - Search for a registers that matches name */
419 /*-----------------------------------------------------------------*/
421 regFindWithName (const char *name)
425 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
426 debugLog ("Found a Direct Register!\n");
429 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
430 debugLog ("Found a Direct Bit Register!\n");
434 if (*name=='_') name++; // Step passed '_'
436 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
437 debugLog ("Found a Dynamic Register!\n");
440 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
441 debugLog ("Found a Processor Register!\n");
444 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
445 debugLog ("Found an Internal Register!\n");
448 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
449 debugLog ("Found an Stack Register!\n");
456 /*-----------------------------------------------------------------*/
457 /* regFindFree - Search for a free register in a set of registers */
458 /*-----------------------------------------------------------------*/
460 regFindFree (set *dRegs)
464 for (dReg = setFirstItem(dRegs) ; dReg ;
465 dReg = setNextItem(dRegs)) {
473 /*-----------------------------------------------------------------*/
474 /* initStack - allocate registers for a psuedo stack */
475 /*-----------------------------------------------------------------*/
476 void initStack(int base_address, int size)
481 Gstack_base_addr = base_address;
483 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
485 for(i = 0; i<size; i++) {
488 SNPRINTF(&buffer[0], 16, "STK%02d", i);
489 r = newReg(REG_STK, PO_GPR_TEMP,base_address,buffer,1,0);
490 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
494 r->alias = 0x180; // Using shared memory for pseudo stack
495 addSet(&dynStackRegs,r);
500 /*-----------------------------------------------------------------*
501 *-----------------------------------------------------------------*/
503 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
506 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
507 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
510 /*-----------------------------------------------------------------*
511 *-----------------------------------------------------------------*/
514 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
516 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
518 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
521 return addSet(&dynInternalRegs,reg);
526 /*-----------------------------------------------------------------*/
527 /* allocReg - allocates register of given type */
528 /*-----------------------------------------------------------------*/
530 allocReg (short type)
534 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
535 //fprintf(stderr,"allocReg\n");
537 reg = pic14_findFreeReg (type);
545 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
550 /*-----------------------------------------------------------------*/
551 /* dirregWithName - search for register by name */
552 /*-----------------------------------------------------------------*/
554 dirregWithName (char *name)
562 /* hash the name to get a key */
564 hkey = regname2key(name);
566 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
570 if(STRCASECMP(reg->name, name) == 0) {
574 reg = hTabNextItemWK (dynDirectRegNames);
578 return NULL; // name wasn't found in the hash table
581 int IS_CONFIG_ADDRESS(int address)
584 return address == 0x2007;
587 /*-----------------------------------------------------------------*/
588 /* allocNewDirReg - allocates a new register of given type */
589 /*-----------------------------------------------------------------*/
591 allocNewDirReg (sym_link *symlnk,const char *name)
595 sym_link *spec = getSpec (symlnk);
597 /* if this is at an absolute address, then get the address. */
598 if (SPEC_ABSA (spec) ) {
599 address = SPEC_ADDR (spec);
600 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
603 /* Register wasn't found in hash, so let's create
604 * a new one and put it in the hash table AND in the
605 * dynDirectRegNames set */
606 if (IS_CONFIG_ADDRESS(address)) {
607 debugLog (" -- %s is declared at address 0x2007\n",name);
612 if (IS_BITVAR (spec))
619 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
620 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
622 if (SPEC_ABSA (spec) ) {
626 if (IS_BITVAR (spec)) {
627 addSet(&dynDirectBitRegs, reg);
630 addSet(&dynDirectRegs, reg);
632 if (!IS_STATIC (spec)) {
635 if (IS_EXTERN (spec)) {
641 if (address && reg) {
643 reg->address = address;
644 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
650 /*-----------------------------------------------------------------*/
651 /* allocDirReg - allocates register of given type */
652 /*-----------------------------------------------------------------*/
654 allocDirReg (operand *op )
661 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
665 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
667 /* If the symbol is at a fixed address, then remove the leading underscore
668 * from the name. This is hack to allow the .asm include file named registers
669 * to match the .c declared register names */
671 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
674 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
676 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
677 debugLog(" %d const char\n",__LINE__);
678 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
681 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
682 if (IS_CODE ( OP_SYM_ETYPE(op)) )
683 debugLog(" %d code space\n",__LINE__);
685 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
686 debugLog(" %d integral\n",__LINE__);
687 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
688 debugLog(" %d literal\n",__LINE__);
689 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
690 debugLog(" %d specifier\n",__LINE__);
691 debugAopGet(NULL, op);
694 if (IS_CODE ( OP_SYM_ETYPE(op)) )
697 /* First, search the hash table to see if there is a register with this name */
698 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
699 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
702 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
703 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
705 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
706 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
709 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
711 reg = dirregWithName(name);
718 /* if this is at an absolute address, then get the address. */
719 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
720 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
721 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
724 /* Register wasn't found in hash, so let's create
725 * a new one and put it in the hash table AND in the
726 * dynDirectRegNames set */
727 if(!IS_CONFIG_ADDRESS(address)) {
728 //fprintf(stderr,"allocating new reg %s\n",name);
730 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
731 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
733 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
735 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
737 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
741 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
742 addSet(&dynDirectBitRegs, reg);
745 addSet(&dynDirectRegs, reg);
747 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
750 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
756 debugLog (" -- %s is declared at address 0x2007\n",name);
761 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
763 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
764 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
769 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
771 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
772 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
775 allocNewDirReg (OP_SYM_TYPE(op),name);
782 /*-----------------------------------------------------------------*/
783 /* allocRegByName - allocates register with given name */
784 /*-----------------------------------------------------------------*/
786 allocRegByName (char *name, int size)
792 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
796 /* First, search the hash table to see if there is a register with this name */
797 reg = dirregWithName(name);
803 /* Register wasn't found in hash, so let's create
804 * a new one and put it in the hash table AND in the
805 * dynDirectRegNames set */
806 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
807 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
808 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
809 if (strcmp(reg->name+1,sym->name)==0) {
810 unsigned a = SPEC_ADDR(sym->etype);
814 if (!IS_STATIC (sym->etype)) {
817 if (IS_EXTERN (sym->etype)) {
820 if (IS_BITVAR (sym->etype))
827 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
828 if (strcmp(reg->name+1,sym->name)==0) {
829 unsigned a = SPEC_ADDR(sym->etype);
831 if (!IS_STATIC (sym->etype)) {
834 if (IS_EXTERN (sym->etype)) {
837 if (IS_BITVAR (sym->etype))
845 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
847 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
848 if (reg->isBitField) {
849 addSet(&dynDirectBitRegs, reg);
851 addSet(&dynDirectRegs, reg);
857 /*-----------------------------------------------------------------*/
858 /* RegWithIdx - returns pointer to register with index number */
859 /*-----------------------------------------------------------------*/
861 typeRegWithIdx (int idx, int type, int fixed)
866 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
871 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
873 debugLog ("Found a Dynamic Register!\n");
876 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
877 debugLog ("Found a Direct Register!\n");
883 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
884 debugLog ("Found a Stack Register!\n");
888 werror (E_STACK_OUT, "Register");
889 /* return an existing register just to avoid the SDCC crash */
890 return regWithIdx ( dynStackRegs, 0x7f, fixed);
894 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
895 debugLog ("Found a Processor Register!\n");
909 /*-----------------------------------------------------------------*/
910 /* pic14_regWithIdx - returns pointer to register with index number*/
911 /*-----------------------------------------------------------------*/
913 pic14_regWithIdx (int idx)
917 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
920 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
926 /*-----------------------------------------------------------------*/
927 /* pic14_regWithIdx - returns pointer to register with index number */
928 /*-----------------------------------------------------------------*/
930 pic14_allocWithIdx (int idx)
935 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
937 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
939 debugLog ("Found a Dynamic Register!\n");
940 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
941 debugLog ("Found a Stack Register!\n");
942 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
943 debugLog ("Found a Processor Register!\n");
944 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
945 debugLog ("Found an Internal Register!\n");
946 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
947 debugLog ("Found an Internal Register!\n");
950 debugLog ("Dynamic Register not found\n");
953 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
954 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
955 "regWithIdx not found");
965 /*-----------------------------------------------------------------*/
966 /*-----------------------------------------------------------------*/
968 pic14_findFreeReg(short type)
975 if((dReg = regFindFree(dynAllocRegs)) != NULL)
977 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
981 if((dReg = regFindFree(dynStackRegs)) != NULL)
993 /*-----------------------------------------------------------------*/
994 /* freeReg - frees a register */
995 /*-----------------------------------------------------------------*/
999 debugLog ("%s\n", __FUNCTION__);
1004 /*-----------------------------------------------------------------*/
1005 /* nFreeRegs - returns number of free registers */
1006 /*-----------------------------------------------------------------*/
1008 nFreeRegs (int type)
1010 /* dynamically allocate as many as we need and worry about
1011 * fitting them into a PIC later */
1018 debugLog ("%s\n", __FUNCTION__);
1019 for (i = 0; i < pic14_nRegs; i++)
1020 if (regspic14[i].isFree && regspic14[i].type == type)
1026 /*-----------------------------------------------------------------*/
1027 /* nfreeRegsType - free registers with type */
1028 /*-----------------------------------------------------------------*/
1030 nfreeRegsType (int type)
1033 debugLog ("%s\n", __FUNCTION__);
1034 if (type == REG_PTR)
1036 if ((nfr = nFreeRegs (type)) == 0)
1037 return nFreeRegs (REG_GPR);
1040 return nFreeRegs (type);
1043 void writeSetUsedRegs(FILE *of, set *dRegs)
1048 for (dReg = setFirstItem(dRegs) ; dReg ;
1049 dReg = setNextItem(dRegs)) {
1052 fprintf (of, "\t%s\n",dReg->name);
1056 extern void assignFixedRegisters(set *regset);
1057 extern void assignRelocatableRegisters(set *regset,int used);
1058 extern void dump_map(void);
1059 extern void dump_sfr(FILE *of);
1061 void packBits(set *bregs)
1065 regs *bitfield=NULL;
1066 regs *relocbitfield=NULL;
1072 for (regset = bregs ; regset ;
1073 regset = regset->next) {
1075 breg = regset->item;
1076 breg->isBitField = 1;
1077 //fprintf(stderr,"bit reg: %s\n",breg->name);
1080 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1082 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1083 breg->rIdx = breg->address & 7;
1084 breg->address >>= 3;
1087 //sprintf (buffer, "fbitfield%02x", breg->address);
1088 sprintf (buffer, "0x%02x", breg->address);
1089 //fprintf(stderr,"new bit field\n");
1090 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1091 bitfield->isBitField = 1;
1092 bitfield->isFixed = 1;
1093 bitfield->address = breg->address;
1094 //addSet(&dynDirectRegs,bitfield);
1095 addSet(&dynInternalRegs,bitfield);
1096 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1098 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1101 breg->reg_alias = bitfield;
1105 if(!relocbitfield || bit_no >7) {
1108 sprintf (buffer, "bitfield%d", byte_no);
1109 //fprintf(stderr,"new relocatable bit field\n");
1110 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1111 relocbitfield->isBitField = 1;
1112 //addSet(&dynDirectRegs,relocbitfield);
1113 addSet(&dynInternalRegs,relocbitfield);
1114 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1118 breg->reg_alias = relocbitfield;
1119 breg->address = rDirectIdx; /* byte_no; */
1120 breg->rIdx = bit_no++;
1128 void bitEQUs(FILE *of, set *bregs)
1130 regs *breg,*bytereg;
1133 //fprintf(stderr," %s\n",__FUNCTION__);
1134 for (breg = setFirstItem(bregs) ; breg ;
1135 breg = setNextItem(bregs)) {
1137 //fprintf(stderr,"bit reg: %s\n",breg->name);
1139 bytereg = breg->reg_alias;
1141 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1144 breg->rIdx & 0x0007);
1147 //fprintf(stderr, "bit field is not assigned to a register\n");
1148 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1158 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1163 for (reg = setFirstItem(fregs) ; reg ;
1164 reg = setNextItem(fregs)) {
1166 //if(!reg->isEmitted && reg->wasUsed) {
1169 fprintf (of, "%s\tEQU\t0x%03x\n",
1173 fprintf (of, "%s\tEQU\t0x%03x\n",
1181 void writeUsedRegs(FILE *of)
1183 packBits(dynDirectBitRegs);
1185 assignFixedRegisters(dynInternalRegs);
1186 assignFixedRegisters(dynAllocRegs);
1187 assignFixedRegisters(dynStackRegs);
1188 assignFixedRegisters(dynDirectRegs);
1190 assignRelocatableRegisters(dynInternalRegs,0);
1191 assignRelocatableRegisters(dynAllocRegs,0);
1192 assignRelocatableRegisters(dynStackRegs,0);
1194 assignRelocatableRegisters(dynDirectRegs,0);
1196 assignRelocatableRegisters(dynDirectRegs,0);
1197 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1202 bitEQUs(of,dynDirectBitRegs);
1204 aliasEQUs(of,dynAllocRegs,0);
1205 aliasEQUs(of,dynDirectRegs,0);
1206 aliasEQUs(of,dynStackRegs,0);
1207 aliasEQUs(of,dynProcessorRegs,1);
1212 /*-----------------------------------------------------------------*/
1213 /* allDefsOutOfRange - all definitions are out of a range */
1214 /*-----------------------------------------------------------------*/
1216 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1220 debugLog ("%s\n", __FUNCTION__);
1224 for (i = 0; i < defs->size; i++)
1228 if (bitVectBitValue (defs, i) &&
1229 (ic = hTabItemWithKey (iCodehTab, i)) &&
1230 (ic->seq >= fseq && ic->seq <= toseq))
1240 /*-----------------------------------------------------------------*/
1241 /* computeSpillable - given a point find the spillable live ranges */
1242 /*-----------------------------------------------------------------*/
1244 computeSpillable (iCode * ic)
1248 debugLog ("%s\n", __FUNCTION__);
1249 /* spillable live ranges are those that are live at this
1250 point . the following categories need to be subtracted
1252 a) - those that are already spilt
1253 b) - if being used by this one
1254 c) - defined by this one */
1256 spillable = bitVectCopy (ic->rlive);
1258 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1260 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1261 bitVectUnSetBit (spillable, ic->defKey);
1262 spillable = bitVectIntersect (spillable, _G.regAssigned);
1267 /*-----------------------------------------------------------------*/
1268 /* noSpilLoc - return true if a variable has no spil location */
1269 /*-----------------------------------------------------------------*/
1271 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1273 debugLog ("%s\n", __FUNCTION__);
1274 return (sym->usl.spillLoc ? 0 : 1);
1277 /*-----------------------------------------------------------------*/
1278 /* hasSpilLoc - will return 1 if the symbol has spil location */
1279 /*-----------------------------------------------------------------*/
1281 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1283 debugLog ("%s\n", __FUNCTION__);
1284 return (sym->usl.spillLoc ? 1 : 0);
1287 /*-----------------------------------------------------------------*/
1288 /* directSpilLoc - will return 1 if the splilocation is in direct */
1289 /*-----------------------------------------------------------------*/
1291 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1293 debugLog ("%s\n", __FUNCTION__);
1294 if (sym->usl.spillLoc &&
1295 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1301 /*-----------------------------------------------------------------*/
1302 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1303 /* but is not used as a pointer */
1304 /*-----------------------------------------------------------------*/
1306 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1308 debugLog ("%s\n", __FUNCTION__);
1309 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1312 /*-----------------------------------------------------------------*/
1313 /* rematable - will return 1 if the remat flag is set */
1314 /*-----------------------------------------------------------------*/
1316 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1318 debugLog ("%s\n", __FUNCTION__);
1322 /*-----------------------------------------------------------------*/
1323 /* notUsedInRemaining - not used or defined in remain of the block */
1324 /*-----------------------------------------------------------------*/
1326 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1328 debugLog ("%s\n", __FUNCTION__);
1329 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1330 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1333 /*-----------------------------------------------------------------*/
1334 /* allLRs - return true for all */
1335 /*-----------------------------------------------------------------*/
1337 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1339 debugLog ("%s\n", __FUNCTION__);
1343 /*-----------------------------------------------------------------*/
1344 /* liveRangesWith - applies function to a given set of live range */
1345 /*-----------------------------------------------------------------*/
1347 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1348 eBBlock * ebp, iCode * ic)
1353 debugLog ("%s\n", __FUNCTION__);
1354 if (!lrs || !lrs->size)
1357 for (i = 1; i < lrs->size; i++)
1360 if (!bitVectBitValue (lrs, i))
1363 /* if we don't find it in the live range
1364 hash table we are in serious trouble */
1365 if (!(sym = hTabItemWithKey (liveRanges, i)))
1367 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1368 "liveRangesWith could not find liveRange");
1372 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1373 addSetHead (&rset, sym);
1380 /*-----------------------------------------------------------------*/
1381 /* leastUsedLR - given a set determines which is the least used */
1382 /*-----------------------------------------------------------------*/
1384 leastUsedLR (set * sset)
1386 symbol *sym = NULL, *lsym = NULL;
1388 debugLog ("%s\n", __FUNCTION__);
1389 sym = lsym = setFirstItem (sset);
1394 for (; lsym; lsym = setNextItem (sset))
1397 /* if usage is the same then prefer
1398 the spill the smaller of the two */
1399 if (lsym->used == sym->used)
1400 if (getSize (lsym->type) < getSize (sym->type))
1404 if (lsym->used < sym->used)
1409 setToNull ((void *) &sset);
1414 /*-----------------------------------------------------------------*/
1415 /* noOverLap - will iterate through the list looking for over lap */
1416 /*-----------------------------------------------------------------*/
1418 noOverLap (set * itmpStack, symbol * fsym)
1421 debugLog ("%s\n", __FUNCTION__);
1424 for (sym = setFirstItem (itmpStack); sym;
1425 sym = setNextItem (itmpStack))
1427 if (sym->liveTo > fsym->liveFrom)
1435 /*-----------------------------------------------------------------*/
1436 /* isFree - will return 1 if the a free spil location is found */
1437 /*-----------------------------------------------------------------*/
1442 V_ARG (symbol **, sloc);
1443 V_ARG (symbol *, fsym);
1445 debugLog ("%s\n", __FUNCTION__);
1446 /* if already found */
1450 /* if it is free && and the itmp assigned to
1451 this does not have any overlapping live ranges
1452 with the one currently being assigned and
1453 the size can be accomodated */
1455 noOverLap (sym->usl.itmpStack, fsym) &&
1456 getSize (sym->type) >= getSize (fsym->type))
1465 /*-----------------------------------------------------------------*/
1466 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1467 /*-----------------------------------------------------------------*/
1469 spillLRWithPtrReg (symbol * forSym)
1475 debugLog ("%s\n", __FUNCTION__);
1476 if (!_G.regAssigned ||
1477 bitVectIsZero (_G.regAssigned))
1480 r0 = pic14_regWithIdx (R0_IDX);
1481 r1 = pic14_regWithIdx (R1_IDX);
1483 /* for all live ranges */
1484 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1485 lrsym = hTabNextItem (liveRanges, &k))
1489 /* if no registers assigned to it or
1491 /* if it does not overlap with this then
1492 not need to spill it */
1494 if (lrsym->isspilt || !lrsym->nRegs ||
1495 (lrsym->liveTo < forSym->liveFrom))
1498 /* go thru the registers : if it is either
1499 r0 or r1 then spil it */
1500 for (j = 0; j < lrsym->nRegs; j++)
1501 if (lrsym->regs[j] == r0 ||
1502 lrsym->regs[j] == r1)
1511 /*-----------------------------------------------------------------*/
1512 /* createStackSpil - create a location on the stack to spil */
1513 /*-----------------------------------------------------------------*/
1515 createStackSpil (symbol * sym)
1517 symbol *sloc = NULL;
1518 int useXstack, model, noOverlay;
1520 char slocBuffer[30];
1521 debugLog ("%s\n", __FUNCTION__);
1525 /* first go try and find a free one that is already
1526 existing on the stack */
1527 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1529 /* found a free one : just update & return */
1530 sym->usl.spillLoc = sloc;
1533 addSetHead (&sloc->usl.itmpStack, sym);
1537 /* could not then have to create one , this is the hard part
1538 we need to allocate this on the stack : this is really a
1539 hack!! but cannot think of anything better at this time */
1541 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1543 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1544 __FILE__, __LINE__);
1548 sloc = newiTemp (slocBuffer);
1550 /* set the type to the spilling symbol */
1551 sloc->type = copyLinkChain (sym->type);
1552 sloc->etype = getSpec (sloc->type);
1553 SPEC_SCLS (sloc->etype) = S_DATA;
1554 SPEC_EXTR (sloc->etype) = 0;
1555 SPEC_STAT (sloc->etype) = 0;
1557 /* we don't allow it to be allocated`
1558 onto the external stack since : so we
1559 temporarily turn it off ; we also
1560 turn off memory model to prevent
1561 the spil from going to the external storage
1562 and turn off overlaying
1565 useXstack = options.useXstack;
1566 model = options.model;
1567 noOverlay = options.noOverlay;
1568 options.noOverlay = 1;
1569 options.model = options.useXstack = 0;
1573 options.useXstack = useXstack;
1574 options.model = model;
1575 options.noOverlay = noOverlay;
1576 sloc->isref = 1; /* to prevent compiler warning */
1578 /* if it is on the stack then update the stack */
1579 if (IN_STACK (sloc->etype))
1581 currFunc->stack += getSize (sloc->type);
1582 _G.stackExtend += getSize (sloc->type);
1585 _G.dataExtend += getSize (sloc->type);
1587 /* add it to the _G.stackSpil set */
1588 addSetHead (&_G.stackSpil, sloc);
1589 sym->usl.spillLoc = sloc;
1592 /* add it to the set of itempStack set
1593 of the spill location */
1594 addSetHead (&sloc->usl.itmpStack, sym);
1598 /*-----------------------------------------------------------------*/
1599 /* isSpiltOnStack - returns true if the spil location is on stack */
1600 /*-----------------------------------------------------------------*/
1602 isSpiltOnStack (symbol * sym)
1606 debugLog ("%s\n", __FUNCTION__);
1615 /* if (sym->_G.stackSpil) */
1618 if (!sym->usl.spillLoc)
1621 etype = getSpec (sym->usl.spillLoc->type);
1622 if (IN_STACK (etype))
1628 /*-----------------------------------------------------------------*/
1629 /* spillThis - spils a specific operand */
1630 /*-----------------------------------------------------------------*/
1632 spillThis (symbol * sym)
1635 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1636 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1638 /* if this is rematerializable or has a spillLocation
1639 we are okay, else we need to create a spillLocation
1641 if (!(sym->remat || sym->usl.spillLoc))
1642 createStackSpil (sym);
1645 /* mark it has spilt & put it in the spilt set */
1647 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1649 bitVectUnSetBit (_G.regAssigned, sym->key);
1651 for (i = 0; i < sym->nRegs; i++)
1655 freeReg (sym->regs[i]);
1656 sym->regs[i] = NULL;
1660 /* if spilt on stack then free up r0 & r1
1661 if they could have been assigned to some
1663 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1666 spillLRWithPtrReg (sym);
1669 if (sym->usl.spillLoc && !sym->remat)
1670 sym->usl.spillLoc->allocreq = 1;
1675 /*-----------------------------------------------------------------*/
1676 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1677 /*-----------------------------------------------------------------*/
1679 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1681 bitVect *lrcs = NULL;
1685 debugLog ("%s\n", __FUNCTION__);
1687 /* get the spillable live ranges */
1688 lrcs = computeSpillable (ic);
1691 /* get all live ranges that are rematerizable */
1692 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1694 /* return the least used of these */
1695 return leastUsedLR (selectS);
1698 /* get live ranges with spillLocations in direct space */
1699 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1701 sym = leastUsedLR (selectS);
1702 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1703 sym->usl.spillLoc->rname :
1704 sym->usl.spillLoc->name));
1706 /* mark it as allocation required */
1707 sym->usl.spillLoc->allocreq = 1;
1711 /* if the symbol is local to the block then */
1712 if (forSym->liveTo < ebp->lSeq)
1715 /* check if there are any live ranges allocated
1716 to registers that are not used in this block */
1717 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1719 sym = leastUsedLR (selectS);
1720 /* if this is not rematerializable */
1729 /* check if there are any live ranges that not
1730 used in the remainder of the block */
1731 if (!_G.blockSpil &&
1732 !isiCodeInFunctionCall (ic) &&
1733 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1735 sym = leastUsedLR (selectS);
1738 sym->remainSpil = 1;
1745 /* find live ranges with spillocation && not used as pointers */
1746 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1749 sym = leastUsedLR (selectS);
1750 /* mark this as allocation required */
1751 sym->usl.spillLoc->allocreq = 1;
1755 /* find live ranges with spillocation */
1756 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1759 sym = leastUsedLR (selectS);
1760 sym->usl.spillLoc->allocreq = 1;
1764 /* couldn't find then we need to create a spil
1765 location on the stack , for which one? the least
1767 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1770 /* return a created spil location */
1771 sym = createStackSpil (leastUsedLR (selectS));
1772 sym->usl.spillLoc->allocreq = 1;
1776 /* this is an extreme situation we will spill
1777 this one : happens very rarely but it does happen */
1783 /*-----------------------------------------------------------------*/
1784 /* spilSomething - spil some variable & mark registers as free */
1785 /*-----------------------------------------------------------------*/
1787 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1792 debugLog ("%s\n", __FUNCTION__);
1793 /* get something we can spil */
1794 ssym = selectSpil (ic, ebp, forSym);
1796 /* mark it as spilt */
1798 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1800 /* mark it as not register assigned &
1801 take it away from the set */
1802 bitVectUnSetBit (_G.regAssigned, ssym->key);
1804 /* mark the registers as free */
1805 for (i = 0; i < ssym->nRegs; i++)
1807 freeReg (ssym->regs[i]);
1809 /* if spilt on stack then free up r0 & r1
1810 if they could have been assigned to as gprs */
1811 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1814 spillLRWithPtrReg (ssym);
1817 /* if this was a block level spil then insert push & pop
1818 at the start & end of block respectively */
1819 if (ssym->blockSpil)
1821 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1822 /* add push to the start of the block */
1823 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1824 ebp->sch->next : ebp->sch));
1825 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1826 /* add pop to the end of the block */
1827 addiCodeToeBBlock (ebp, nic, NULL);
1830 /* if spilt because not used in the remainder of the
1831 block then add a push before this instruction and
1832 a pop at the end of the block */
1833 if (ssym->remainSpil)
1836 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1837 /* add push just before this instruction */
1838 addiCodeToeBBlock (ebp, nic, ic);
1840 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1841 /* add pop to the end of the block */
1842 addiCodeToeBBlock (ebp, nic, NULL);
1851 /*-----------------------------------------------------------------*/
1852 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1853 /*-----------------------------------------------------------------*/
1855 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1860 debugLog ("%s\n", __FUNCTION__);
1862 /* try for a ptr type */
1863 if ((reg = allocReg (REG_PTR)))
1866 /* try for gpr type */
1867 if ((reg = allocReg (REG_GPR)))
1870 /* we have to spil */
1871 if (!spilSomething (ic, ebp, sym))
1874 /* make sure partially assigned registers aren't reused */
1875 for (j=0; j<=sym->nRegs; j++)
1877 sym->regs[j]->isFree = 0;
1879 /* this looks like an infinite loop but
1880 in really selectSpil will abort */
1884 /*-----------------------------------------------------------------*/
1885 /* getRegGpr - will try for GPR if not spil */
1886 /*-----------------------------------------------------------------*/
1888 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1893 debugLog ("%s\n", __FUNCTION__);
1895 /* try for gpr type */
1896 if ((reg = allocReg (REG_GPR)))
1899 if (!pic14_ptrRegReq)
1900 if ((reg = allocReg (REG_PTR)))
1903 /* we have to spil */
1904 if (!spilSomething (ic, ebp, sym))
1907 /* make sure partially assigned registers aren't reused */
1908 for (j=0; j<=sym->nRegs; j++)
1910 sym->regs[j]->isFree = 0;
1912 /* this looks like an infinite loop but
1913 in really selectSpil will abort */
1917 /*-----------------------------------------------------------------*/
1918 /* symHasReg - symbol has a given register */
1919 /*-----------------------------------------------------------------*/
1921 symHasReg (symbol * sym, regs * reg)
1925 debugLog ("%s\n", __FUNCTION__);
1926 for (i = 0; i < sym->nRegs; i++)
1927 if (sym->regs[i] == reg)
1933 /*-----------------------------------------------------------------*/
1934 /* deassignLRs - check the live to and if they have registers & are */
1935 /* not spilt then free up the registers */
1936 /*-----------------------------------------------------------------*/
1938 deassignLRs (iCode * ic, eBBlock * ebp)
1944 debugLog ("%s\n", __FUNCTION__);
1945 for (sym = hTabFirstItem (liveRanges, &k); sym;
1946 sym = hTabNextItem (liveRanges, &k))
1949 symbol *psym = NULL;
1950 /* if it does not end here */
1951 if (sym->liveTo > ic->seq)
1954 /* Prevent the result from being assigned the same registers as (one)
1955 * operand as many genXXX-functions fail otherwise.
1956 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1957 * are known to fail. */
1958 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1962 case '=': /* assignment */
1963 case BITWISEAND: /* bitwise AND */
1964 case '|': /* bitwise OR */
1965 case '^': /* bitwise XOR */
1966 case '~': /* bitwise negate */
1967 case RLC: /* rotate through carry */
1970 case '+': /* addition */
1971 case '-': /* subtraction */
1972 /* go ahead, these are safe to use with
1973 * non-disjoint register sets */
1977 /* do not release operand registers */
1978 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1983 /* if it was spilt on stack then we can
1984 mark the stack spil location as free */
1989 sym->usl.spillLoc->isFree = 1;
1995 if (!bitVectBitValue (_G.regAssigned, sym->key))
1997 /* special case check if this is an IFX &
1998 the privious one was a pop and the
1999 previous one was not spilt then keep track
2001 if (ic->op == IFX && ic->prev &&
2002 ic->prev->op == IPOP &&
2003 !ic->prev->parmPush &&
2004 IS_SYMOP(IC_LEFT (ic->prev)) &&
2005 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2006 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2012 bitVectUnSetBit (_G.regAssigned, sym->key);
2014 /* if the result of this one needs registers
2015 and does not have it then assign it right
2017 if (IC_RESULT (ic) &&
2018 !(SKIP_IC2 (ic) || /* not a special icode */
2019 ic->op == JUMPTABLE ||
2024 POINTER_SET (ic)) &&
2025 IS_SYMOP (IC_RESULT (ic)) &&
2026 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2027 result->liveTo > ic->seq && /* and will live beyond this */
2028 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2029 result->liveFrom == ic->seq && /* does not start before here */
2030 result->regType == sym->regType && /* same register types */
2031 result->regType == sym->regType && /* same register types */
2032 result->nRegs && /* which needs registers */
2033 !result->isspilt && /* and does not already have them */
2035 !bitVectBitValue (_G.regAssigned, result->key) &&
2036 /* the number of free regs + number of regs in this LR
2037 can accomodate the what result Needs */
2038 ((nfreeRegsType (result->regType) +
2039 sym->nRegs) >= result->nRegs)
2043 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2045 result->regs[i] = sym->regs[i];
2047 result->regs[i] = getRegGpr (ic, ebp, result);
2049 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2053 /* free the remaining */
2054 for (; i < sym->nRegs; i++)
2058 if (!symHasReg (psym, sym->regs[i]))
2059 freeReg (sym->regs[i]);
2062 freeReg (sym->regs[i]);
2069 /*-----------------------------------------------------------------*/
2070 /* reassignLR - reassign this to registers */
2071 /*-----------------------------------------------------------------*/
2073 reassignLR (operand * op)
2075 symbol *sym = OP_SYMBOL (op);
2078 debugLog ("%s\n", __FUNCTION__);
2079 /* not spilt any more */
2080 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2081 bitVectUnSetBit (_G.spiltSet, sym->key);
2083 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2087 for (i = 0; i < sym->nRegs; i++)
2088 sym->regs[i]->isFree = 0;
2091 /*-----------------------------------------------------------------*/
2092 /* willCauseSpill - determines if allocating will cause a spill */
2093 /*-----------------------------------------------------------------*/
2095 willCauseSpill (int nr, int rt)
2097 debugLog ("%s\n", __FUNCTION__);
2098 /* first check if there are any avlb registers
2099 of te type required */
2102 /* special case for pointer type
2103 if pointer type not avlb then
2104 check for type gpr */
2105 if (nFreeRegs (rt) >= nr)
2107 if (nFreeRegs (REG_GPR) >= nr)
2112 if (pic14_ptrRegReq)
2114 if (nFreeRegs (rt) >= nr)
2119 if (nFreeRegs (REG_PTR) +
2120 nFreeRegs (REG_GPR) >= nr)
2125 debugLog (" ... yep it will (cause a spill)\n");
2126 /* it will cause a spil */
2130 /*-----------------------------------------------------------------*/
2131 /* positionRegs - the allocator can allocate same registers to res- */
2132 /* ult and operand, if this happens make sure they are in the same */
2133 /* position as the operand otherwise chaos results */
2134 /*-----------------------------------------------------------------*/
2136 positionRegs (symbol * result, symbol * opsym, int lineno)
2138 int count = min (result->nRegs, opsym->nRegs);
2139 int i, j = 0, shared = 0;
2141 debugLog ("%s\n", __FUNCTION__);
2142 /* if the result has been spilt then cannot share */
2147 /* first make sure that they actually share */
2148 for (i = 0; i < count; i++)
2150 for (j = 0; j < count; j++)
2152 if (result->regs[i] == opsym->regs[j] && i != j)
2162 regs *tmp = result->regs[i];
2163 result->regs[i] = result->regs[j];
2164 result->regs[j] = tmp;
2169 /*------------------------------------------------------------------*/
2170 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2171 /* it should either have registers or have beed spilled. Otherwise, */
2172 /* there was an uninitialized variable, so just spill this to get */
2173 /* the operand in a valid state. */
2174 /*------------------------------------------------------------------*/
2176 verifyRegsAssigned (operand *op, iCode * ic)
2181 if (!IS_ITEMP (op)) return;
2183 sym = OP_SYMBOL (op);
2184 if (sym->isspilt) return;
2185 if (!sym->nRegs) return;
2186 if (sym->regs[0]) return;
2188 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2189 sym->prereqv ? sym->prereqv->name : sym->name);
2194 /*-----------------------------------------------------------------*/
2195 /* serialRegAssign - serially allocate registers to the variables */
2196 /*-----------------------------------------------------------------*/
2198 serialRegAssign (eBBlock ** ebbs, int count)
2202 debugLog ("%s\n", __FUNCTION__);
2203 /* for all blocks */
2204 for (i = 0; i < count; i++)
2209 if (ebbs[i]->noPath &&
2210 (ebbs[i]->entryLabel != entryLabel &&
2211 ebbs[i]->entryLabel != returnLabel))
2214 /* of all instructions do */
2215 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2217 debugLog (" op: %s\n", decodeOp (ic->op));
2219 /* if this is an ipop that means some live
2220 range will have to be assigned again */
2222 reassignLR (IC_LEFT (ic));
2224 /* if result is present && is a true symbol */
2225 if (IC_RESULT (ic) && ic->op != IFX &&
2226 IS_TRUE_SYMOP (IC_RESULT (ic)))
2227 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2229 /* take away registers from live
2230 ranges that end at this instruction */
2231 deassignLRs (ic, ebbs[i]);
2233 /* some don't need registers */
2234 if (SKIP_IC2 (ic) ||
2235 ic->op == JUMPTABLE ||
2239 (IC_RESULT (ic) && POINTER_SET (ic)))
2242 /* now we need to allocate registers
2243 only for the result */
2244 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2246 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2252 /* Make sure any spill location is definately allocated */
2253 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2254 !sym->usl.spillLoc->allocreq)
2256 sym->usl.spillLoc->allocreq++;
2259 /* if it does not need or is spilt
2260 or is already assigned to registers
2261 or will not live beyond this instructions */
2264 bitVectBitValue (_G.regAssigned, sym->key) ||
2265 sym->liveTo <= ic->seq)
2268 /* if some liverange has been spilt at the block level
2269 and this one live beyond this block then spil this
2271 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2276 /* if trying to allocate this will cause
2277 a spill and there is nothing to spill
2278 or this one is rematerializable then
2280 willCS = willCauseSpill (sym->nRegs, sym->regType);
2281 spillable = computeSpillable (ic);
2283 (willCS && bitVectIsZero (spillable)))
2291 /* If the live range preceeds the point of definition
2292 then ideally we must take into account registers that
2293 have been allocated after sym->liveFrom but freed
2294 before ic->seq. This is complicated, so spill this
2295 symbol instead and let fillGaps handle the allocation. */
2296 if (sym->liveFrom < ic->seq)
2302 /* if it has a spillocation & is used less than
2303 all other live ranges then spill this */
2305 if (sym->usl.spillLoc) {
2306 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2307 allLRs, ebbs[i], ic));
2308 if (leastUsed && leastUsed->used > sym->used) {
2313 /* if none of the liveRanges have a spillLocation then better
2314 to spill this one than anything else already assigned to registers */
2315 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2316 /* if this is local to this block then we might find a block spil */
2317 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2325 if (ic->op == RECEIVE)
2326 debugLog ("When I get clever, I'll optimize the receive logic\n");
2328 /* if we need ptr regs for the right side
2330 if (POINTER_GET (ic)
2331 && IS_SYMOP(IC_LEFT(ic))
2332 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2333 <= (unsigned) PTRSIZE)
2338 /* else we assign registers to it */
2339 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2341 debugLog (" %d - \n", __LINE__);
2343 bitVectDebugOn(_G.regAssigned, debugF);
2344 for (j = 0; j < sym->nRegs; j++)
2346 if (sym->regType == REG_PTR)
2347 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2349 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2351 /* if the allocation failed which means
2352 this was spilt then break */
2356 debugLog (" %d - \n", __LINE__);
2358 /* if it shares registers with operands make sure
2359 that they are in the same position */
2360 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2361 IS_SYMOP(IC_RESULT(ic)) &&
2362 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2363 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2364 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2365 /* do the same for the right operand */
2366 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2367 IS_SYMOP(IC_RESULT(ic)) &&
2368 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2369 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2370 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2372 debugLog (" %d - \n", __LINE__);
2375 debugLog (" %d - \n", __LINE__);
2384 /* Check for and fix any problems with uninitialized operands */
2385 for (i = 0; i < count; i++)
2389 if (ebbs[i]->noPath &&
2390 (ebbs[i]->entryLabel != entryLabel &&
2391 ebbs[i]->entryLabel != returnLabel))
2394 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2401 verifyRegsAssigned (IC_COND (ic), ic);
2405 if (ic->op == JUMPTABLE)
2407 verifyRegsAssigned (IC_JTCOND (ic), ic);
2411 verifyRegsAssigned (IC_RESULT (ic), ic);
2412 verifyRegsAssigned (IC_LEFT (ic), ic);
2413 verifyRegsAssigned (IC_RIGHT (ic), ic);
2419 /*-----------------------------------------------------------------*/
2420 /* rUmaskForOp :- returns register mask for an operand */
2421 /*-----------------------------------------------------------------*/
2423 rUmaskForOp (operand * op)
2429 debugLog ("%s\n", __FUNCTION__);
2430 /* only temporaries are assigned registers */
2434 sym = OP_SYMBOL (op);
2436 /* if spilt or no registers assigned to it
2438 if (sym->isspilt || !sym->nRegs)
2441 rumask = newBitVect (pic14_nRegs);
2443 for (j = 0; j < sym->nRegs; j++)
2445 rumask = bitVectSetBit (rumask,
2446 sym->regs[j]->rIdx);
2452 /*-----------------------------------------------------------------*/
2453 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2454 /*-----------------------------------------------------------------*/
2456 regsUsedIniCode (iCode * ic)
2458 bitVect *rmask = newBitVect (pic14_nRegs);
2460 debugLog ("%s\n", __FUNCTION__);
2461 /* do the special cases first */
2464 rmask = bitVectUnion (rmask,
2465 rUmaskForOp (IC_COND (ic)));
2469 /* for the jumptable */
2470 if (ic->op == JUMPTABLE)
2472 rmask = bitVectUnion (rmask,
2473 rUmaskForOp (IC_JTCOND (ic)));
2478 /* of all other cases */
2480 rmask = bitVectUnion (rmask,
2481 rUmaskForOp (IC_LEFT (ic)));
2485 rmask = bitVectUnion (rmask,
2486 rUmaskForOp (IC_RIGHT (ic)));
2489 rmask = bitVectUnion (rmask,
2490 rUmaskForOp (IC_RESULT (ic)));
2496 /*-----------------------------------------------------------------*/
2497 /* createRegMask - for each instruction will determine the regsUsed */
2498 /*-----------------------------------------------------------------*/
2500 createRegMask (eBBlock ** ebbs, int count)
2504 debugLog ("%s\n", __FUNCTION__);
2505 /* for all blocks */
2506 for (i = 0; i < count; i++)
2510 if (ebbs[i]->noPath &&
2511 (ebbs[i]->entryLabel != entryLabel &&
2512 ebbs[i]->entryLabel != returnLabel))
2515 /* for all instructions */
2516 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2521 if (SKIP_IC2 (ic) || !ic->rlive)
2524 /* first mark the registers used in this
2526 ic->rUsed = regsUsedIniCode (ic);
2527 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2529 /* now create the register mask for those
2530 registers that are in use : this is a
2531 super set of ic->rUsed */
2532 ic->rMask = newBitVect (pic14_nRegs + 1);
2534 /* for all live Ranges alive at this point */
2535 for (j = 1; j < ic->rlive->size; j++)
2540 /* if not alive then continue */
2541 if (!bitVectBitValue (ic->rlive, j))
2544 /* find the live range we are interested in */
2545 if (!(sym = hTabItemWithKey (liveRanges, j)))
2547 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2548 "createRegMask cannot find live range");
2552 /* if no register assigned to it */
2553 if (!sym->nRegs || sym->isspilt)
2556 /* for all the registers allocated to it */
2557 for (k = 0; k < sym->nRegs; k++)
2560 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2566 /* This was the active version */
2567 /*-----------------------------------------------------------------*/
2568 /* rematStr - returns the rematerialized string for a remat var */
2569 /*-----------------------------------------------------------------*/
2571 rematStr (symbol * sym)
2574 iCode *ic = sym->rematiCode;
2575 symbol *psym = NULL;
2577 debugLog ("%s\n", __FUNCTION__);
2579 //printf ("%s\n", s);
2581 /* if plus or minus print the right hand side */
2583 if (ic->op == '+' || ic->op == '-') {
2585 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2587 sprintf (s, "(%s %c 0x%04x)",
2588 OP_SYMBOL (IC_LEFT (ric))->rname,
2590 (int) operandLitValue (IC_RIGHT (ic)));
2593 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2595 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2596 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2601 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2602 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2604 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2610 /* deprecated version */
2611 /*-----------------------------------------------------------------*/
2612 /* rematStr - returns the rematerialized string for a remat var */
2613 /*-----------------------------------------------------------------*/
2615 rematStr (symbol * sym)
2618 iCode *ic = sym->rematiCode;
2620 debugLog ("%s\n", __FUNCTION__);
2625 /* if plus or minus print the right hand side */
2627 if (ic->op == '+' || ic->op == '-') {
2628 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2631 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2635 if (ic->op == '+' || ic->op == '-')
2637 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2638 sprintf (s, "(%s %c 0x%04x)",
2639 OP_SYMBOL (IC_LEFT (ric))->rname,
2641 (int) operandLitValue (IC_RIGHT (ic)));
2644 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2646 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2650 /* we reached the end */
2651 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2655 printf ("%s\n", buffer);
2660 /*-----------------------------------------------------------------*/
2661 /* regTypeNum - computes the type & number of registers required */
2662 /*-----------------------------------------------------------------*/
2670 debugLog ("%s\n", __FUNCTION__);
2671 /* for each live range do */
2672 for (sym = hTabFirstItem (liveRanges, &k); sym;
2673 sym = hTabNextItem (liveRanges, &k)) {
2675 debugLog (" %d - %s\n", __LINE__, sym->rname);
2677 /* if used zero times then no registers needed */
2678 if ((sym->liveTo - sym->liveFrom) == 0)
2682 /* if the live range is a temporary */
2685 debugLog (" %d - itemp register\n", __LINE__);
2687 /* if the type is marked as a conditional */
2688 if (sym->regType == REG_CND)
2691 /* if used in return only then we don't
2694 if (IS_AGGREGATE (sym->type) || sym->isptr)
2695 sym->type = aggrToPtr (sym->type, FALSE);
2696 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2702 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2703 // sym->type = aggrToPtr (sym->type, FALSE);
2704 debugLog (" %d - used as a return\n", __LINE__);
2709 /* if the symbol has only one definition &
2710 that definition is a get_pointer and the
2711 pointer we are getting is rematerializable and
2715 if (bitVectnBitsOn (sym->defs) == 1 &&
2716 (ic = hTabItemWithKey (iCodehTab,
2717 bitVectFirstBit (sym->defs))) &&
2719 !IS_BITVAR (sym->etype) &&
2720 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2722 if (ptrPseudoSymSafe (sym, ic)) {
2726 debugLog (" %d - \n", __LINE__);
2728 /* create a psuedo symbol & force a spil */
2729 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2730 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2731 psym->type = sym->type;
2732 psym->etype = sym->etype;
2733 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2734 strcpy (psym->rname, psym->name);
2736 sym->usl.spillLoc = psym;
2740 /* if in data space or idata space then try to
2741 allocate pointer register */
2746 /* if not then we require registers */
2747 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2748 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2749 getSize (sym->type));
2752 if(IS_PTR_CONST (sym->type)) {
2753 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2757 if (sym->nRegs > 4) {
2758 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2759 printTypeChain (sym->type, stderr);
2760 fprintf (stderr, "\n");
2763 /* determine the type of register required */
2764 if (sym->nRegs == 1 &&
2765 IS_PTR (sym->type) &&
2767 sym->regType = REG_PTR;
2769 sym->regType = REG_GPR;
2772 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2776 /* for the first run we don't provide */
2777 /* registers for true symbols we will */
2778 /* see how things go */
2783 DEFSETFUNC (markRegFree)
2785 ((regs *)item)->isFree = 1;
2790 DEFSETFUNC (deallocReg)
2792 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2793 ((regs *)item)->isFree = 1;
2794 ((regs *)item)->wasUsed = 0;
2798 /*-----------------------------------------------------------------*/
2799 /* freeAllRegs - mark all registers as free */
2800 /*-----------------------------------------------------------------*/
2802 pic14_freeAllRegs ()
2806 debugLog ("%s\n", __FUNCTION__);
2808 applyToSet(dynAllocRegs,markRegFree);
2809 applyToSet(dynStackRegs,markRegFree);
2812 for (i = 0; i < pic14_nRegs; i++)
2813 regspic14[i].isFree = 1;
2817 /*-----------------------------------------------------------------*/
2818 /*-----------------------------------------------------------------*/
2820 pic14_deallocateAllRegs ()
2824 debugLog ("%s\n", __FUNCTION__);
2826 applyToSet(dynAllocRegs,deallocReg);
2829 for (i = 0; i < pic14_nRegs; i++) {
2830 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2831 regspic14[i].isFree = 1;
2832 regspic14[i].wasUsed = 0;
2839 /*-----------------------------------------------------------------*/
2840 /* deallocStackSpil - this will set the stack pointer back */
2841 /*-----------------------------------------------------------------*/
2843 DEFSETFUNC (deallocStackSpil)
2847 debugLog ("%s\n", __FUNCTION__);
2852 /*-----------------------------------------------------------------*/
2853 /* farSpacePackable - returns the packable icode for far variables */
2854 /*-----------------------------------------------------------------*/
2856 farSpacePackable (iCode * ic)
2860 debugLog ("%s\n", __FUNCTION__);
2861 /* go thru till we find a definition for the
2862 symbol on the right */
2863 for (dic = ic->prev; dic; dic = dic->prev)
2866 /* if the definition is a call then no */
2867 if ((dic->op == CALL || dic->op == PCALL) &&
2868 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2873 /* if shift by unknown amount then not */
2874 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2875 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2878 /* if pointer get and size > 1 */
2879 if (POINTER_GET (dic) &&
2880 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2883 if (POINTER_SET (dic) &&
2884 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2887 /* if any three is a true symbol in far space */
2888 if (IC_RESULT (dic) &&
2889 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2890 isOperandInFarSpace (IC_RESULT (dic)))
2893 if (IC_RIGHT (dic) &&
2894 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2895 isOperandInFarSpace (IC_RIGHT (dic)) &&
2896 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2899 if (IC_LEFT (dic) &&
2900 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2901 isOperandInFarSpace (IC_LEFT (dic)) &&
2902 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2905 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2907 if ((dic->op == LEFT_OP ||
2908 dic->op == RIGHT_OP ||
2910 IS_OP_LITERAL (IC_RIGHT (dic)))
2920 /*-----------------------------------------------------------------*/
2921 /* packRegsForAssign - register reduction for assignment */
2922 /*-----------------------------------------------------------------*/
2924 packRegsForAssign (iCode * ic, eBBlock * ebp)
2929 debugLog ("%s\n", __FUNCTION__);
2931 debugAopGet (" result:", IC_RESULT (ic));
2932 debugAopGet (" left:", IC_LEFT (ic));
2933 debugAopGet (" right:", IC_RIGHT (ic));
2935 /* if this is at an absolute address, then get the address. */
2936 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2937 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2938 debugLog (" %d - found config word declaration\n", __LINE__);
2939 if(IS_VALOP(IC_RIGHT(ic))) {
2940 debugLog (" setting config word to %x\n",
2941 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2942 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2943 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2946 /* remove the assignment from the iCode chain. */
2948 remiCodeFromeBBlock (ebp, ic);
2949 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2950 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2957 if (!IS_ITEMP (IC_RESULT (ic))) {
2958 allocDirReg(IC_RESULT (ic));
2959 debugLog (" %d - result is not temp\n", __LINE__);
2962 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2963 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2964 allocDirReg(IC_LEFT (ic));
2968 if (!IS_ITEMP (IC_RIGHT (ic))) {
2969 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2971 /* only pack if this is not a function pointer */
2972 if (!IS_REF (IC_RIGHT (ic)))
2973 allocDirReg(IC_RIGHT (ic));
2977 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2978 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2980 debugLog (" %d - not packing - right side fails \n", __LINE__);
2984 /* if the true symbol is defined in far space or on stack
2985 then we should not since this will increase register pressure */
2986 if (isOperandInFarSpace (IC_RESULT (ic)))
2988 if ((dic = farSpacePackable (ic)))
2994 /* find the definition of iTempNN scanning backwards if we find a
2995 a use of the true symbol before we find the definition then
2997 for (dic = ic->prev; dic; dic = dic->prev)
3000 /* if there is a function call and this is
3001 a parameter & not my parameter then don't pack it */
3002 if ((dic->op == CALL || dic->op == PCALL) &&
3003 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3004 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3006 debugLog (" %d - \n", __LINE__);
3014 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3015 IS_OP_VOLATILE (IC_RESULT (dic)))
3017 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3022 if (IS_SYMOP (IC_RESULT (dic)) &&
3023 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3025 /* A previous result was assigned to the same register - we'll our definition */
3026 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3027 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3028 if (POINTER_SET (dic))
3034 if (IS_SYMOP (IC_RIGHT (dic)) &&
3035 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3036 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3038 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3043 if (IS_SYMOP (IC_LEFT (dic)) &&
3044 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3045 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3047 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3052 if (POINTER_SET (dic) &&
3053 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3055 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3063 return 0; /* did not find */
3065 /* if the result is on stack or iaccess then it must be
3066 the same at least one of the operands */
3067 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3068 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3071 /* the operation has only one symbol
3072 operator then we can pack */
3073 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3074 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3077 if (!((IC_LEFT (dic) &&
3078 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3080 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3084 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3085 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3086 /* found the definition */
3087 /* replace the result with the result of */
3088 /* this assignment and remove this assignment */
3089 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3090 IC_RESULT (dic) = IC_RESULT (ic);
3092 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3094 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3096 /* delete from liverange table also
3097 delete from all the points inbetween and the new
3099 for (sic = dic; sic != ic; sic = sic->next)
3101 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3102 if (IS_ITEMP (IC_RESULT (dic)))
3103 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3106 remiCodeFromeBBlock (ebp, ic);
3107 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3108 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3109 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3115 /*-----------------------------------------------------------------*/
3116 /* findAssignToSym : scanning backwards looks for first assig found */
3117 /*-----------------------------------------------------------------*/
3119 findAssignToSym (operand * op, iCode * ic)
3123 debugLog ("%s\n", __FUNCTION__);
3124 for (dic = ic->prev; dic; dic = dic->prev)
3127 /* if definition by assignment */
3128 if (dic->op == '=' &&
3129 !POINTER_SET (dic) &&
3130 IC_RESULT (dic)->key == op->key
3131 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3135 /* we are interested only if defined in far space */
3136 /* or in stack space in case of + & - */
3138 /* if assigned to a non-symbol then return
3140 if (!IS_SYMOP (IC_RIGHT (dic)))
3143 /* if the symbol is in far space then
3145 if (isOperandInFarSpace (IC_RIGHT (dic)))
3148 /* for + & - operations make sure that
3149 if it is on the stack it is the same
3150 as one of the three operands */
3151 if ((ic->op == '+' || ic->op == '-') &&
3152 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3155 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3156 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3157 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3165 /* if we find an usage then we cannot delete it */
3166 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3169 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3172 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3176 /* now make sure that the right side of dic
3177 is not defined between ic & dic */
3180 iCode *sic = dic->next;
3182 for (; sic != ic; sic = sic->next)
3183 if (IC_RESULT (sic) &&
3184 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3193 /*-----------------------------------------------------------------*/
3194 /* packRegsForSupport :- reduce some registers for support calls */
3195 /*-----------------------------------------------------------------*/
3197 packRegsForSupport (iCode * ic, eBBlock * ebp)
3201 debugLog ("%s\n", __FUNCTION__);
3202 /* for the left & right operand :- look to see if the
3203 left was assigned a true symbol in far space in that
3204 case replace them */
3205 if (IS_ITEMP (IC_LEFT (ic)) &&
3206 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3208 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3214 debugAopGet ("removing left:", IC_LEFT (ic));
3216 /* found it we need to remove it from the
3218 for (sic = dic; sic != ic; sic = sic->next)
3219 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3221 IC_LEFT (ic)->operand.symOperand =
3222 IC_RIGHT (dic)->operand.symOperand;
3223 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3224 remiCodeFromeBBlock (ebp, dic);
3225 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3226 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3230 /* do the same for the right operand */
3233 IS_ITEMP (IC_RIGHT (ic)) &&
3234 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3236 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3242 /* if this is a subtraction & the result
3243 is a true symbol in far space then don't pack */
3244 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3246 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3247 if (IN_FARSPACE (SPEC_OCLS (etype)))
3251 debugAopGet ("removing right:", IC_RIGHT (ic));
3253 /* found it we need to remove it from the
3255 for (sic = dic; sic != ic; sic = sic->next)
3256 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3258 IC_RIGHT (ic)->operand.symOperand =
3259 IC_RIGHT (dic)->operand.symOperand;
3260 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3262 remiCodeFromeBBlock (ebp, dic);
3263 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3264 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3271 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3274 /*-----------------------------------------------------------------*/
3275 /* packRegsForOneuse : - will reduce some registers for single Use */
3276 /*-----------------------------------------------------------------*/
3278 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3283 debugLog ("%s\n", __FUNCTION__);
3284 /* if returning a literal then do nothing */
3288 /* only upto 2 bytes since we cannot predict
3289 the usage of b, & acc */
3290 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3295 /* this routine will mark the a symbol as used in one
3296 instruction use only && if the definition is local
3297 (ie. within the basic block) && has only one definition &&
3298 that definition is either a return value from a
3299 function or does not contain any variables in
3301 uses = bitVectCopy (OP_USES (op));
3302 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3303 if (!bitVectIsZero (uses)) /* has other uses */
3306 /* if it has only one defintion */
3307 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3308 return NULL; /* has more than one definition */
3310 /* get that definition */
3312 hTabItemWithKey (iCodehTab,
3313 bitVectFirstBit (OP_DEFS (op)))))
3316 /* found the definition now check if it is local */
3317 if (dic->seq < ebp->fSeq ||
3318 dic->seq > ebp->lSeq)
3319 return NULL; /* non-local */
3321 /* now check if it is the return from
3323 if (dic->op == CALL || dic->op == PCALL)
3325 if (ic->op != SEND && ic->op != RETURN &&
3326 !POINTER_SET(ic) && !POINTER_GET(ic))
3328 OP_SYMBOL (op)->ruonly = 1;
3335 /* otherwise check that the definition does
3336 not contain any symbols in far space */
3337 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3338 isOperandInFarSpace (IC_RIGHT (dic)) ||
3339 IS_OP_RUONLY (IC_LEFT (ic)) ||
3340 IS_OP_RUONLY (IC_RIGHT (ic)))
3345 /* if pointer set then make sure the pointer
3347 if (POINTER_SET (dic) &&
3348 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3351 if (POINTER_GET (dic) &&
3352 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3357 /* also make sure the intervenening instructions
3358 don't have any thing in far space */
3359 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3362 /* if there is an intervening function call then no */
3363 if (dic->op == CALL || dic->op == PCALL)
3365 /* if pointer set then make sure the pointer
3367 if (POINTER_SET (dic) &&
3368 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3371 if (POINTER_GET (dic) &&
3372 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3375 /* if address of & the result is remat then okay */
3376 if (dic->op == ADDRESS_OF &&
3377 OP_SYMBOL (IC_RESULT (dic))->remat)
3380 /* if operand has size of three or more & this
3381 operation is a '*','/' or '%' then 'b' may
3383 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3384 getSize (operandType (op)) >= 3)
3387 /* if left or right or result is in far space */
3388 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3389 isOperandInFarSpace (IC_RIGHT (dic)) ||
3390 isOperandInFarSpace (IC_RESULT (dic)) ||
3391 IS_OP_RUONLY (IC_LEFT (dic)) ||
3392 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3393 IS_OP_RUONLY (IC_RESULT (dic)))
3399 OP_SYMBOL (op)->ruonly = 1;
3404 /*-----------------------------------------------------------------*/
3405 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3406 /*-----------------------------------------------------------------*/
3408 isBitwiseOptimizable (iCode * ic)
3410 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3411 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3413 debugLog ("%s\n", __FUNCTION__);
3414 /* bitwise operations are considered optimizable
3415 under the following conditions (Jean-Louis VERN)
3427 if (IS_LITERAL (rtype) ||
3428 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3434 /*-----------------------------------------------------------------*/
3435 /* packRegsForAccUse - pack registers for acc use */
3436 /*-----------------------------------------------------------------*/
3438 packRegsForAccUse (iCode * ic)
3442 debugLog ("%s\n", __FUNCTION__);
3444 /* result too large for WREG? */
3445 if (getSize (operandType (IC_RESULT (ic))) > 1)
3448 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3449 * is never used as an operand to an instruction that
3450 * cannot have WREG as an operand (e.g. BTFSx cannot
3451 * operate on WREG...
3452 * For now, store all results into proper registers. */
3456 /* if this is an aggregate, e.g. a one byte char array */
3457 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3460 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3462 /* if + or - then it has to be one byte result */
3463 if ((ic->op == '+' || ic->op == '-')
3464 && getSize (operandType (IC_RESULT (ic))) > 1)
3467 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3468 /* if shift operation make sure right side is not a literal */
3469 if (ic->op == RIGHT_OP &&
3470 (isOperandLiteral (IC_RIGHT (ic)) ||
3471 getSize (operandType (IC_RESULT (ic))) > 1))
3474 if (ic->op == LEFT_OP &&
3475 (isOperandLiteral (IC_RIGHT (ic)) ||
3476 getSize (operandType (IC_RESULT (ic))) > 1))
3479 if (IS_BITWISE_OP (ic) &&
3480 getSize (operandType (IC_RESULT (ic))) > 1)
3484 /* has only one definition */
3485 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3488 /* has only one use */
3489 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3492 /* and the usage immediately follows this iCode */
3493 if (!(uic = hTabItemWithKey (iCodehTab,
3494 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3497 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3498 if (ic->next != uic)
3501 /* if it is a conditional branch then we definitely can */
3505 if (uic->op == JUMPTABLE)
3508 /* if the usage is not is an assignment
3509 or an arithmetic / bitwise / shift operation then not */
3510 if (POINTER_SET (uic) &&
3511 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3514 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3515 if (uic->op != '=' &&
3516 !IS_ARITHMETIC_OP (uic) &&
3517 !IS_BITWISE_OP (uic) &&
3518 uic->op != LEFT_OP &&
3519 uic->op != RIGHT_OP)
3522 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3523 /* if used in ^ operation then make sure right is not a
3525 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3528 /* if shift operation make sure right side is not a literal */
3529 if (uic->op == RIGHT_OP &&
3530 (isOperandLiteral (IC_RIGHT (uic)) ||
3531 getSize (operandType (IC_RESULT (uic))) > 1))
3534 if (uic->op == LEFT_OP &&
3535 (isOperandLiteral (IC_RIGHT (uic)) ||
3536 getSize (operandType (IC_RESULT (uic))) > 1))
3539 /* make sure that the result of this icode is not on the
3540 stack, since acc is used to compute stack offset */
3541 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3542 OP_SYMBOL (IC_RESULT (uic))->onStack)
3545 /* if either one of them in far space then we cannot */
3546 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3547 isOperandInFarSpace (IC_LEFT (uic))) ||
3548 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3549 isOperandInFarSpace (IC_RIGHT (uic))))
3552 /* if the usage has only one operand then we can */
3553 if (IC_LEFT (uic) == NULL ||
3554 IC_RIGHT (uic) == NULL)
3557 /* make sure this is on the left side if not
3558 a '+' since '+' is commutative */
3559 if (ic->op != '+' &&
3560 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3563 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3564 /* if one of them is a literal then we can */
3565 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3566 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3567 (getSize (operandType (IC_RESULT (uic))) <= 1))
3569 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3573 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3574 /* if the other one is not on stack then we can */
3575 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3576 (IS_ITEMP (IC_RIGHT (uic)) ||
3577 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3578 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3581 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3582 (IS_ITEMP (IC_LEFT (uic)) ||
3583 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3584 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3590 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3591 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3595 /*-----------------------------------------------------------------*/
3596 /* packForPush - hueristics to reduce iCode for pushing */
3597 /*-----------------------------------------------------------------*/
3599 packForReceive (iCode * ic, eBBlock * ebp)
3603 debugLog ("%s\n", __FUNCTION__);
3604 debugAopGet (" result:", IC_RESULT (ic));
3605 debugAopGet (" left:", IC_LEFT (ic));
3606 debugAopGet (" right:", IC_RIGHT (ic));
3611 for (dic = ic->next; dic; dic = dic->next)
3616 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3617 debugLog (" used on left\n");
3618 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3619 debugLog (" used on right\n");
3620 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3621 debugLog (" used on result\n");
3623 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3624 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3629 debugLog (" hey we can remove this unnecessary assign\n");
3631 /*-----------------------------------------------------------------*/
3632 /* packForPush - hueristics to reduce iCode for pushing */
3633 /*-----------------------------------------------------------------*/
3635 packForPush (iCode * ic, eBBlock * ebp)
3639 debugLog ("%s\n", __FUNCTION__);
3640 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3643 /* must have only definition & one usage */
3644 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3645 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3648 /* find the definition */
3649 if (!(dic = hTabItemWithKey (iCodehTab,
3650 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3653 if (dic->op != '=' || POINTER_SET (dic))
3656 /* we now we know that it has one & only one def & use
3657 and the that the definition is an assignment */
3658 IC_LEFT (ic) = IC_RIGHT (dic);
3660 remiCodeFromeBBlock (ebp, dic);
3661 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3662 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3665 void printSymType(char * str, sym_link *sl)
3667 debugLog (" %s Symbol type: ",str);
3668 printTypeChain( sl, debugF);
3673 /*-----------------------------------------------------------------*/
3674 /* some debug code to print the symbol S_TYPE. Note that
3675 * the function checkSClass in src/SDCCsymt.c dinks with
3676 * the S_TYPE in ways the PIC port doesn't fully like...*/
3677 /*-----------------------------------------------------------------*/
3678 void isData(sym_link *sl)
3688 for ( ; sl; sl=sl->next) {
3690 switch (SPEC_SCLS(sl)) {
3692 case S_DATA: fprintf (of, "data "); break;
3693 case S_XDATA: fprintf (of, "xdata "); break;
3694 case S_SFR: fprintf (of, "sfr "); break;
3695 case S_SBIT: fprintf (of, "sbit "); break;
3696 case S_CODE: fprintf (of, "code "); break;
3697 case S_IDATA: fprintf (of, "idata "); break;
3698 case S_PDATA: fprintf (of, "pdata "); break;
3699 case S_LITERAL: fprintf (of, "literal "); break;
3700 case S_STACK: fprintf (of, "stack "); break;
3701 case S_XSTACK: fprintf (of, "xstack "); break;
3702 case S_BIT: fprintf (of, "bit "); break;
3703 case S_EEPROM: fprintf (of, "eeprom "); break;
3713 /*-----------------------------------------------------------------*/
3714 /* packRegisters - does some transformations to reduce register */
3716 /*-----------------------------------------------------------------*/
3718 packRegisters (eBBlock * ebp)
3723 debugLog ("%s\n", __FUNCTION__);
3729 /* look for assignments of the form */
3730 /* iTempNN = TRueSym (someoperation) SomeOperand */
3732 /* TrueSym := iTempNN:1 */
3733 for (ic = ebp->sch; ic; ic = ic->next)
3736 /* find assignment of the form TrueSym := iTempNN:1 */
3737 if (ic->op == '=' && !POINTER_SET (ic))
3738 change += packRegsForAssign (ic, ebp);
3742 if (POINTER_SET (ic))
3743 debugLog ("pointer is set\n");
3744 debugAopGet (" result:", IC_RESULT (ic));
3745 debugAopGet (" left:", IC_LEFT (ic));
3746 debugAopGet (" right:", IC_RIGHT (ic));
3755 for (ic = ebp->sch; ic; ic = ic->next) {
3757 if(IS_SYMOP ( IC_LEFT(ic))) {
3758 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3760 debugAopGet (" left:", IC_LEFT (ic));
3761 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3762 debugLog (" is a pointer\n");
3764 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3765 debugLog (" is volatile\n");
3769 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3772 if(IS_SYMOP ( IC_RIGHT(ic))) {
3773 debugAopGet (" right:", IC_RIGHT (ic));
3774 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3777 if(IS_SYMOP ( IC_RESULT(ic))) {
3778 debugAopGet (" result:", IC_RESULT (ic));
3779 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3782 if (POINTER_SET (ic))
3783 debugLog (" %d - Pointer set\n", __LINE__);
3786 /* Look for two subsequent iCodes with */
3788 /* _c = iTemp & op; */
3789 /* and replace them by */
3792 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3794 ic->prev->op == '=' &&
3795 IS_ITEMP (IC_LEFT (ic)) &&
3796 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3797 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3799 iCode* ic_prev = ic->prev;
3800 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3802 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3803 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3805 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3806 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3807 prev_result_sym->liveTo == ic->seq)
3809 prev_result_sym->liveTo = ic_prev->seq;
3812 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3814 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3816 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3818 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3819 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3820 remiCodeFromeBBlock (ebp, ic_prev);
3821 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3825 /* if this is an itemp & result of a address of a true sym
3826 then mark this as rematerialisable */
3827 if (ic->op == ADDRESS_OF &&
3828 IS_ITEMP (IC_RESULT (ic)) &&
3829 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3830 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3831 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3834 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3836 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3837 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3838 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3842 /* if straight assignment then carry remat flag if
3843 this is the only definition */
3844 if (ic->op == '=' &&
3845 !POINTER_SET (ic) &&
3846 IS_SYMOP (IC_RIGHT (ic)) &&
3847 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3848 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3850 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3852 OP_SYMBOL (IC_RESULT (ic))->remat =
3853 OP_SYMBOL (IC_RIGHT (ic))->remat;
3854 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3855 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3858 /* if this is a +/- operation with a rematerizable
3859 then mark this as rematerializable as well */
3860 if ((ic->op == '+' || ic->op == '-') &&
3861 (IS_SYMOP (IC_LEFT (ic)) &&
3862 IS_ITEMP (IC_RESULT (ic)) &&
3863 OP_SYMBOL (IC_LEFT (ic))->remat &&
3864 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3865 IS_OP_LITERAL (IC_RIGHT (ic))))
3867 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3869 operandLitValue (IC_RIGHT (ic));
3870 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3871 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3872 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3875 /* mark the pointer usages */
3876 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3878 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3879 debugLog (" marking as a pointer (set) =>");
3880 debugAopGet (" result:", IC_RESULT (ic));
3882 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3884 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3885 debugLog (" marking as a pointer (get) =>");
3886 debugAopGet (" left:", IC_LEFT (ic));
3891 /* if we are using a symbol on the stack
3892 then we should say pic14_ptrRegReq */
3893 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3894 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3895 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3896 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3897 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3898 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3901 if (IS_SYMOP (IC_LEFT (ic)))
3902 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3903 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3904 if (IS_SYMOP (IC_RIGHT (ic)))
3905 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3906 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3907 if (IS_SYMOP (IC_RESULT (ic)))
3908 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3909 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3912 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3916 /* if the condition of an if instruction
3917 is defined in the previous instruction then
3918 mark the itemp as a conditional */
3919 if ((IS_CONDITIONAL (ic) ||
3920 ((ic->op == BITWISEAND ||
3923 isBitwiseOptimizable (ic))) &&
3924 ic->next && ic->next->op == IFX &&
3925 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3926 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3929 debugLog (" %d\n", __LINE__);
3930 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3934 /* reduce for support function calls */
3935 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3936 packRegsForSupport (ic, ebp);
3938 /* if a parameter is passed, it's in W, so we may not
3939 need to place a copy in a register */
3940 if (ic->op == RECEIVE)
3941 packForReceive (ic, ebp);
3943 /* some cases the redundant moves can
3944 can be eliminated for return statements */
3945 if ((ic->op == RETURN || ic->op == SEND) &&
3946 !isOperandInFarSpace (IC_LEFT (ic)) &&
3948 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3950 /* if pointer set & left has a size more than
3951 one and right is not in far space */
3952 if (POINTER_SET (ic) &&
3953 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3954 IS_SYMOP(IC_RESULT(ic)) &&
3955 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3956 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3957 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3959 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3961 /* if pointer get */
3962 if (POINTER_GET (ic) &&
3963 !isOperandInFarSpace (IC_RESULT (ic)) &&
3964 IS_SYMOP(IC_LEFT(ic)) &&
3965 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3966 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3967 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3969 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3972 /* if this is cast for intergral promotion then
3973 check if only use of the definition of the
3974 operand being casted/ if yes then replace
3975 the result of that arithmetic operation with
3976 this result and get rid of the cast */
3977 if (ic->op == CAST) {
3979 sym_link *fromType = operandType (IC_RIGHT (ic));
3980 sym_link *toType = operandType (IC_LEFT (ic));
3982 debugLog (" %d - casting\n", __LINE__);
3984 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3985 getSize (fromType) != getSize (toType)) {
3988 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3991 if (IS_ARITHMETIC_OP (dic)) {
3993 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3994 IC_RESULT (dic) = IC_RESULT (ic);
3995 remiCodeFromeBBlock (ebp, ic);
3996 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3997 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3998 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4002 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4006 /* if the type from and type to are the same
4007 then if this is the only use then packit */
4008 if (compareType (operandType (IC_RIGHT (ic)),
4009 operandType (IC_LEFT (ic))) == 1) {
4011 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4014 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4015 IC_RESULT (dic) = IC_RESULT (ic);
4016 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4017 remiCodeFromeBBlock (ebp, ic);
4018 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4019 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4027 iTempNN := (some variable in farspace) V1
4032 if (ic->op == IPUSH)
4034 packForPush (ic, ebp);
4038 /* pack registers for accumulator use, when the
4039 result of an arithmetic or bit wise operation
4040 has only one use, that use is immediately following
4041 the defintion and the using iCode has only one
4042 operand or has two operands but one is literal &
4043 the result of that operation is not on stack then
4044 we can leave the result of this operation in acc:b
4046 if ((IS_ARITHMETIC_OP (ic)
4048 || IS_BITWISE_OP (ic)
4050 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4053 IS_ITEMP (IC_RESULT (ic)) &&
4054 getSize (operandType (IC_RESULT (ic))) <= 2)
4056 packRegsForAccUse (ic);
4062 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4066 if (!debug || !debugF)
4069 for (i = 0; i < count; i++)
4071 fprintf (debugF, "\n----------------------------------------------------------------\n");
4072 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4073 ebbs[i]->entryLabel->name,
4076 ebbs[i]->isLastInLoop);
4077 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4082 fprintf (debugF, "visited %d : hasFcall = %d\n",
4086 fprintf (debugF, "\ndefines bitVector :");
4087 bitVectDebugOn (ebbs[i]->defSet, debugF);
4088 fprintf (debugF, "\nlocal defines bitVector :");
4089 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4090 fprintf (debugF, "\npointers Set bitvector :");
4091 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4092 fprintf (debugF, "\nin pointers Set bitvector :");
4093 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4094 fprintf (debugF, "\ninDefs Set bitvector :");
4095 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4096 fprintf (debugF, "\noutDefs Set bitvector :");
4097 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4098 fprintf (debugF, "\nusesDefs Set bitvector :");
4099 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4100 fprintf (debugF, "\n----------------------------------------------------------------\n");
4101 printiCChain (ebbs[i]->sch, debugF);
4104 /*-----------------------------------------------------------------*/
4105 /* assignRegisters - assigns registers to each live range as need */
4106 /*-----------------------------------------------------------------*/
4108 pic14_assignRegisters (ebbIndex * ebbi)
4110 eBBlock ** ebbs = ebbi->bbOrder;
4111 int count = ebbi->count;
4115 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4116 debugLog ("\nebbs before optimizing:\n");
4117 dumpEbbsToDebug (ebbs, count);
4119 setToNull ((void *) &_G.funcrUsed);
4120 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4123 /* change assignments this will remove some
4124 live ranges reducing some register pressure */
4125 for (i = 0; i < count; i++)
4126 packRegisters (ebbs[i]);
4133 debugLog("dir registers allocated so far:\n");
4134 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4137 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4138 reg = hTabNextItem(dynDirectRegNames, &hkey);
4143 if (options.dump_pack)
4144 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4146 /* first determine for each live range the number of
4147 registers & the type of registers required for each */
4150 /* and serially allocate registers */
4151 serialRegAssign (ebbs, count);
4153 /* if stack was extended then tell the user */
4156 /* werror(W_TOOMANY_SPILS,"stack", */
4157 /* _G.stackExtend,currFunc->name,""); */
4163 /* werror(W_TOOMANY_SPILS,"data space", */
4164 /* _G.dataExtend,currFunc->name,""); */
4168 /* after that create the register mask
4169 for each of the instruction */
4170 createRegMask (ebbs, count);
4172 /* redo that offsets for stacked automatic variables */
4173 redoStackOffsets ();
4175 if (options.dump_rassgn)
4176 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4178 /* now get back the chain */
4179 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4181 debugLog ("ebbs after optimizing:\n");
4182 dumpEbbsToDebug (ebbs, count);
4187 /* free up any _G.stackSpil locations allocated */
4188 applyToSet (_G.stackSpil, deallocStackSpil);
4190 setToNull ((void *) &_G.stackSpil);
4191 setToNull ((void *) &_G.spiltSet);
4192 /* mark all registers as free */
4193 //pic14_freeAllRegs ();
4195 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");