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 */
96 static void spillThis (symbol *);
98 static FILE *debugF = NULL;
99 /*-----------------------------------------------------------------*/
100 /* debugLog - open a file for debugging information */
101 /*-----------------------------------------------------------------*/
102 //static void debugLog(char *inst,char *fmt, ...)
104 debugLog (char *fmt,...)
106 static int append = 0; // First time through, open the file without append.
109 //char *bufferP=buffer;
112 if (!debug || !dstFileName)
118 /* create the file name */
119 strcpy (buffer, dstFileName);
120 strcat (buffer, ".d");
122 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
124 werror (E_FILE_OPEN_ERR, buffer);
127 append = 1; // Next time debubLog is called, we'll append the debug info
133 vsprintf (buffer, fmt, ap);
135 fprintf (debugF, "%s", buffer);
137 while (isspace(*bufferP)) bufferP++;
139 if (bufferP && *bufferP)
140 lineCurr = (lineCurr ?
141 connectLine(lineCurr,newLineNode(lb)) :
142 (lineHead = newLineNode(lb)));
143 lineCurr->isInline = _G.inLine;
144 lineCurr->isDebug = _G.debugLine;
154 fputc ('\n', debugF);
156 /*-----------------------------------------------------------------*/
157 /* debugLogClose - closes the debug log file (if opened) */
158 /*-----------------------------------------------------------------*/
168 #define AOP(op) op->aop
171 debugAopGet (char *str, operand * op)
176 printOperand (op, debugF);
184 decodeOp (unsigned int op)
187 if (op < 128 && op > ' ')
189 buffer[0] = (op & 0xff);
196 case IDENTIFIER: return "IDENTIFIER";
197 case TYPE_NAME: return "TYPE_NAME";
198 case CONSTANT: return "CONSTANT";
199 case STRING_LITERAL: return "STRING_LITERAL";
200 case SIZEOF: return "SIZEOF";
201 case PTR_OP: return "PTR_OP";
202 case INC_OP: return "INC_OP";
203 case DEC_OP: return "DEC_OP";
204 case LEFT_OP: return "LEFT_OP";
205 case RIGHT_OP: return "RIGHT_OP";
206 case LE_OP: return "LE_OP";
207 case GE_OP: return "GE_OP";
208 case EQ_OP: return "EQ_OP";
209 case NE_OP: return "NE_OP";
210 case AND_OP: return "AND_OP";
211 case OR_OP: return "OR_OP";
212 case MUL_ASSIGN: return "MUL_ASSIGN";
213 case DIV_ASSIGN: return "DIV_ASSIGN";
214 case MOD_ASSIGN: return "MOD_ASSIGN";
215 case ADD_ASSIGN: return "ADD_ASSIGN";
216 case SUB_ASSIGN: return "SUB_ASSIGN";
217 case LEFT_ASSIGN: return "LEFT_ASSIGN";
218 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
219 case AND_ASSIGN: return "AND_ASSIGN";
220 case XOR_ASSIGN: return "XOR_ASSIGN";
221 case OR_ASSIGN: return "OR_ASSIGN";
222 case TYPEDEF: return "TYPEDEF";
223 case EXTERN: return "EXTERN";
224 case STATIC: return "STATIC";
225 case AUTO: return "AUTO";
226 case REGISTER: return "REGISTER";
227 case CODE: return "CODE";
228 case EEPROM: return "EEPROM";
229 case INTERRUPT: return "INTERRUPT";
230 case SFR: return "SFR";
231 case AT: return "AT";
232 case SBIT: return "SBIT";
233 case REENTRANT: return "REENTRANT";
234 case USING: return "USING";
235 case XDATA: return "XDATA";
236 case DATA: return "DATA";
237 case IDATA: return "IDATA";
238 case PDATA: return "PDATA";
239 case VAR_ARGS: return "VAR_ARGS";
240 case CRITICAL: return "CRITICAL";
241 case NONBANKED: return "NONBANKED";
242 case BANKED: return "BANKED";
243 case CHAR: return "CHAR";
244 case SHORT: return "SHORT";
245 case INT: return "INT";
246 case LONG: return "LONG";
247 case SIGNED: return "SIGNED";
248 case UNSIGNED: return "UNSIGNED";
249 case FLOAT: return "FLOAT";
250 case DOUBLE: return "DOUBLE";
251 case CONST: return "CONST";
252 case VOLATILE: return "VOLATILE";
253 case VOID: return "VOID";
254 case BIT: return "BIT";
255 case STRUCT: return "STRUCT";
256 case UNION: return "UNION";
257 case ENUM: return "ENUM";
258 case ELIPSIS: return "ELIPSIS";
259 case RANGE: return "RANGE";
260 case FAR: return "FAR";
261 case CASE: return "CASE";
262 case DEFAULT: return "DEFAULT";
263 case IF: return "IF";
264 case ELSE: return "ELSE";
265 case SWITCH: return "SWITCH";
266 case WHILE: return "WHILE";
267 case DO: return "DO";
268 case FOR: return "FOR";
269 case GOTO: return "GOTO";
270 case CONTINUE: return "CONTINUE";
271 case BREAK: return "BREAK";
272 case RETURN: return "RETURN";
273 case INLINEASM: return "INLINEASM";
274 case IFX: return "IFX";
275 case ADDRESS_OF: return "ADDRESS_OF";
276 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
277 case SPIL: return "SPIL";
278 case UNSPIL: return "UNSPIL";
279 case GETHBIT: return "GETHBIT";
280 case BITWISEAND: return "BITWISEAND";
281 case UNARYMINUS: return "UNARYMINUS";
282 case IPUSH: return "IPUSH";
283 case IPOP: return "IPOP";
284 case PCALL: return "PCALL";
285 case ENDFUNCTION: return "ENDFUNCTION";
286 case JUMPTABLE: return "JUMPTABLE";
287 case RRC: return "RRC";
288 case RLC: return "RLC";
289 case CAST: return "CAST";
290 case CALL: return "CALL";
291 case PARAM: return "PARAM ";
292 case NULLOP: return "NULLOP";
293 case BLOCK: return "BLOCK";
294 case LABEL: return "LABEL";
295 case RECEIVE: return "RECEIVE";
296 case SEND: return "SEND";
298 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
301 /*-----------------------------------------------------------------*/
302 /*-----------------------------------------------------------------*/
304 debugLogRegType (short type)
309 case REG_GPR: return "REG_GPR";
310 case REG_PTR: return "REG_PTR";
311 case REG_CND: return "REG_CND";
314 sprintf (buffer, "unknown reg type %d", type);
318 /*-----------------------------------------------------------------*/
319 /*-----------------------------------------------------------------*/
320 static int regname2key(char const *name)
329 key += (*name++) + 1;
333 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
337 /*-----------------------------------------------------------------*/
338 /* newReg - allocate and init memory for a new register */
339 /*-----------------------------------------------------------------*/
340 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
345 dReg = Safe_calloc(1,sizeof(regs));
347 dReg->pc_type = pc_type;
350 dReg->name = Safe_strdup(name);
352 sprintf(buffer,"r0x%02X", dReg->rIdx);
353 dReg->name = Safe_strdup(buffer);
369 dReg->reg_alias = NULL;
370 dReg->reglives.usedpFlows = newSet();
371 dReg->reglives.assignedpFlows = newSet();
373 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
378 /*-----------------------------------------------------------------*/
379 /* regWithIdx - Search through a set of registers that matches idx */
380 /*-----------------------------------------------------------------*/
382 regWithIdx (set *dRegs, int idx, int fixed)
386 for (dReg = setFirstItem(dRegs) ; dReg ;
387 dReg = setNextItem(dRegs)) {
389 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
397 /*-----------------------------------------------------------------*/
398 /* regWithName - Search through a set of registers that matches name */
399 /*-----------------------------------------------------------------*/
401 regWithName (set *dRegs, const char *name)
405 for (dReg = setFirstItem(dRegs) ; dReg ;
406 dReg = setNextItem(dRegs)) {
408 if((strcmp(name,dReg->name)==0)) {
416 /*-----------------------------------------------------------------*/
417 /* regWithName - Search for a registers that matches name */
418 /*-----------------------------------------------------------------*/
420 regFindWithName (const char *name)
424 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
425 debugLog ("Found a Direct Register!\n");
428 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
429 debugLog ("Found a Direct Bit Register!\n");
433 if (*name=='_') name++; // Step passed '_'
435 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
436 debugLog ("Found a Dynamic Register!\n");
439 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
440 debugLog ("Found a Processor Register!\n");
443 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
444 debugLog ("Found an Internal Register!\n");
447 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
448 debugLog ("Found an Stack Register!\n");
455 /*-----------------------------------------------------------------*/
456 /* regFindFree - Search for a free register in a set of registers */
457 /*-----------------------------------------------------------------*/
459 regFindFree (set *dRegs)
463 for (dReg = setFirstItem(dRegs) ; dReg ;
464 dReg = setNextItem(dRegs)) {
472 /*-----------------------------------------------------------------*/
473 /* initStack - allocate registers for a psuedo stack */
474 /*-----------------------------------------------------------------*/
475 void initStack(int base_address, int size)
480 Gstack_base_addr = base_address;
481 //fprintf(stderr,"initStack");
483 for(i = 0; i<size; i++) {
484 regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
485 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
488 r->alias = 0x180; // Using shared memory for pseudo stack
489 addSet(&dynStackRegs,r);
494 /*-----------------------------------------------------------------*
495 *-----------------------------------------------------------------*/
497 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
500 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
501 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
504 /*-----------------------------------------------------------------*
505 *-----------------------------------------------------------------*/
508 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
510 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
512 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
515 return addSet(&dynInternalRegs,reg);
520 /*-----------------------------------------------------------------*/
521 /* allocReg - allocates register of given type */
522 /*-----------------------------------------------------------------*/
524 allocReg (short type)
528 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
529 //fprintf(stderr,"allocReg\n");
531 reg = pic14_findFreeReg (type);
539 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
544 /*-----------------------------------------------------------------*/
545 /* dirregWithName - search for register by name */
546 /*-----------------------------------------------------------------*/
548 dirregWithName (char *name)
556 /* hash the name to get a key */
558 hkey = regname2key(name);
560 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
564 if(STRCASECMP(reg->name, name) == 0) {
568 reg = hTabNextItemWK (dynDirectRegNames);
572 return NULL; // name wasn't found in the hash table
575 int IS_CONFIG_ADDRESS(int address)
578 return address == 0x2007;
581 /*-----------------------------------------------------------------*/
582 /* allocNewDirReg - allocates a new register of given type */
583 /*-----------------------------------------------------------------*/
585 allocNewDirReg (sym_link *symlnk,const char *name)
589 sym_link *spec = getSpec (symlnk);
591 /* if this is at an absolute address, then get the address. */
592 if (SPEC_ABSA (spec) ) {
593 address = SPEC_ADDR (spec);
594 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
597 /* Register wasn't found in hash, so let's create
598 * a new one and put it in the hash table AND in the
599 * dynDirectRegNames set */
600 if (IS_CONFIG_ADDRESS(address)) {
601 debugLog (" -- %s is declared at address 0x2007\n",name);
606 if (IS_BITVAR (spec))
613 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
614 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
616 if (SPEC_ABSA (spec) ) {
620 if (IS_BITVAR (spec)) {
621 addSet(&dynDirectBitRegs, reg);
624 addSet(&dynDirectRegs, reg);
626 if (!IS_STATIC (spec)) {
629 if (IS_EXTERN (spec)) {
635 if (address && reg) {
637 reg->address = address;
638 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
644 /*-----------------------------------------------------------------*/
645 /* allocDirReg - allocates register of given type */
646 /*-----------------------------------------------------------------*/
648 allocDirReg (operand *op )
655 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
659 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
661 /* If the symbol is at a fixed address, then remove the leading underscore
662 * from the name. This is hack to allow the .asm include file named registers
663 * to match the .c declared register names */
665 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
668 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
670 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
671 debugLog(" %d const char\n",__LINE__);
672 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
675 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
676 if (IS_CODE ( OP_SYM_ETYPE(op)) )
677 debugLog(" %d code space\n",__LINE__);
679 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
680 debugLog(" %d integral\n",__LINE__);
681 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
682 debugLog(" %d literal\n",__LINE__);
683 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
684 debugLog(" %d specifier\n",__LINE__);
685 debugAopGet(NULL, op);
688 if (IS_CODE ( OP_SYM_ETYPE(op)) )
691 /* First, search the hash table to see if there is a register with this name */
692 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
693 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
696 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
697 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
699 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
700 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
703 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
705 reg = dirregWithName(name);
712 /* if this is at an absolute address, then get the address. */
713 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
714 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
715 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
718 /* Register wasn't found in hash, so let's create
719 * a new one and put it in the hash table AND in the
720 * dynDirectRegNames set */
721 if(!IS_CONFIG_ADDRESS(address)) {
722 //fprintf(stderr,"allocating new reg %s\n",name);
724 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
725 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
727 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
729 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
731 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
735 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
736 addSet(&dynDirectBitRegs, reg);
739 addSet(&dynDirectRegs, reg);
741 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
744 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
750 debugLog (" -- %s is declared at address 0x2007\n",name);
755 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
757 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
758 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
763 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
765 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
766 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
769 allocNewDirReg (OP_SYM_TYPE(op),name);
776 /*-----------------------------------------------------------------*/
777 /* allocRegByName - allocates register with given name */
778 /*-----------------------------------------------------------------*/
780 allocRegByName (char *name, int size)
786 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
790 /* First, search the hash table to see if there is a register with this name */
791 reg = dirregWithName(name);
797 /* Register wasn't found in hash, so let's create
798 * a new one and put it in the hash table AND in the
799 * dynDirectRegNames set */
800 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
801 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
802 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
803 if (strcmp(reg->name+1,sym->name)==0) {
804 unsigned a = SPEC_ADDR(sym->etype);
808 if (!IS_STATIC (sym->etype)) {
811 if (IS_EXTERN (sym->etype)) {
814 if (IS_BITVAR (sym->etype))
821 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
822 if (strcmp(reg->name+1,sym->name)==0) {
823 unsigned a = SPEC_ADDR(sym->etype);
825 if (!IS_STATIC (sym->etype)) {
828 if (IS_EXTERN (sym->etype)) {
831 if (IS_BITVAR (sym->etype))
839 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
841 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
842 if (reg->isBitField) {
843 addSet(&dynDirectBitRegs, reg);
845 addSet(&dynDirectRegs, reg);
851 /*-----------------------------------------------------------------*/
852 /* RegWithIdx - returns pointer to register with index number */
853 /*-----------------------------------------------------------------*/
855 typeRegWithIdx (int idx, int type, int fixed)
860 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
865 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
867 debugLog ("Found a Dynamic Register!\n");
870 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
871 debugLog ("Found a Direct Register!\n");
877 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
878 debugLog ("Found a Stack Register!\n");
882 werror (E_STACK_OUT, "Register");
883 /* return an existing register just to avoid the SDCC crash */
884 return regWithIdx ( dynStackRegs, 0x7f, fixed);
888 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
889 debugLog ("Found a Processor Register!\n");
903 /*-----------------------------------------------------------------*/
904 /* pic14_regWithIdx - returns pointer to register with index number*/
905 /*-----------------------------------------------------------------*/
907 pic14_regWithIdx (int idx)
911 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
914 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
920 /*-----------------------------------------------------------------*/
921 /* pic14_regWithIdx - returns pointer to register with index number */
922 /*-----------------------------------------------------------------*/
924 pic14_allocWithIdx (int idx)
929 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
931 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
933 debugLog ("Found a Dynamic Register!\n");
934 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
935 debugLog ("Found a Stack Register!\n");
936 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
937 debugLog ("Found a Processor Register!\n");
938 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
939 debugLog ("Found an Internal Register!\n");
940 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
941 debugLog ("Found an Internal Register!\n");
944 debugLog ("Dynamic Register not found\n");
947 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
948 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
949 "regWithIdx not found");
959 /*-----------------------------------------------------------------*/
960 /*-----------------------------------------------------------------*/
962 pic14_findFreeReg(short type)
969 if((dReg = regFindFree(dynAllocRegs)) != NULL)
971 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
975 if((dReg = regFindFree(dynStackRegs)) != NULL)
987 /*-----------------------------------------------------------------*/
988 /* freeReg - frees a register */
989 /*-----------------------------------------------------------------*/
993 debugLog ("%s\n", __FUNCTION__);
998 /*-----------------------------------------------------------------*/
999 /* nFreeRegs - returns number of free registers */
1000 /*-----------------------------------------------------------------*/
1002 nFreeRegs (int type)
1004 /* dynamically allocate as many as we need and worry about
1005 * fitting them into a PIC later */
1012 debugLog ("%s\n", __FUNCTION__);
1013 for (i = 0; i < pic14_nRegs; i++)
1014 if (regspic14[i].isFree && regspic14[i].type == type)
1020 /*-----------------------------------------------------------------*/
1021 /* nfreeRegsType - free registers with type */
1022 /*-----------------------------------------------------------------*/
1024 nfreeRegsType (int type)
1027 debugLog ("%s\n", __FUNCTION__);
1028 if (type == REG_PTR)
1030 if ((nfr = nFreeRegs (type)) == 0)
1031 return nFreeRegs (REG_GPR);
1034 return nFreeRegs (type);
1037 void writeSetUsedRegs(FILE *of, set *dRegs)
1042 for (dReg = setFirstItem(dRegs) ; dReg ;
1043 dReg = setNextItem(dRegs)) {
1046 fprintf (of, "\t%s\n",dReg->name);
1050 extern void assignFixedRegisters(set *regset);
1051 extern void assignRelocatableRegisters(set *regset,int used);
1052 extern void dump_map(void);
1053 extern void dump_sfr(FILE *of);
1055 void packBits(set *bregs)
1059 regs *bitfield=NULL;
1060 regs *relocbitfield=NULL;
1066 for (regset = bregs ; regset ;
1067 regset = regset->next) {
1069 breg = regset->item;
1070 breg->isBitField = 1;
1071 //fprintf(stderr,"bit reg: %s\n",breg->name);
1074 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1076 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1077 breg->rIdx = breg->address & 7;
1078 breg->address >>= 3;
1081 //sprintf (buffer, "fbitfield%02x", breg->address);
1082 sprintf (buffer, "0x%02x", breg->address);
1083 //fprintf(stderr,"new bit field\n");
1084 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1085 bitfield->isBitField = 1;
1086 bitfield->isFixed = 1;
1087 bitfield->address = breg->address;
1088 //addSet(&dynDirectRegs,bitfield);
1089 addSet(&dynInternalRegs,bitfield);
1090 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1092 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1095 breg->reg_alias = bitfield;
1099 if(!relocbitfield || bit_no >7) {
1102 sprintf (buffer, "bitfield%d", byte_no);
1103 //fprintf(stderr,"new relocatable bit field\n");
1104 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1105 relocbitfield->isBitField = 1;
1106 //addSet(&dynDirectRegs,relocbitfield);
1107 addSet(&dynInternalRegs,relocbitfield);
1108 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1112 breg->reg_alias = relocbitfield;
1113 breg->address = rDirectIdx; /* byte_no; */
1114 breg->rIdx = bit_no++;
1122 void bitEQUs(FILE *of, set *bregs)
1124 regs *breg,*bytereg;
1127 //fprintf(stderr," %s\n",__FUNCTION__);
1128 for (breg = setFirstItem(bregs) ; breg ;
1129 breg = setNextItem(bregs)) {
1131 //fprintf(stderr,"bit reg: %s\n",breg->name);
1133 bytereg = breg->reg_alias;
1135 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1138 breg->rIdx & 0x0007);
1141 //fprintf(stderr, "bit field is not assigned to a register\n");
1142 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1152 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1157 for (reg = setFirstItem(fregs) ; reg ;
1158 reg = setNextItem(fregs)) {
1160 //if(!reg->isEmitted && reg->wasUsed) {
1163 fprintf (of, "%s\tEQU\t0x%03x\n",
1167 fprintf (of, "%s\tEQU\t0x%03x\n",
1175 void writeUsedRegs(FILE *of)
1177 packBits(dynDirectBitRegs);
1179 assignFixedRegisters(dynInternalRegs);
1180 assignFixedRegisters(dynAllocRegs);
1181 assignFixedRegisters(dynStackRegs);
1182 assignFixedRegisters(dynDirectRegs);
1184 assignRelocatableRegisters(dynInternalRegs,0);
1185 assignRelocatableRegisters(dynAllocRegs,0);
1186 assignRelocatableRegisters(dynStackRegs,0);
1188 assignRelocatableRegisters(dynDirectRegs,0);
1190 assignRelocatableRegisters(dynDirectRegs,0);
1191 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1196 bitEQUs(of,dynDirectBitRegs);
1198 aliasEQUs(of,dynAllocRegs,0);
1199 aliasEQUs(of,dynDirectRegs,0);
1200 aliasEQUs(of,dynStackRegs,0);
1201 aliasEQUs(of,dynProcessorRegs,1);
1206 /*-----------------------------------------------------------------*/
1207 /* allDefsOutOfRange - all definitions are out of a range */
1208 /*-----------------------------------------------------------------*/
1210 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1214 debugLog ("%s\n", __FUNCTION__);
1218 for (i = 0; i < defs->size; i++)
1222 if (bitVectBitValue (defs, i) &&
1223 (ic = hTabItemWithKey (iCodehTab, i)) &&
1224 (ic->seq >= fseq && ic->seq <= toseq))
1234 /*-----------------------------------------------------------------*/
1235 /* computeSpillable - given a point find the spillable live ranges */
1236 /*-----------------------------------------------------------------*/
1238 computeSpillable (iCode * ic)
1242 debugLog ("%s\n", __FUNCTION__);
1243 /* spillable live ranges are those that are live at this
1244 point . the following categories need to be subtracted
1246 a) - those that are already spilt
1247 b) - if being used by this one
1248 c) - defined by this one */
1250 spillable = bitVectCopy (ic->rlive);
1252 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1254 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1255 bitVectUnSetBit (spillable, ic->defKey);
1256 spillable = bitVectIntersect (spillable, _G.regAssigned);
1261 /*-----------------------------------------------------------------*/
1262 /* noSpilLoc - return true if a variable has no spil location */
1263 /*-----------------------------------------------------------------*/
1265 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1267 debugLog ("%s\n", __FUNCTION__);
1268 return (sym->usl.spillLoc ? 0 : 1);
1271 /*-----------------------------------------------------------------*/
1272 /* hasSpilLoc - will return 1 if the symbol has spil location */
1273 /*-----------------------------------------------------------------*/
1275 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1277 debugLog ("%s\n", __FUNCTION__);
1278 return (sym->usl.spillLoc ? 1 : 0);
1281 /*-----------------------------------------------------------------*/
1282 /* directSpilLoc - will return 1 if the splilocation is in direct */
1283 /*-----------------------------------------------------------------*/
1285 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1287 debugLog ("%s\n", __FUNCTION__);
1288 if (sym->usl.spillLoc &&
1289 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1295 /*-----------------------------------------------------------------*/
1296 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1297 /* but is not used as a pointer */
1298 /*-----------------------------------------------------------------*/
1300 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1302 debugLog ("%s\n", __FUNCTION__);
1303 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1306 /*-----------------------------------------------------------------*/
1307 /* rematable - will return 1 if the remat flag is set */
1308 /*-----------------------------------------------------------------*/
1310 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1312 debugLog ("%s\n", __FUNCTION__);
1316 /*-----------------------------------------------------------------*/
1317 /* notUsedInRemaining - not used or defined in remain of the block */
1318 /*-----------------------------------------------------------------*/
1320 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1322 debugLog ("%s\n", __FUNCTION__);
1323 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1324 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1327 /*-----------------------------------------------------------------*/
1328 /* allLRs - return true for all */
1329 /*-----------------------------------------------------------------*/
1331 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1333 debugLog ("%s\n", __FUNCTION__);
1337 /*-----------------------------------------------------------------*/
1338 /* liveRangesWith - applies function to a given set of live range */
1339 /*-----------------------------------------------------------------*/
1341 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1342 eBBlock * ebp, iCode * ic)
1347 debugLog ("%s\n", __FUNCTION__);
1348 if (!lrs || !lrs->size)
1351 for (i = 1; i < lrs->size; i++)
1354 if (!bitVectBitValue (lrs, i))
1357 /* if we don't find it in the live range
1358 hash table we are in serious trouble */
1359 if (!(sym = hTabItemWithKey (liveRanges, i)))
1361 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1362 "liveRangesWith could not find liveRange");
1366 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1367 addSetHead (&rset, sym);
1374 /*-----------------------------------------------------------------*/
1375 /* leastUsedLR - given a set determines which is the least used */
1376 /*-----------------------------------------------------------------*/
1378 leastUsedLR (set * sset)
1380 symbol *sym = NULL, *lsym = NULL;
1382 debugLog ("%s\n", __FUNCTION__);
1383 sym = lsym = setFirstItem (sset);
1388 for (; lsym; lsym = setNextItem (sset))
1391 /* if usage is the same then prefer
1392 the spill the smaller of the two */
1393 if (lsym->used == sym->used)
1394 if (getSize (lsym->type) < getSize (sym->type))
1398 if (lsym->used < sym->used)
1403 setToNull ((void *) &sset);
1408 /*-----------------------------------------------------------------*/
1409 /* noOverLap - will iterate through the list looking for over lap */
1410 /*-----------------------------------------------------------------*/
1412 noOverLap (set * itmpStack, symbol * fsym)
1415 debugLog ("%s\n", __FUNCTION__);
1418 for (sym = setFirstItem (itmpStack); sym;
1419 sym = setNextItem (itmpStack))
1421 if (sym->liveTo > fsym->liveFrom)
1429 /*-----------------------------------------------------------------*/
1430 /* isFree - will return 1 if the a free spil location is found */
1431 /*-----------------------------------------------------------------*/
1436 V_ARG (symbol **, sloc);
1437 V_ARG (symbol *, fsym);
1439 debugLog ("%s\n", __FUNCTION__);
1440 /* if already found */
1444 /* if it is free && and the itmp assigned to
1445 this does not have any overlapping live ranges
1446 with the one currently being assigned and
1447 the size can be accomodated */
1449 noOverLap (sym->usl.itmpStack, fsym) &&
1450 getSize (sym->type) >= getSize (fsym->type))
1459 /*-----------------------------------------------------------------*/
1460 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1461 /*-----------------------------------------------------------------*/
1463 spillLRWithPtrReg (symbol * forSym)
1469 debugLog ("%s\n", __FUNCTION__);
1470 if (!_G.regAssigned ||
1471 bitVectIsZero (_G.regAssigned))
1474 r0 = pic14_regWithIdx (R0_IDX);
1475 r1 = pic14_regWithIdx (R1_IDX);
1477 /* for all live ranges */
1478 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1479 lrsym = hTabNextItem (liveRanges, &k))
1483 /* if no registers assigned to it or
1485 /* if it does not overlap with this then
1486 not need to spill it */
1488 if (lrsym->isspilt || !lrsym->nRegs ||
1489 (lrsym->liveTo < forSym->liveFrom))
1492 /* go thru the registers : if it is either
1493 r0 or r1 then spil it */
1494 for (j = 0; j < lrsym->nRegs; j++)
1495 if (lrsym->regs[j] == r0 ||
1496 lrsym->regs[j] == r1)
1505 /*-----------------------------------------------------------------*/
1506 /* createStackSpil - create a location on the stack to spil */
1507 /*-----------------------------------------------------------------*/
1509 createStackSpil (symbol * sym)
1511 symbol *sloc = NULL;
1512 int useXstack, model, noOverlay;
1514 char slocBuffer[30];
1515 debugLog ("%s\n", __FUNCTION__);
1519 /* first go try and find a free one that is already
1520 existing on the stack */
1521 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1523 /* found a free one : just update & return */
1524 sym->usl.spillLoc = sloc;
1527 addSetHead (&sloc->usl.itmpStack, sym);
1531 /* could not then have to create one , this is the hard part
1532 we need to allocate this on the stack : this is really a
1533 hack!! but cannot think of anything better at this time */
1535 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1537 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1538 __FILE__, __LINE__);
1542 sloc = newiTemp (slocBuffer);
1544 /* set the type to the spilling symbol */
1545 sloc->type = copyLinkChain (sym->type);
1546 sloc->etype = getSpec (sloc->type);
1547 SPEC_SCLS (sloc->etype) = S_DATA;
1548 SPEC_EXTR (sloc->etype) = 0;
1549 SPEC_STAT (sloc->etype) = 0;
1551 /* we don't allow it to be allocated`
1552 onto the external stack since : so we
1553 temporarily turn it off ; we also
1554 turn off memory model to prevent
1555 the spil from going to the external storage
1556 and turn off overlaying
1559 useXstack = options.useXstack;
1560 model = options.model;
1561 noOverlay = options.noOverlay;
1562 options.noOverlay = 1;
1563 options.model = options.useXstack = 0;
1567 options.useXstack = useXstack;
1568 options.model = model;
1569 options.noOverlay = noOverlay;
1570 sloc->isref = 1; /* to prevent compiler warning */
1572 /* if it is on the stack then update the stack */
1573 if (IN_STACK (sloc->etype))
1575 currFunc->stack += getSize (sloc->type);
1576 _G.stackExtend += getSize (sloc->type);
1579 _G.dataExtend += getSize (sloc->type);
1581 /* add it to the _G.stackSpil set */
1582 addSetHead (&_G.stackSpil, sloc);
1583 sym->usl.spillLoc = sloc;
1586 /* add it to the set of itempStack set
1587 of the spill location */
1588 addSetHead (&sloc->usl.itmpStack, sym);
1592 /*-----------------------------------------------------------------*/
1593 /* isSpiltOnStack - returns true if the spil location is on stack */
1594 /*-----------------------------------------------------------------*/
1596 isSpiltOnStack (symbol * sym)
1600 debugLog ("%s\n", __FUNCTION__);
1609 /* if (sym->_G.stackSpil) */
1612 if (!sym->usl.spillLoc)
1615 etype = getSpec (sym->usl.spillLoc->type);
1616 if (IN_STACK (etype))
1622 /*-----------------------------------------------------------------*/
1623 /* spillThis - spils a specific operand */
1624 /*-----------------------------------------------------------------*/
1626 spillThis (symbol * sym)
1629 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1630 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1632 /* if this is rematerializable or has a spillLocation
1633 we are okay, else we need to create a spillLocation
1635 if (!(sym->remat || sym->usl.spillLoc))
1636 createStackSpil (sym);
1639 /* mark it has spilt & put it in the spilt set */
1641 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1643 bitVectUnSetBit (_G.regAssigned, sym->key);
1645 for (i = 0; i < sym->nRegs; i++)
1649 freeReg (sym->regs[i]);
1650 sym->regs[i] = NULL;
1654 /* if spilt on stack then free up r0 & r1
1655 if they could have been assigned to some
1657 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1660 spillLRWithPtrReg (sym);
1663 if (sym->usl.spillLoc && !sym->remat)
1664 sym->usl.spillLoc->allocreq = 1;
1669 /*-----------------------------------------------------------------*/
1670 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1671 /*-----------------------------------------------------------------*/
1673 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1675 bitVect *lrcs = NULL;
1679 debugLog ("%s\n", __FUNCTION__);
1681 /* get the spillable live ranges */
1682 lrcs = computeSpillable (ic);
1685 /* get all live ranges that are rematerizable */
1686 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1688 /* return the least used of these */
1689 return leastUsedLR (selectS);
1692 /* get live ranges with spillLocations in direct space */
1693 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1695 sym = leastUsedLR (selectS);
1696 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1697 sym->usl.spillLoc->rname :
1698 sym->usl.spillLoc->name));
1700 /* mark it as allocation required */
1701 sym->usl.spillLoc->allocreq = 1;
1705 /* if the symbol is local to the block then */
1706 if (forSym->liveTo < ebp->lSeq)
1709 /* check if there are any live ranges allocated
1710 to registers that are not used in this block */
1711 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1713 sym = leastUsedLR (selectS);
1714 /* if this is not rematerializable */
1723 /* check if there are any live ranges that not
1724 used in the remainder of the block */
1725 if (!_G.blockSpil &&
1726 !isiCodeInFunctionCall (ic) &&
1727 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1729 sym = leastUsedLR (selectS);
1732 sym->remainSpil = 1;
1739 /* find live ranges with spillocation && not used as pointers */
1740 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1743 sym = leastUsedLR (selectS);
1744 /* mark this as allocation required */
1745 sym->usl.spillLoc->allocreq = 1;
1749 /* find live ranges with spillocation */
1750 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1753 sym = leastUsedLR (selectS);
1754 sym->usl.spillLoc->allocreq = 1;
1758 /* couldn't find then we need to create a spil
1759 location on the stack , for which one? the least
1761 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1764 /* return a created spil location */
1765 sym = createStackSpil (leastUsedLR (selectS));
1766 sym->usl.spillLoc->allocreq = 1;
1770 /* this is an extreme situation we will spill
1771 this one : happens very rarely but it does happen */
1777 /*-----------------------------------------------------------------*/
1778 /* spilSomething - spil some variable & mark registers as free */
1779 /*-----------------------------------------------------------------*/
1781 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1786 debugLog ("%s\n", __FUNCTION__);
1787 /* get something we can spil */
1788 ssym = selectSpil (ic, ebp, forSym);
1790 /* mark it as spilt */
1792 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1794 /* mark it as not register assigned &
1795 take it away from the set */
1796 bitVectUnSetBit (_G.regAssigned, ssym->key);
1798 /* mark the registers as free */
1799 for (i = 0; i < ssym->nRegs; i++)
1801 freeReg (ssym->regs[i]);
1803 /* if spilt on stack then free up r0 & r1
1804 if they could have been assigned to as gprs */
1805 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1808 spillLRWithPtrReg (ssym);
1811 /* if this was a block level spil then insert push & pop
1812 at the start & end of block respectively */
1813 if (ssym->blockSpil)
1815 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1816 /* add push to the start of the block */
1817 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1818 ebp->sch->next : ebp->sch));
1819 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1820 /* add pop to the end of the block */
1821 addiCodeToeBBlock (ebp, nic, NULL);
1824 /* if spilt because not used in the remainder of the
1825 block then add a push before this instruction and
1826 a pop at the end of the block */
1827 if (ssym->remainSpil)
1830 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1831 /* add push just before this instruction */
1832 addiCodeToeBBlock (ebp, nic, ic);
1834 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1835 /* add pop to the end of the block */
1836 addiCodeToeBBlock (ebp, nic, NULL);
1845 /*-----------------------------------------------------------------*/
1846 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1847 /*-----------------------------------------------------------------*/
1849 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1854 debugLog ("%s\n", __FUNCTION__);
1856 /* try for a ptr type */
1857 if ((reg = allocReg (REG_PTR)))
1860 /* try for gpr type */
1861 if ((reg = allocReg (REG_GPR)))
1864 /* we have to spil */
1865 if (!spilSomething (ic, ebp, sym))
1868 /* make sure partially assigned registers aren't reused */
1869 for (j=0; j<=sym->nRegs; j++)
1871 sym->regs[j]->isFree = 0;
1873 /* this looks like an infinite loop but
1874 in really selectSpil will abort */
1878 /*-----------------------------------------------------------------*/
1879 /* getRegGpr - will try for GPR if not spil */
1880 /*-----------------------------------------------------------------*/
1882 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1887 debugLog ("%s\n", __FUNCTION__);
1889 /* try for gpr type */
1890 if ((reg = allocReg (REG_GPR)))
1893 if (!pic14_ptrRegReq)
1894 if ((reg = allocReg (REG_PTR)))
1897 /* we have to spil */
1898 if (!spilSomething (ic, ebp, sym))
1901 /* make sure partially assigned registers aren't reused */
1902 for (j=0; j<=sym->nRegs; j++)
1904 sym->regs[j]->isFree = 0;
1906 /* this looks like an infinite loop but
1907 in really selectSpil will abort */
1911 /*-----------------------------------------------------------------*/
1912 /* symHasReg - symbol has a given register */
1913 /*-----------------------------------------------------------------*/
1915 symHasReg (symbol * sym, regs * reg)
1919 debugLog ("%s\n", __FUNCTION__);
1920 for (i = 0; i < sym->nRegs; i++)
1921 if (sym->regs[i] == reg)
1927 /*-----------------------------------------------------------------*/
1928 /* deassignLRs - check the live to and if they have registers & are */
1929 /* not spilt then free up the registers */
1930 /*-----------------------------------------------------------------*/
1932 deassignLRs (iCode * ic, eBBlock * ebp)
1938 debugLog ("%s\n", __FUNCTION__);
1939 for (sym = hTabFirstItem (liveRanges, &k); sym;
1940 sym = hTabNextItem (liveRanges, &k))
1943 symbol *psym = NULL;
1944 /* if it does not end here */
1945 if (sym->liveTo > ic->seq)
1948 /* HACK: result and addr must be disjoint for POINTER_GET */
1949 if (sym->liveTo == ic->seq && POINTER_GET(ic))
1951 //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n");
1955 /* if it was spilt on stack then we can
1956 mark the stack spil location as free */
1961 sym->usl.spillLoc->isFree = 1;
1967 if (!bitVectBitValue (_G.regAssigned, sym->key))
1969 /* special case check if this is an IFX &
1970 the privious one was a pop and the
1971 previous one was not spilt then keep track
1973 if (ic->op == IFX && ic->prev &&
1974 ic->prev->op == IPOP &&
1975 !ic->prev->parmPush &&
1976 IS_SYMOP(IC_LEFT (ic->prev)) &&
1977 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1978 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1984 bitVectUnSetBit (_G.regAssigned, sym->key);
1986 /* if the result of this one needs registers
1987 and does not have it then assign it right
1989 if (IC_RESULT (ic) &&
1990 !(SKIP_IC2 (ic) || /* not a special icode */
1991 ic->op == JUMPTABLE ||
1996 POINTER_SET (ic)) &&
1997 IS_SYMOP (IC_RESULT (ic)) &&
1998 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1999 result->liveTo > ic->seq && /* and will live beyond this */
2000 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2001 result->liveFrom == ic->seq && /* does not start before here */
2002 result->regType == sym->regType && /* same register types */
2003 result->regType == sym->regType && /* same register types */
2004 result->nRegs && /* which needs registers */
2005 !result->isspilt && /* and does not already have them */
2007 !bitVectBitValue (_G.regAssigned, result->key) &&
2008 /* the number of free regs + number of regs in this LR
2009 can accomodate the what result Needs */
2010 ((nfreeRegsType (result->regType) +
2011 sym->nRegs) >= result->nRegs)
2015 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2017 result->regs[i] = sym->regs[i];
2019 result->regs[i] = getRegGpr (ic, ebp, result);
2021 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2025 /* free the remaining */
2026 for (; i < sym->nRegs; i++)
2030 if (!symHasReg (psym, sym->regs[i]))
2031 freeReg (sym->regs[i]);
2034 freeReg (sym->regs[i]);
2041 /*-----------------------------------------------------------------*/
2042 /* reassignLR - reassign this to registers */
2043 /*-----------------------------------------------------------------*/
2045 reassignLR (operand * op)
2047 symbol *sym = OP_SYMBOL (op);
2050 debugLog ("%s\n", __FUNCTION__);
2051 /* not spilt any more */
2052 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2053 bitVectUnSetBit (_G.spiltSet, sym->key);
2055 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2059 for (i = 0; i < sym->nRegs; i++)
2060 sym->regs[i]->isFree = 0;
2063 /*-----------------------------------------------------------------*/
2064 /* willCauseSpill - determines if allocating will cause a spill */
2065 /*-----------------------------------------------------------------*/
2067 willCauseSpill (int nr, int rt)
2069 debugLog ("%s\n", __FUNCTION__);
2070 /* first check if there are any avlb registers
2071 of te type required */
2074 /* special case for pointer type
2075 if pointer type not avlb then
2076 check for type gpr */
2077 if (nFreeRegs (rt) >= nr)
2079 if (nFreeRegs (REG_GPR) >= nr)
2084 if (pic14_ptrRegReq)
2086 if (nFreeRegs (rt) >= nr)
2091 if (nFreeRegs (REG_PTR) +
2092 nFreeRegs (REG_GPR) >= nr)
2097 debugLog (" ... yep it will (cause a spill)\n");
2098 /* it will cause a spil */
2102 /*-----------------------------------------------------------------*/
2103 /* positionRegs - the allocator can allocate same registers to res- */
2104 /* ult and operand, if this happens make sure they are in the same */
2105 /* position as the operand otherwise chaos results */
2106 /*-----------------------------------------------------------------*/
2108 positionRegs (symbol * result, symbol * opsym, int lineno)
2110 int count = min (result->nRegs, opsym->nRegs);
2111 int i, j = 0, shared = 0;
2113 debugLog ("%s\n", __FUNCTION__);
2114 /* if the result has been spilt then cannot share */
2119 /* first make sure that they actually share */
2120 for (i = 0; i < count; i++)
2122 for (j = 0; j < count; j++)
2124 if (result->regs[i] == opsym->regs[j] && i != j)
2134 regs *tmp = result->regs[i];
2135 result->regs[i] = result->regs[j];
2136 result->regs[j] = tmp;
2141 /*------------------------------------------------------------------*/
2142 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2143 /* it should either have registers or have beed spilled. Otherwise, */
2144 /* there was an uninitialized variable, so just spill this to get */
2145 /* the operand in a valid state. */
2146 /*------------------------------------------------------------------*/
2148 verifyRegsAssigned (operand *op, iCode * ic)
2153 if (!IS_ITEMP (op)) return;
2155 sym = OP_SYMBOL (op);
2156 if (sym->isspilt) return;
2157 if (!sym->nRegs) return;
2158 if (sym->regs[0]) return;
2160 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2161 sym->prereqv ? sym->prereqv->name : sym->name);
2166 /*-----------------------------------------------------------------*/
2167 /* serialRegAssign - serially allocate registers to the variables */
2168 /*-----------------------------------------------------------------*/
2170 serialRegAssign (eBBlock ** ebbs, int count)
2174 debugLog ("%s\n", __FUNCTION__);
2175 /* for all blocks */
2176 for (i = 0; i < count; i++)
2181 if (ebbs[i]->noPath &&
2182 (ebbs[i]->entryLabel != entryLabel &&
2183 ebbs[i]->entryLabel != returnLabel))
2186 /* of all instructions do */
2187 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2189 debugLog (" op: %s\n", decodeOp (ic->op));
2191 /* if this is an ipop that means some live
2192 range will have to be assigned again */
2194 reassignLR (IC_LEFT (ic));
2196 /* if result is present && is a true symbol */
2197 if (IC_RESULT (ic) && ic->op != IFX &&
2198 IS_TRUE_SYMOP (IC_RESULT (ic)))
2199 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2201 /* take away registers from live
2202 ranges that end at this instruction */
2203 deassignLRs (ic, ebbs[i]);
2205 /* some don't need registers */
2206 if (SKIP_IC2 (ic) ||
2207 ic->op == JUMPTABLE ||
2211 (IC_RESULT (ic) && POINTER_SET (ic)))
2214 /* now we need to allocate registers
2215 only for the result */
2216 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2218 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2224 /* Make sure any spill location is definately allocated */
2225 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2226 !sym->usl.spillLoc->allocreq)
2228 sym->usl.spillLoc->allocreq++;
2231 /* if it does not need or is spilt
2232 or is already assigned to registers
2233 or will not live beyond this instructions */
2236 bitVectBitValue (_G.regAssigned, sym->key) ||
2237 sym->liveTo <= ic->seq)
2240 /* if some liverange has been spilt at the block level
2241 and this one live beyond this block then spil this
2243 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2248 /* if trying to allocate this will cause
2249 a spill and there is nothing to spill
2250 or this one is rematerializable then
2252 willCS = willCauseSpill (sym->nRegs, sym->regType);
2253 spillable = computeSpillable (ic);
2255 (willCS && bitVectIsZero (spillable)))
2263 /* If the live range preceeds the point of definition
2264 then ideally we must take into account registers that
2265 have been allocated after sym->liveFrom but freed
2266 before ic->seq. This is complicated, so spill this
2267 symbol instead and let fillGaps handle the allocation. */
2268 if (sym->liveFrom < ic->seq)
2274 /* if it has a spillocation & is used less than
2275 all other live ranges then spill this */
2277 if (sym->usl.spillLoc) {
2278 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2279 allLRs, ebbs[i], ic));
2280 if (leastUsed && leastUsed->used > sym->used) {
2285 /* if none of the liveRanges have a spillLocation then better
2286 to spill this one than anything else already assigned to registers */
2287 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2288 /* if this is local to this block then we might find a block spil */
2289 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2297 if (ic->op == RECEIVE)
2298 debugLog ("When I get clever, I'll optimize the receive logic\n");
2300 /* if we need ptr regs for the right side
2302 if (POINTER_GET (ic)
2303 && IS_SYMOP(IC_LEFT(ic))
2304 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2305 <= (unsigned) PTRSIZE)
2310 /* else we assign registers to it */
2311 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2313 debugLog (" %d - \n", __LINE__);
2315 bitVectDebugOn(_G.regAssigned, debugF);
2316 for (j = 0; j < sym->nRegs; j++)
2318 if (sym->regType == REG_PTR)
2319 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2321 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2323 /* if the allocation failed which means
2324 this was spilt then break */
2328 debugLog (" %d - \n", __LINE__);
2330 /* if it shares registers with operands make sure
2331 that they are in the same position */
2332 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2333 IS_SYMOP(IC_RESULT(ic)) &&
2334 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2335 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2336 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2337 /* do the same for the right operand */
2338 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2339 IS_SYMOP(IC_RESULT(ic)) &&
2340 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2341 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2342 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2344 debugLog (" %d - \n", __LINE__);
2347 debugLog (" %d - \n", __LINE__);
2356 /* Check for and fix any problems with uninitialized operands */
2357 for (i = 0; i < count; i++)
2361 if (ebbs[i]->noPath &&
2362 (ebbs[i]->entryLabel != entryLabel &&
2363 ebbs[i]->entryLabel != returnLabel))
2366 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2373 verifyRegsAssigned (IC_COND (ic), ic);
2377 if (ic->op == JUMPTABLE)
2379 verifyRegsAssigned (IC_JTCOND (ic), ic);
2383 verifyRegsAssigned (IC_RESULT (ic), ic);
2384 verifyRegsAssigned (IC_LEFT (ic), ic);
2385 verifyRegsAssigned (IC_RIGHT (ic), ic);
2391 /*-----------------------------------------------------------------*/
2392 /* rUmaskForOp :- returns register mask for an operand */
2393 /*-----------------------------------------------------------------*/
2395 rUmaskForOp (operand * op)
2401 debugLog ("%s\n", __FUNCTION__);
2402 /* only temporaries are assigned registers */
2406 sym = OP_SYMBOL (op);
2408 /* if spilt or no registers assigned to it
2410 if (sym->isspilt || !sym->nRegs)
2413 rumask = newBitVect (pic14_nRegs);
2415 for (j = 0; j < sym->nRegs; j++)
2417 rumask = bitVectSetBit (rumask,
2418 sym->regs[j]->rIdx);
2424 /*-----------------------------------------------------------------*/
2425 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2426 /*-----------------------------------------------------------------*/
2428 regsUsedIniCode (iCode * ic)
2430 bitVect *rmask = newBitVect (pic14_nRegs);
2432 debugLog ("%s\n", __FUNCTION__);
2433 /* do the special cases first */
2436 rmask = bitVectUnion (rmask,
2437 rUmaskForOp (IC_COND (ic)));
2441 /* for the jumptable */
2442 if (ic->op == JUMPTABLE)
2444 rmask = bitVectUnion (rmask,
2445 rUmaskForOp (IC_JTCOND (ic)));
2450 /* of all other cases */
2452 rmask = bitVectUnion (rmask,
2453 rUmaskForOp (IC_LEFT (ic)));
2457 rmask = bitVectUnion (rmask,
2458 rUmaskForOp (IC_RIGHT (ic)));
2461 rmask = bitVectUnion (rmask,
2462 rUmaskForOp (IC_RESULT (ic)));
2468 /*-----------------------------------------------------------------*/
2469 /* createRegMask - for each instruction will determine the regsUsed */
2470 /*-----------------------------------------------------------------*/
2472 createRegMask (eBBlock ** ebbs, int count)
2476 debugLog ("%s\n", __FUNCTION__);
2477 /* for all blocks */
2478 for (i = 0; i < count; i++)
2482 if (ebbs[i]->noPath &&
2483 (ebbs[i]->entryLabel != entryLabel &&
2484 ebbs[i]->entryLabel != returnLabel))
2487 /* for all instructions */
2488 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2493 if (SKIP_IC2 (ic) || !ic->rlive)
2496 /* first mark the registers used in this
2498 ic->rUsed = regsUsedIniCode (ic);
2499 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2501 /* now create the register mask for those
2502 registers that are in use : this is a
2503 super set of ic->rUsed */
2504 ic->rMask = newBitVect (pic14_nRegs + 1);
2506 /* for all live Ranges alive at this point */
2507 for (j = 1; j < ic->rlive->size; j++)
2512 /* if not alive then continue */
2513 if (!bitVectBitValue (ic->rlive, j))
2516 /* find the live range we are interested in */
2517 if (!(sym = hTabItemWithKey (liveRanges, j)))
2519 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2520 "createRegMask cannot find live range");
2524 /* if no register assigned to it */
2525 if (!sym->nRegs || sym->isspilt)
2528 /* for all the registers allocated to it */
2529 for (k = 0; k < sym->nRegs; k++)
2532 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2538 /* This was the active version */
2539 /*-----------------------------------------------------------------*/
2540 /* rematStr - returns the rematerialized string for a remat var */
2541 /*-----------------------------------------------------------------*/
2543 rematStr (symbol * sym)
2546 iCode *ic = sym->rematiCode;
2547 symbol *psym = NULL;
2549 debugLog ("%s\n", __FUNCTION__);
2551 //printf ("%s\n", s);
2553 /* if plus or minus print the right hand side */
2555 if (ic->op == '+' || ic->op == '-') {
2557 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2559 sprintf (s, "(%s %c 0x%04x)",
2560 OP_SYMBOL (IC_LEFT (ric))->rname,
2562 (int) operandLitValue (IC_RIGHT (ic)));
2565 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2567 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2568 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2573 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2574 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2576 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2582 /* deprecated version */
2583 /*-----------------------------------------------------------------*/
2584 /* rematStr - returns the rematerialized string for a remat var */
2585 /*-----------------------------------------------------------------*/
2587 rematStr (symbol * sym)
2590 iCode *ic = sym->rematiCode;
2592 debugLog ("%s\n", __FUNCTION__);
2597 /* if plus or minus print the right hand side */
2599 if (ic->op == '+' || ic->op == '-') {
2600 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2603 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2607 if (ic->op == '+' || ic->op == '-')
2609 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2610 sprintf (s, "(%s %c 0x%04x)",
2611 OP_SYMBOL (IC_LEFT (ric))->rname,
2613 (int) operandLitValue (IC_RIGHT (ic)));
2616 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2618 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2622 /* we reached the end */
2623 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2627 printf ("%s\n", buffer);
2632 /*-----------------------------------------------------------------*/
2633 /* regTypeNum - computes the type & number of registers required */
2634 /*-----------------------------------------------------------------*/
2642 debugLog ("%s\n", __FUNCTION__);
2643 /* for each live range do */
2644 for (sym = hTabFirstItem (liveRanges, &k); sym;
2645 sym = hTabNextItem (liveRanges, &k)) {
2647 debugLog (" %d - %s\n", __LINE__, sym->rname);
2649 /* if used zero times then no registers needed */
2650 if ((sym->liveTo - sym->liveFrom) == 0)
2654 /* if the live range is a temporary */
2657 debugLog (" %d - itemp register\n", __LINE__);
2659 /* if the type is marked as a conditional */
2660 if (sym->regType == REG_CND)
2663 /* if used in return only then we don't
2666 if (IS_AGGREGATE (sym->type) || sym->isptr)
2667 sym->type = aggrToPtr (sym->type, FALSE);
2668 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2674 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2675 // sym->type = aggrToPtr (sym->type, FALSE);
2676 debugLog (" %d - used as a return\n", __LINE__);
2681 /* if the symbol has only one definition &
2682 that definition is a get_pointer and the
2683 pointer we are getting is rematerializable and
2687 if (bitVectnBitsOn (sym->defs) == 1 &&
2688 (ic = hTabItemWithKey (iCodehTab,
2689 bitVectFirstBit (sym->defs))) &&
2691 !IS_BITVAR (sym->etype) &&
2692 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2694 if (ptrPseudoSymSafe (sym, ic)) {
2698 debugLog (" %d - \n", __LINE__);
2700 /* create a psuedo symbol & force a spil */
2701 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2702 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2703 psym->type = sym->type;
2704 psym->etype = sym->etype;
2705 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2706 strcpy (psym->rname, psym->name);
2708 sym->usl.spillLoc = psym;
2712 /* if in data space or idata space then try to
2713 allocate pointer register */
2718 /* if not then we require registers */
2719 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2720 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2721 getSize (sym->type));
2724 if(IS_PTR_CONST (sym->type)) {
2725 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2729 if (sym->nRegs > 4) {
2730 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2731 printTypeChain (sym->type, stderr);
2732 fprintf (stderr, "\n");
2735 /* determine the type of register required */
2736 if (sym->nRegs == 1 &&
2737 IS_PTR (sym->type) &&
2739 sym->regType = REG_PTR;
2741 sym->regType = REG_GPR;
2744 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2748 /* for the first run we don't provide */
2749 /* registers for true symbols we will */
2750 /* see how things go */
2755 DEFSETFUNC (markRegFree)
2757 ((regs *)item)->isFree = 1;
2762 DEFSETFUNC (deallocReg)
2764 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2765 ((regs *)item)->isFree = 1;
2766 ((regs *)item)->wasUsed = 0;
2770 /*-----------------------------------------------------------------*/
2771 /* freeAllRegs - mark all registers as free */
2772 /*-----------------------------------------------------------------*/
2774 pic14_freeAllRegs ()
2778 debugLog ("%s\n", __FUNCTION__);
2780 applyToSet(dynAllocRegs,markRegFree);
2781 applyToSet(dynStackRegs,markRegFree);
2784 for (i = 0; i < pic14_nRegs; i++)
2785 regspic14[i].isFree = 1;
2789 /*-----------------------------------------------------------------*/
2790 /*-----------------------------------------------------------------*/
2792 pic14_deallocateAllRegs ()
2796 debugLog ("%s\n", __FUNCTION__);
2798 applyToSet(dynAllocRegs,deallocReg);
2801 for (i = 0; i < pic14_nRegs; i++) {
2802 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2803 regspic14[i].isFree = 1;
2804 regspic14[i].wasUsed = 0;
2811 /*-----------------------------------------------------------------*/
2812 /* deallocStackSpil - this will set the stack pointer back */
2813 /*-----------------------------------------------------------------*/
2815 DEFSETFUNC (deallocStackSpil)
2819 debugLog ("%s\n", __FUNCTION__);
2824 /*-----------------------------------------------------------------*/
2825 /* farSpacePackable - returns the packable icode for far variables */
2826 /*-----------------------------------------------------------------*/
2828 farSpacePackable (iCode * ic)
2832 debugLog ("%s\n", __FUNCTION__);
2833 /* go thru till we find a definition for the
2834 symbol on the right */
2835 for (dic = ic->prev; dic; dic = dic->prev)
2838 /* if the definition is a call then no */
2839 if ((dic->op == CALL || dic->op == PCALL) &&
2840 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2845 /* if shift by unknown amount then not */
2846 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2847 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2850 /* if pointer get and size > 1 */
2851 if (POINTER_GET (dic) &&
2852 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2855 if (POINTER_SET (dic) &&
2856 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2859 /* if any three is a true symbol in far space */
2860 if (IC_RESULT (dic) &&
2861 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2862 isOperandInFarSpace (IC_RESULT (dic)))
2865 if (IC_RIGHT (dic) &&
2866 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2867 isOperandInFarSpace (IC_RIGHT (dic)) &&
2868 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2871 if (IC_LEFT (dic) &&
2872 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2873 isOperandInFarSpace (IC_LEFT (dic)) &&
2874 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2877 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2879 if ((dic->op == LEFT_OP ||
2880 dic->op == RIGHT_OP ||
2882 IS_OP_LITERAL (IC_RIGHT (dic)))
2892 /*-----------------------------------------------------------------*/
2893 /* packRegsForAssign - register reduction for assignment */
2894 /*-----------------------------------------------------------------*/
2896 packRegsForAssign (iCode * ic, eBBlock * ebp)
2901 debugLog ("%s\n", __FUNCTION__);
2903 debugAopGet (" result:", IC_RESULT (ic));
2904 debugAopGet (" left:", IC_LEFT (ic));
2905 debugAopGet (" right:", IC_RIGHT (ic));
2907 /* if this is at an absolute address, then get the address. */
2908 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2909 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2910 debugLog (" %d - found config word declaration\n", __LINE__);
2911 if(IS_VALOP(IC_RIGHT(ic))) {
2912 debugLog (" setting config word to %x\n",
2913 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2914 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2915 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2918 /* remove the assignment from the iCode chain. */
2920 remiCodeFromeBBlock (ebp, ic);
2921 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2922 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2929 if (!IS_ITEMP (IC_RESULT (ic))) {
2930 allocDirReg(IC_RESULT (ic));
2931 debugLog (" %d - result is not temp\n", __LINE__);
2934 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2935 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2936 allocDirReg(IC_LEFT (ic));
2940 if (!IS_ITEMP (IC_RIGHT (ic))) {
2941 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2943 /* only pack if this is not a function pointer */
2944 if (!IS_REF (IC_RIGHT (ic)))
2945 allocDirReg(IC_RIGHT (ic));
2949 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2950 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2952 debugLog (" %d - not packing - right side fails \n", __LINE__);
2956 /* if the true symbol is defined in far space or on stack
2957 then we should not since this will increase register pressure */
2958 if (isOperandInFarSpace (IC_RESULT (ic)))
2960 if ((dic = farSpacePackable (ic)))
2966 /* find the definition of iTempNN scanning backwards if we find a
2967 a use of the true symbol before we find the definition then
2969 for (dic = ic->prev; dic; dic = dic->prev)
2972 /* if there is a function call and this is
2973 a parameter & not my parameter then don't pack it */
2974 if ((dic->op == CALL || dic->op == PCALL) &&
2975 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2976 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2978 debugLog (" %d - \n", __LINE__);
2986 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2987 IS_OP_VOLATILE (IC_RESULT (dic)))
2989 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2994 if (IS_SYMOP (IC_RESULT (dic)) &&
2995 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2997 /* A previous result was assigned to the same register - we'll our definition */
2998 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2999 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3000 if (POINTER_SET (dic))
3006 if (IS_SYMOP (IC_RIGHT (dic)) &&
3007 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3008 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3010 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3015 if (IS_SYMOP (IC_LEFT (dic)) &&
3016 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3017 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3019 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3024 if (POINTER_SET (dic) &&
3025 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3027 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3035 return 0; /* did not find */
3037 /* if the result is on stack or iaccess then it must be
3038 the same at least one of the operands */
3039 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3040 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3043 /* the operation has only one symbol
3044 operator then we can pack */
3045 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3046 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3049 if (!((IC_LEFT (dic) &&
3050 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3052 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3056 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3057 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3058 /* found the definition */
3059 /* replace the result with the result of */
3060 /* this assignment and remove this assignment */
3061 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3062 IC_RESULT (dic) = IC_RESULT (ic);
3064 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3066 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3068 /* delete from liverange table also
3069 delete from all the points inbetween and the new
3071 for (sic = dic; sic != ic; sic = sic->next)
3073 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3074 if (IS_ITEMP (IC_RESULT (dic)))
3075 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3078 remiCodeFromeBBlock (ebp, ic);
3079 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3080 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3081 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3087 /*-----------------------------------------------------------------*/
3088 /* findAssignToSym : scanning backwards looks for first assig found */
3089 /*-----------------------------------------------------------------*/
3091 findAssignToSym (operand * op, iCode * ic)
3095 debugLog ("%s\n", __FUNCTION__);
3096 for (dic = ic->prev; dic; dic = dic->prev)
3099 /* if definition by assignment */
3100 if (dic->op == '=' &&
3101 !POINTER_SET (dic) &&
3102 IC_RESULT (dic)->key == op->key
3103 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3107 /* we are interested only if defined in far space */
3108 /* or in stack space in case of + & - */
3110 /* if assigned to a non-symbol then return
3112 if (!IS_SYMOP (IC_RIGHT (dic)))
3115 /* if the symbol is in far space then
3117 if (isOperandInFarSpace (IC_RIGHT (dic)))
3120 /* for + & - operations make sure that
3121 if it is on the stack it is the same
3122 as one of the three operands */
3123 if ((ic->op == '+' || ic->op == '-') &&
3124 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3127 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3128 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3129 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3137 /* if we find an usage then we cannot delete it */
3138 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3141 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3144 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3148 /* now make sure that the right side of dic
3149 is not defined between ic & dic */
3152 iCode *sic = dic->next;
3154 for (; sic != ic; sic = sic->next)
3155 if (IC_RESULT (sic) &&
3156 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3165 /*-----------------------------------------------------------------*/
3166 /* packRegsForSupport :- reduce some registers for support calls */
3167 /*-----------------------------------------------------------------*/
3169 packRegsForSupport (iCode * ic, eBBlock * ebp)
3173 debugLog ("%s\n", __FUNCTION__);
3174 /* for the left & right operand :- look to see if the
3175 left was assigned a true symbol in far space in that
3176 case replace them */
3177 if (IS_ITEMP (IC_LEFT (ic)) &&
3178 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3180 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3186 debugAopGet ("removing left:", IC_LEFT (ic));
3188 /* found it we need to remove it from the
3190 for (sic = dic; sic != ic; sic = sic->next)
3191 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3193 IC_LEFT (ic)->operand.symOperand =
3194 IC_RIGHT (dic)->operand.symOperand;
3195 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3196 remiCodeFromeBBlock (ebp, dic);
3197 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3198 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3202 /* do the same for the right operand */
3205 IS_ITEMP (IC_RIGHT (ic)) &&
3206 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3208 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3214 /* if this is a subtraction & the result
3215 is a true symbol in far space then don't pack */
3216 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3218 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3219 if (IN_FARSPACE (SPEC_OCLS (etype)))
3223 debugAopGet ("removing right:", IC_RIGHT (ic));
3225 /* found it we need to remove it from the
3227 for (sic = dic; sic != ic; sic = sic->next)
3228 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3230 IC_RIGHT (ic)->operand.symOperand =
3231 IC_RIGHT (dic)->operand.symOperand;
3232 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3234 remiCodeFromeBBlock (ebp, dic);
3235 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3236 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3243 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3246 /*-----------------------------------------------------------------*/
3247 /* packRegsForOneuse : - will reduce some registers for single Use */
3248 /*-----------------------------------------------------------------*/
3250 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3255 debugLog ("%s\n", __FUNCTION__);
3256 /* if returning a literal then do nothing */
3260 /* only upto 2 bytes since we cannot predict
3261 the usage of b, & acc */
3262 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3267 /* this routine will mark the a symbol as used in one
3268 instruction use only && if the definition is local
3269 (ie. within the basic block) && has only one definition &&
3270 that definition is either a return value from a
3271 function or does not contain any variables in
3273 uses = bitVectCopy (OP_USES (op));
3274 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3275 if (!bitVectIsZero (uses)) /* has other uses */
3278 /* if it has only one defintion */
3279 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3280 return NULL; /* has more than one definition */
3282 /* get that definition */
3284 hTabItemWithKey (iCodehTab,
3285 bitVectFirstBit (OP_DEFS (op)))))
3288 /* found the definition now check if it is local */
3289 if (dic->seq < ebp->fSeq ||
3290 dic->seq > ebp->lSeq)
3291 return NULL; /* non-local */
3293 /* now check if it is the return from
3295 if (dic->op == CALL || dic->op == PCALL)
3297 if (ic->op != SEND && ic->op != RETURN &&
3298 !POINTER_SET(ic) && !POINTER_GET(ic))
3300 OP_SYMBOL (op)->ruonly = 1;
3307 /* otherwise check that the definition does
3308 not contain any symbols in far space */
3309 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3310 isOperandInFarSpace (IC_RIGHT (dic)) ||
3311 IS_OP_RUONLY (IC_LEFT (ic)) ||
3312 IS_OP_RUONLY (IC_RIGHT (ic)))
3317 /* if pointer set then make sure the pointer
3319 if (POINTER_SET (dic) &&
3320 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3323 if (POINTER_GET (dic) &&
3324 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3329 /* also make sure the intervenening instructions
3330 don't have any thing in far space */
3331 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3334 /* if there is an intervening function call then no */
3335 if (dic->op == CALL || dic->op == PCALL)
3337 /* if pointer set then make sure the pointer
3339 if (POINTER_SET (dic) &&
3340 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3343 if (POINTER_GET (dic) &&
3344 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3347 /* if address of & the result is remat then okay */
3348 if (dic->op == ADDRESS_OF &&
3349 OP_SYMBOL (IC_RESULT (dic))->remat)
3352 /* if operand has size of three or more & this
3353 operation is a '*','/' or '%' then 'b' may
3355 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3356 getSize (operandType (op)) >= 3)
3359 /* if left or right or result is in far space */
3360 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3361 isOperandInFarSpace (IC_RIGHT (dic)) ||
3362 isOperandInFarSpace (IC_RESULT (dic)) ||
3363 IS_OP_RUONLY (IC_LEFT (dic)) ||
3364 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3365 IS_OP_RUONLY (IC_RESULT (dic)))
3371 OP_SYMBOL (op)->ruonly = 1;
3376 /*-----------------------------------------------------------------*/
3377 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3378 /*-----------------------------------------------------------------*/
3380 isBitwiseOptimizable (iCode * ic)
3382 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3383 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3385 debugLog ("%s\n", __FUNCTION__);
3386 /* bitwise operations are considered optimizable
3387 under the following conditions (Jean-Louis VERN)
3399 if (IS_LITERAL (rtype) ||
3400 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3406 /*-----------------------------------------------------------------*/
3407 /* packRegsForAccUse - pack registers for acc use */
3408 /*-----------------------------------------------------------------*/
3410 packRegsForAccUse (iCode * ic)
3414 debugLog ("%s\n", __FUNCTION__);
3416 /* result too large for WREG? */
3417 if (getSize (operandType (IC_RESULT (ic))) > 1)
3420 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3421 * is never used as an operand to an instruction that
3422 * cannot have WREG as an operand (e.g. BTFSx cannot
3423 * operate on WREG...
3424 * For now, store all results into proper registers. */
3428 /* if this is an aggregate, e.g. a one byte char array */
3429 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3432 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3434 /* if + or - then it has to be one byte result */
3435 if ((ic->op == '+' || ic->op == '-')
3436 && getSize (operandType (IC_RESULT (ic))) > 1)
3439 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3440 /* if shift operation make sure right side is not a literal */
3441 if (ic->op == RIGHT_OP &&
3442 (isOperandLiteral (IC_RIGHT (ic)) ||
3443 getSize (operandType (IC_RESULT (ic))) > 1))
3446 if (ic->op == LEFT_OP &&
3447 (isOperandLiteral (IC_RIGHT (ic)) ||
3448 getSize (operandType (IC_RESULT (ic))) > 1))
3451 if (IS_BITWISE_OP (ic) &&
3452 getSize (operandType (IC_RESULT (ic))) > 1)
3456 /* has only one definition */
3457 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3460 /* has only one use */
3461 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3464 /* and the usage immediately follows this iCode */
3465 if (!(uic = hTabItemWithKey (iCodehTab,
3466 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3469 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3470 if (ic->next != uic)
3473 /* if it is a conditional branch then we definitely can */
3477 if (uic->op == JUMPTABLE)
3480 /* if the usage is not is an assignment
3481 or an arithmetic / bitwise / shift operation then not */
3482 if (POINTER_SET (uic) &&
3483 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3486 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3487 if (uic->op != '=' &&
3488 !IS_ARITHMETIC_OP (uic) &&
3489 !IS_BITWISE_OP (uic) &&
3490 uic->op != LEFT_OP &&
3491 uic->op != RIGHT_OP)
3494 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3495 /* if used in ^ operation then make sure right is not a
3497 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3500 /* if shift operation make sure right side is not a literal */
3501 if (uic->op == RIGHT_OP &&
3502 (isOperandLiteral (IC_RIGHT (uic)) ||
3503 getSize (operandType (IC_RESULT (uic))) > 1))
3506 if (uic->op == LEFT_OP &&
3507 (isOperandLiteral (IC_RIGHT (uic)) ||
3508 getSize (operandType (IC_RESULT (uic))) > 1))
3511 /* make sure that the result of this icode is not on the
3512 stack, since acc is used to compute stack offset */
3513 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3514 OP_SYMBOL (IC_RESULT (uic))->onStack)
3517 /* if either one of them in far space then we cannot */
3518 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3519 isOperandInFarSpace (IC_LEFT (uic))) ||
3520 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3521 isOperandInFarSpace (IC_RIGHT (uic))))
3524 /* if the usage has only one operand then we can */
3525 if (IC_LEFT (uic) == NULL ||
3526 IC_RIGHT (uic) == NULL)
3529 /* make sure this is on the left side if not
3530 a '+' since '+' is commutative */
3531 if (ic->op != '+' &&
3532 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3535 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3536 /* if one of them is a literal then we can */
3537 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3538 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3539 (getSize (operandType (IC_RESULT (uic))) <= 1))
3541 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3545 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3546 /* if the other one is not on stack then we can */
3547 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3548 (IS_ITEMP (IC_RIGHT (uic)) ||
3549 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3550 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3553 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3554 (IS_ITEMP (IC_LEFT (uic)) ||
3555 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3556 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3562 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3563 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3567 /*-----------------------------------------------------------------*/
3568 /* packForPush - hueristics to reduce iCode for pushing */
3569 /*-----------------------------------------------------------------*/
3571 packForReceive (iCode * ic, eBBlock * ebp)
3575 debugLog ("%s\n", __FUNCTION__);
3576 debugAopGet (" result:", IC_RESULT (ic));
3577 debugAopGet (" left:", IC_LEFT (ic));
3578 debugAopGet (" right:", IC_RIGHT (ic));
3583 for (dic = ic->next; dic; dic = dic->next)
3588 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3589 debugLog (" used on left\n");
3590 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3591 debugLog (" used on right\n");
3592 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3593 debugLog (" used on result\n");
3595 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3596 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3601 debugLog (" hey we can remove this unnecessary assign\n");
3603 /*-----------------------------------------------------------------*/
3604 /* packForPush - hueristics to reduce iCode for pushing */
3605 /*-----------------------------------------------------------------*/
3607 packForPush (iCode * ic, eBBlock * ebp)
3611 debugLog ("%s\n", __FUNCTION__);
3612 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3615 /* must have only definition & one usage */
3616 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3617 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3620 /* find the definition */
3621 if (!(dic = hTabItemWithKey (iCodehTab,
3622 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3625 if (dic->op != '=' || POINTER_SET (dic))
3628 /* we now we know that it has one & only one def & use
3629 and the that the definition is an assignment */
3630 IC_LEFT (ic) = IC_RIGHT (dic);
3632 remiCodeFromeBBlock (ebp, dic);
3633 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3634 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3637 void printSymType(char * str, sym_link *sl)
3639 debugLog (" %s Symbol type: ",str);
3640 printTypeChain( sl, debugF);
3645 /*-----------------------------------------------------------------*/
3646 /* some debug code to print the symbol S_TYPE. Note that
3647 * the function checkSClass in src/SDCCsymt.c dinks with
3648 * the S_TYPE in ways the PIC port doesn't fully like...*/
3649 /*-----------------------------------------------------------------*/
3650 void isData(sym_link *sl)
3660 for ( ; sl; sl=sl->next) {
3662 switch (SPEC_SCLS(sl)) {
3664 case S_DATA: fprintf (of, "data "); break;
3665 case S_XDATA: fprintf (of, "xdata "); break;
3666 case S_SFR: fprintf (of, "sfr "); break;
3667 case S_SBIT: fprintf (of, "sbit "); break;
3668 case S_CODE: fprintf (of, "code "); break;
3669 case S_IDATA: fprintf (of, "idata "); break;
3670 case S_PDATA: fprintf (of, "pdata "); break;
3671 case S_LITERAL: fprintf (of, "literal "); break;
3672 case S_STACK: fprintf (of, "stack "); break;
3673 case S_XSTACK: fprintf (of, "xstack "); break;
3674 case S_BIT: fprintf (of, "bit "); break;
3675 case S_EEPROM: fprintf (of, "eeprom "); break;
3685 /*-----------------------------------------------------------------*/
3686 /* packRegisters - does some transformations to reduce register */
3688 /*-----------------------------------------------------------------*/
3690 packRegisters (eBBlock * ebp)
3695 debugLog ("%s\n", __FUNCTION__);
3701 /* look for assignments of the form */
3702 /* iTempNN = TRueSym (someoperation) SomeOperand */
3704 /* TrueSym := iTempNN:1 */
3705 for (ic = ebp->sch; ic; ic = ic->next)
3708 /* find assignment of the form TrueSym := iTempNN:1 */
3709 if (ic->op == '=' && !POINTER_SET (ic))
3710 change += packRegsForAssign (ic, ebp);
3714 if (POINTER_SET (ic))
3715 debugLog ("pointer is set\n");
3716 debugAopGet (" result:", IC_RESULT (ic));
3717 debugAopGet (" left:", IC_LEFT (ic));
3718 debugAopGet (" right:", IC_RIGHT (ic));
3727 for (ic = ebp->sch; ic; ic = ic->next) {
3729 if(IS_SYMOP ( IC_LEFT(ic))) {
3730 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3732 debugAopGet (" left:", IC_LEFT (ic));
3733 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3734 debugLog (" is a pointer\n");
3736 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3737 debugLog (" is volatile\n");
3741 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3744 if(IS_SYMOP ( IC_RIGHT(ic))) {
3745 debugAopGet (" right:", IC_RIGHT (ic));
3746 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3749 if(IS_SYMOP ( IC_RESULT(ic))) {
3750 debugAopGet (" result:", IC_RESULT (ic));
3751 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3754 if (POINTER_SET (ic))
3755 debugLog (" %d - Pointer set\n", __LINE__);
3758 /* Look for two subsequent iCodes with */
3760 /* _c = iTemp & op; */
3761 /* and replace them by */
3764 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3766 ic->prev->op == '=' &&
3767 IS_ITEMP (IC_LEFT (ic)) &&
3768 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3769 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3771 iCode* ic_prev = ic->prev;
3772 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3774 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3775 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3777 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3778 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3779 prev_result_sym->liveTo == ic->seq)
3781 prev_result_sym->liveTo = ic_prev->seq;
3784 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3786 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3788 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3790 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3791 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3792 remiCodeFromeBBlock (ebp, ic_prev);
3793 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3797 /* if this is an itemp & result of a address of a true sym
3798 then mark this as rematerialisable */
3799 if (ic->op == ADDRESS_OF &&
3800 IS_ITEMP (IC_RESULT (ic)) &&
3801 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3802 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3803 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3806 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3808 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3809 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3810 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3814 /* if straight assignment then carry remat flag if
3815 this is the only definition */
3816 if (ic->op == '=' &&
3817 !POINTER_SET (ic) &&
3818 IS_SYMOP (IC_RIGHT (ic)) &&
3819 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3820 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3822 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3824 OP_SYMBOL (IC_RESULT (ic))->remat =
3825 OP_SYMBOL (IC_RIGHT (ic))->remat;
3826 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3827 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3830 /* if this is a +/- operation with a rematerizable
3831 then mark this as rematerializable as well */
3832 if ((ic->op == '+' || ic->op == '-') &&
3833 (IS_SYMOP (IC_LEFT (ic)) &&
3834 IS_ITEMP (IC_RESULT (ic)) &&
3835 OP_SYMBOL (IC_LEFT (ic))->remat &&
3836 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3837 IS_OP_LITERAL (IC_RIGHT (ic))))
3839 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3841 operandLitValue (IC_RIGHT (ic));
3842 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3843 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3844 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3847 /* mark the pointer usages */
3848 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3850 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3851 debugLog (" marking as a pointer (set) =>");
3852 debugAopGet (" result:", IC_RESULT (ic));
3854 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3856 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3857 debugLog (" marking as a pointer (get) =>");
3858 debugAopGet (" left:", IC_LEFT (ic));
3863 /* if we are using a symbol on the stack
3864 then we should say pic14_ptrRegReq */
3865 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3866 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3867 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3868 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3869 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3870 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3873 if (IS_SYMOP (IC_LEFT (ic)))
3874 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3875 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3876 if (IS_SYMOP (IC_RIGHT (ic)))
3877 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3878 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3879 if (IS_SYMOP (IC_RESULT (ic)))
3880 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3881 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3884 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3888 /* if the condition of an if instruction
3889 is defined in the previous instruction then
3890 mark the itemp as a conditional */
3891 if ((IS_CONDITIONAL (ic) ||
3892 ((ic->op == BITWISEAND ||
3895 isBitwiseOptimizable (ic))) &&
3896 ic->next && ic->next->op == IFX &&
3897 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3898 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3901 debugLog (" %d\n", __LINE__);
3902 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3906 /* reduce for support function calls */
3907 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3908 packRegsForSupport (ic, ebp);
3910 /* if a parameter is passed, it's in W, so we may not
3911 need to place a copy in a register */
3912 if (ic->op == RECEIVE)
3913 packForReceive (ic, ebp);
3915 /* some cases the redundant moves can
3916 can be eliminated for return statements */
3917 if ((ic->op == RETURN || ic->op == SEND) &&
3918 !isOperandInFarSpace (IC_LEFT (ic)) &&
3920 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3922 /* if pointer set & left has a size more than
3923 one and right is not in far space */
3924 if (POINTER_SET (ic) &&
3925 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3926 IS_SYMOP(IC_RESULT(ic)) &&
3927 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3928 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3929 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3931 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3933 /* if pointer get */
3934 if (POINTER_GET (ic) &&
3935 !isOperandInFarSpace (IC_RESULT (ic)) &&
3936 IS_SYMOP(IC_LEFT(ic)) &&
3937 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3938 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3939 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3941 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3944 /* if this is cast for intergral promotion then
3945 check if only use of the definition of the
3946 operand being casted/ if yes then replace
3947 the result of that arithmetic operation with
3948 this result and get rid of the cast */
3949 if (ic->op == CAST) {
3951 sym_link *fromType = operandType (IC_RIGHT (ic));
3952 sym_link *toType = operandType (IC_LEFT (ic));
3954 debugLog (" %d - casting\n", __LINE__);
3956 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3957 getSize (fromType) != getSize (toType)) {
3960 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3963 if (IS_ARITHMETIC_OP (dic)) {
3965 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3966 IC_RESULT (dic) = IC_RESULT (ic);
3967 remiCodeFromeBBlock (ebp, ic);
3968 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3969 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3970 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3974 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3978 /* if the type from and type to are the same
3979 then if this is the only use then packit */
3980 if (compareType (operandType (IC_RIGHT (ic)),
3981 operandType (IC_LEFT (ic))) == 1) {
3983 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3986 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3987 IC_RESULT (dic) = IC_RESULT (ic);
3988 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3989 remiCodeFromeBBlock (ebp, ic);
3990 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3991 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3999 iTempNN := (some variable in farspace) V1
4004 if (ic->op == IPUSH)
4006 packForPush (ic, ebp);
4010 /* pack registers for accumulator use, when the
4011 result of an arithmetic or bit wise operation
4012 has only one use, that use is immediately following
4013 the defintion and the using iCode has only one
4014 operand or has two operands but one is literal &
4015 the result of that operation is not on stack then
4016 we can leave the result of this operation in acc:b
4018 if ((IS_ARITHMETIC_OP (ic)
4020 || IS_BITWISE_OP (ic)
4022 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4025 IS_ITEMP (IC_RESULT (ic)) &&
4026 getSize (operandType (IC_RESULT (ic))) <= 2)
4028 packRegsForAccUse (ic);
4034 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4038 if (!debug || !debugF)
4041 for (i = 0; i < count; i++)
4043 fprintf (debugF, "\n----------------------------------------------------------------\n");
4044 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4045 ebbs[i]->entryLabel->name,
4048 ebbs[i]->isLastInLoop);
4049 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4054 fprintf (debugF, "visited %d : hasFcall = %d\n",
4058 fprintf (debugF, "\ndefines bitVector :");
4059 bitVectDebugOn (ebbs[i]->defSet, debugF);
4060 fprintf (debugF, "\nlocal defines bitVector :");
4061 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4062 fprintf (debugF, "\npointers Set bitvector :");
4063 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4064 fprintf (debugF, "\nin pointers Set bitvector :");
4065 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4066 fprintf (debugF, "\ninDefs Set bitvector :");
4067 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4068 fprintf (debugF, "\noutDefs Set bitvector :");
4069 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4070 fprintf (debugF, "\nusesDefs Set bitvector :");
4071 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4072 fprintf (debugF, "\n----------------------------------------------------------------\n");
4073 printiCChain (ebbs[i]->sch, debugF);
4076 /*-----------------------------------------------------------------*/
4077 /* assignRegisters - assigns registers to each live range as need */
4078 /*-----------------------------------------------------------------*/
4080 pic14_assignRegisters (ebbIndex * ebbi)
4082 eBBlock ** ebbs = ebbi->bbOrder;
4083 int count = ebbi->count;
4087 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4088 debugLog ("\nebbs before optimizing:\n");
4089 dumpEbbsToDebug (ebbs, count);
4091 setToNull ((void *) &_G.funcrUsed);
4092 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4095 /* change assignments this will remove some
4096 live ranges reducing some register pressure */
4097 for (i = 0; i < count; i++)
4098 packRegisters (ebbs[i]);
4105 debugLog("dir registers allocated so far:\n");
4106 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4109 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4110 reg = hTabNextItem(dynDirectRegNames, &hkey);
4115 if (options.dump_pack)
4116 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4118 /* first determine for each live range the number of
4119 registers & the type of registers required for each */
4122 /* and serially allocate registers */
4123 serialRegAssign (ebbs, count);
4125 /* if stack was extended then tell the user */
4128 /* werror(W_TOOMANY_SPILS,"stack", */
4129 /* _G.stackExtend,currFunc->name,""); */
4135 /* werror(W_TOOMANY_SPILS,"data space", */
4136 /* _G.dataExtend,currFunc->name,""); */
4140 /* after that create the register mask
4141 for each of the instruction */
4142 createRegMask (ebbs, count);
4144 /* redo that offsets for stacked automatic variables */
4145 redoStackOffsets ();
4147 if (options.dump_rassgn)
4148 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4150 /* now get back the chain */
4151 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4153 debugLog ("ebbs after optimizing:\n");
4154 dumpEbbsToDebug (ebbs, count);
4159 /* free up any _G.stackSpil locations allocated */
4160 applyToSet (_G.stackSpil, deallocStackSpil);
4162 setToNull ((void *) &_G.stackSpil);
4163 setToNull ((void *) &_G.spiltSet);
4164 /* mark all registers as free */
4165 //pic14_freeAllRegs ();
4167 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");