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((unsigned char)*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 /* Prevent the result from being assigned the same registers as (one)
1949 * operand as many genXXX-functions fail otherwise.
1950 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1951 * are known to fail. */
1952 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1956 case '=': /* assignment */
1957 case BITWISEAND: /* bitwise AND */
1958 case '|': /* bitwise OR */
1959 case '^': /* bitwise XOR */
1960 case '~': /* bitwise negate */
1961 case RLC: /* rotate through carry */
1964 case '+': /* addition */
1965 case '-': /* subtraction */
1966 /* go ahead, these are safe to use with
1967 * non-disjoint register sets */
1971 /* do not release operand registers */
1972 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1977 /* if it was spilt on stack then we can
1978 mark the stack spil location as free */
1983 sym->usl.spillLoc->isFree = 1;
1989 if (!bitVectBitValue (_G.regAssigned, sym->key))
1991 /* special case check if this is an IFX &
1992 the privious one was a pop and the
1993 previous one was not spilt then keep track
1995 if (ic->op == IFX && ic->prev &&
1996 ic->prev->op == IPOP &&
1997 !ic->prev->parmPush &&
1998 IS_SYMOP(IC_LEFT (ic->prev)) &&
1999 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2000 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2006 bitVectUnSetBit (_G.regAssigned, sym->key);
2008 /* if the result of this one needs registers
2009 and does not have it then assign it right
2011 if (IC_RESULT (ic) &&
2012 !(SKIP_IC2 (ic) || /* not a special icode */
2013 ic->op == JUMPTABLE ||
2018 POINTER_SET (ic)) &&
2019 IS_SYMOP (IC_RESULT (ic)) &&
2020 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2021 result->liveTo > ic->seq && /* and will live beyond this */
2022 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2023 result->liveFrom == ic->seq && /* does not start before here */
2024 result->regType == sym->regType && /* same register types */
2025 result->regType == sym->regType && /* same register types */
2026 result->nRegs && /* which needs registers */
2027 !result->isspilt && /* and does not already have them */
2029 !bitVectBitValue (_G.regAssigned, result->key) &&
2030 /* the number of free regs + number of regs in this LR
2031 can accomodate the what result Needs */
2032 ((nfreeRegsType (result->regType) +
2033 sym->nRegs) >= result->nRegs)
2037 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2039 result->regs[i] = sym->regs[i];
2041 result->regs[i] = getRegGpr (ic, ebp, result);
2043 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2047 /* free the remaining */
2048 for (; i < sym->nRegs; i++)
2052 if (!symHasReg (psym, sym->regs[i]))
2053 freeReg (sym->regs[i]);
2056 freeReg (sym->regs[i]);
2063 /*-----------------------------------------------------------------*/
2064 /* reassignLR - reassign this to registers */
2065 /*-----------------------------------------------------------------*/
2067 reassignLR (operand * op)
2069 symbol *sym = OP_SYMBOL (op);
2072 debugLog ("%s\n", __FUNCTION__);
2073 /* not spilt any more */
2074 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2075 bitVectUnSetBit (_G.spiltSet, sym->key);
2077 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2081 for (i = 0; i < sym->nRegs; i++)
2082 sym->regs[i]->isFree = 0;
2085 /*-----------------------------------------------------------------*/
2086 /* willCauseSpill - determines if allocating will cause a spill */
2087 /*-----------------------------------------------------------------*/
2089 willCauseSpill (int nr, int rt)
2091 debugLog ("%s\n", __FUNCTION__);
2092 /* first check if there are any avlb registers
2093 of te type required */
2096 /* special case for pointer type
2097 if pointer type not avlb then
2098 check for type gpr */
2099 if (nFreeRegs (rt) >= nr)
2101 if (nFreeRegs (REG_GPR) >= nr)
2106 if (pic14_ptrRegReq)
2108 if (nFreeRegs (rt) >= nr)
2113 if (nFreeRegs (REG_PTR) +
2114 nFreeRegs (REG_GPR) >= nr)
2119 debugLog (" ... yep it will (cause a spill)\n");
2120 /* it will cause a spil */
2124 /*-----------------------------------------------------------------*/
2125 /* positionRegs - the allocator can allocate same registers to res- */
2126 /* ult and operand, if this happens make sure they are in the same */
2127 /* position as the operand otherwise chaos results */
2128 /*-----------------------------------------------------------------*/
2130 positionRegs (symbol * result, symbol * opsym, int lineno)
2132 int count = min (result->nRegs, opsym->nRegs);
2133 int i, j = 0, shared = 0;
2135 debugLog ("%s\n", __FUNCTION__);
2136 /* if the result has been spilt then cannot share */
2141 /* first make sure that they actually share */
2142 for (i = 0; i < count; i++)
2144 for (j = 0; j < count; j++)
2146 if (result->regs[i] == opsym->regs[j] && i != j)
2156 regs *tmp = result->regs[i];
2157 result->regs[i] = result->regs[j];
2158 result->regs[j] = tmp;
2163 /*------------------------------------------------------------------*/
2164 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2165 /* it should either have registers or have beed spilled. Otherwise, */
2166 /* there was an uninitialized variable, so just spill this to get */
2167 /* the operand in a valid state. */
2168 /*------------------------------------------------------------------*/
2170 verifyRegsAssigned (operand *op, iCode * ic)
2175 if (!IS_ITEMP (op)) return;
2177 sym = OP_SYMBOL (op);
2178 if (sym->isspilt) return;
2179 if (!sym->nRegs) return;
2180 if (sym->regs[0]) return;
2182 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2183 sym->prereqv ? sym->prereqv->name : sym->name);
2188 /*-----------------------------------------------------------------*/
2189 /* serialRegAssign - serially allocate registers to the variables */
2190 /*-----------------------------------------------------------------*/
2192 serialRegAssign (eBBlock ** ebbs, int count)
2196 debugLog ("%s\n", __FUNCTION__);
2197 /* for all blocks */
2198 for (i = 0; i < count; i++)
2203 if (ebbs[i]->noPath &&
2204 (ebbs[i]->entryLabel != entryLabel &&
2205 ebbs[i]->entryLabel != returnLabel))
2208 /* of all instructions do */
2209 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2211 debugLog (" op: %s\n", decodeOp (ic->op));
2213 /* if this is an ipop that means some live
2214 range will have to be assigned again */
2216 reassignLR (IC_LEFT (ic));
2218 /* if result is present && is a true symbol */
2219 if (IC_RESULT (ic) && ic->op != IFX &&
2220 IS_TRUE_SYMOP (IC_RESULT (ic)))
2221 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2223 /* take away registers from live
2224 ranges that end at this instruction */
2225 deassignLRs (ic, ebbs[i]);
2227 /* some don't need registers */
2228 if (SKIP_IC2 (ic) ||
2229 ic->op == JUMPTABLE ||
2233 (IC_RESULT (ic) && POINTER_SET (ic)))
2236 /* now we need to allocate registers
2237 only for the result */
2238 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2240 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2246 /* Make sure any spill location is definately allocated */
2247 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2248 !sym->usl.spillLoc->allocreq)
2250 sym->usl.spillLoc->allocreq++;
2253 /* if it does not need or is spilt
2254 or is already assigned to registers
2255 or will not live beyond this instructions */
2258 bitVectBitValue (_G.regAssigned, sym->key) ||
2259 sym->liveTo <= ic->seq)
2262 /* if some liverange has been spilt at the block level
2263 and this one live beyond this block then spil this
2265 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2270 /* if trying to allocate this will cause
2271 a spill and there is nothing to spill
2272 or this one is rematerializable then
2274 willCS = willCauseSpill (sym->nRegs, sym->regType);
2275 spillable = computeSpillable (ic);
2277 (willCS && bitVectIsZero (spillable)))
2285 /* If the live range preceeds the point of definition
2286 then ideally we must take into account registers that
2287 have been allocated after sym->liveFrom but freed
2288 before ic->seq. This is complicated, so spill this
2289 symbol instead and let fillGaps handle the allocation. */
2290 if (sym->liveFrom < ic->seq)
2296 /* if it has a spillocation & is used less than
2297 all other live ranges then spill this */
2299 if (sym->usl.spillLoc) {
2300 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2301 allLRs, ebbs[i], ic));
2302 if (leastUsed && leastUsed->used > sym->used) {
2307 /* if none of the liveRanges have a spillLocation then better
2308 to spill this one than anything else already assigned to registers */
2309 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2310 /* if this is local to this block then we might find a block spil */
2311 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2319 if (ic->op == RECEIVE)
2320 debugLog ("When I get clever, I'll optimize the receive logic\n");
2322 /* if we need ptr regs for the right side
2324 if (POINTER_GET (ic)
2325 && IS_SYMOP(IC_LEFT(ic))
2326 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2327 <= (unsigned) PTRSIZE)
2332 /* else we assign registers to it */
2333 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2335 debugLog (" %d - \n", __LINE__);
2337 bitVectDebugOn(_G.regAssigned, debugF);
2338 for (j = 0; j < sym->nRegs; j++)
2340 if (sym->regType == REG_PTR)
2341 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2343 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2345 /* if the allocation failed which means
2346 this was spilt then break */
2350 debugLog (" %d - \n", __LINE__);
2352 /* if it shares registers with operands make sure
2353 that they are in the same position */
2354 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2355 IS_SYMOP(IC_RESULT(ic)) &&
2356 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2357 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2358 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2359 /* do the same for the right operand */
2360 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2361 IS_SYMOP(IC_RESULT(ic)) &&
2362 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2363 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2364 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2366 debugLog (" %d - \n", __LINE__);
2369 debugLog (" %d - \n", __LINE__);
2378 /* Check for and fix any problems with uninitialized operands */
2379 for (i = 0; i < count; i++)
2383 if (ebbs[i]->noPath &&
2384 (ebbs[i]->entryLabel != entryLabel &&
2385 ebbs[i]->entryLabel != returnLabel))
2388 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2395 verifyRegsAssigned (IC_COND (ic), ic);
2399 if (ic->op == JUMPTABLE)
2401 verifyRegsAssigned (IC_JTCOND (ic), ic);
2405 verifyRegsAssigned (IC_RESULT (ic), ic);
2406 verifyRegsAssigned (IC_LEFT (ic), ic);
2407 verifyRegsAssigned (IC_RIGHT (ic), ic);
2413 /*-----------------------------------------------------------------*/
2414 /* rUmaskForOp :- returns register mask for an operand */
2415 /*-----------------------------------------------------------------*/
2417 rUmaskForOp (operand * op)
2423 debugLog ("%s\n", __FUNCTION__);
2424 /* only temporaries are assigned registers */
2428 sym = OP_SYMBOL (op);
2430 /* if spilt or no registers assigned to it
2432 if (sym->isspilt || !sym->nRegs)
2435 rumask = newBitVect (pic14_nRegs);
2437 for (j = 0; j < sym->nRegs; j++)
2439 rumask = bitVectSetBit (rumask,
2440 sym->regs[j]->rIdx);
2446 /*-----------------------------------------------------------------*/
2447 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2448 /*-----------------------------------------------------------------*/
2450 regsUsedIniCode (iCode * ic)
2452 bitVect *rmask = newBitVect (pic14_nRegs);
2454 debugLog ("%s\n", __FUNCTION__);
2455 /* do the special cases first */
2458 rmask = bitVectUnion (rmask,
2459 rUmaskForOp (IC_COND (ic)));
2463 /* for the jumptable */
2464 if (ic->op == JUMPTABLE)
2466 rmask = bitVectUnion (rmask,
2467 rUmaskForOp (IC_JTCOND (ic)));
2472 /* of all other cases */
2474 rmask = bitVectUnion (rmask,
2475 rUmaskForOp (IC_LEFT (ic)));
2479 rmask = bitVectUnion (rmask,
2480 rUmaskForOp (IC_RIGHT (ic)));
2483 rmask = bitVectUnion (rmask,
2484 rUmaskForOp (IC_RESULT (ic)));
2490 /*-----------------------------------------------------------------*/
2491 /* createRegMask - for each instruction will determine the regsUsed */
2492 /*-----------------------------------------------------------------*/
2494 createRegMask (eBBlock ** ebbs, int count)
2498 debugLog ("%s\n", __FUNCTION__);
2499 /* for all blocks */
2500 for (i = 0; i < count; i++)
2504 if (ebbs[i]->noPath &&
2505 (ebbs[i]->entryLabel != entryLabel &&
2506 ebbs[i]->entryLabel != returnLabel))
2509 /* for all instructions */
2510 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2515 if (SKIP_IC2 (ic) || !ic->rlive)
2518 /* first mark the registers used in this
2520 ic->rUsed = regsUsedIniCode (ic);
2521 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2523 /* now create the register mask for those
2524 registers that are in use : this is a
2525 super set of ic->rUsed */
2526 ic->rMask = newBitVect (pic14_nRegs + 1);
2528 /* for all live Ranges alive at this point */
2529 for (j = 1; j < ic->rlive->size; j++)
2534 /* if not alive then continue */
2535 if (!bitVectBitValue (ic->rlive, j))
2538 /* find the live range we are interested in */
2539 if (!(sym = hTabItemWithKey (liveRanges, j)))
2541 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2542 "createRegMask cannot find live range");
2546 /* if no register assigned to it */
2547 if (!sym->nRegs || sym->isspilt)
2550 /* for all the registers allocated to it */
2551 for (k = 0; k < sym->nRegs; k++)
2554 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2560 /* This was the active version */
2561 /*-----------------------------------------------------------------*/
2562 /* rematStr - returns the rematerialized string for a remat var */
2563 /*-----------------------------------------------------------------*/
2565 rematStr (symbol * sym)
2568 iCode *ic = sym->rematiCode;
2569 symbol *psym = NULL;
2571 debugLog ("%s\n", __FUNCTION__);
2573 //printf ("%s\n", s);
2575 /* if plus or minus print the right hand side */
2577 if (ic->op == '+' || ic->op == '-') {
2579 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2581 sprintf (s, "(%s %c 0x%04x)",
2582 OP_SYMBOL (IC_LEFT (ric))->rname,
2584 (int) operandLitValue (IC_RIGHT (ic)));
2587 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2589 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2590 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2595 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2596 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2598 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2604 /* deprecated version */
2605 /*-----------------------------------------------------------------*/
2606 /* rematStr - returns the rematerialized string for a remat var */
2607 /*-----------------------------------------------------------------*/
2609 rematStr (symbol * sym)
2612 iCode *ic = sym->rematiCode;
2614 debugLog ("%s\n", __FUNCTION__);
2619 /* if plus or minus print the right hand side */
2621 if (ic->op == '+' || ic->op == '-') {
2622 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2625 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2629 if (ic->op == '+' || ic->op == '-')
2631 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2632 sprintf (s, "(%s %c 0x%04x)",
2633 OP_SYMBOL (IC_LEFT (ric))->rname,
2635 (int) operandLitValue (IC_RIGHT (ic)));
2638 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2640 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2644 /* we reached the end */
2645 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2649 printf ("%s\n", buffer);
2654 /*-----------------------------------------------------------------*/
2655 /* regTypeNum - computes the type & number of registers required */
2656 /*-----------------------------------------------------------------*/
2664 debugLog ("%s\n", __FUNCTION__);
2665 /* for each live range do */
2666 for (sym = hTabFirstItem (liveRanges, &k); sym;
2667 sym = hTabNextItem (liveRanges, &k)) {
2669 debugLog (" %d - %s\n", __LINE__, sym->rname);
2671 /* if used zero times then no registers needed */
2672 if ((sym->liveTo - sym->liveFrom) == 0)
2676 /* if the live range is a temporary */
2679 debugLog (" %d - itemp register\n", __LINE__);
2681 /* if the type is marked as a conditional */
2682 if (sym->regType == REG_CND)
2685 /* if used in return only then we don't
2688 if (IS_AGGREGATE (sym->type) || sym->isptr)
2689 sym->type = aggrToPtr (sym->type, FALSE);
2690 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2696 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2697 // sym->type = aggrToPtr (sym->type, FALSE);
2698 debugLog (" %d - used as a return\n", __LINE__);
2703 /* if the symbol has only one definition &
2704 that definition is a get_pointer and the
2705 pointer we are getting is rematerializable and
2709 if (bitVectnBitsOn (sym->defs) == 1 &&
2710 (ic = hTabItemWithKey (iCodehTab,
2711 bitVectFirstBit (sym->defs))) &&
2713 !IS_BITVAR (sym->etype) &&
2714 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2716 if (ptrPseudoSymSafe (sym, ic)) {
2720 debugLog (" %d - \n", __LINE__);
2722 /* create a psuedo symbol & force a spil */
2723 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2724 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2725 psym->type = sym->type;
2726 psym->etype = sym->etype;
2727 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2728 strcpy (psym->rname, psym->name);
2730 sym->usl.spillLoc = psym;
2734 /* if in data space or idata space then try to
2735 allocate pointer register */
2740 /* if not then we require registers */
2741 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2742 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2743 getSize (sym->type));
2746 if(IS_PTR_CONST (sym->type)) {
2747 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2751 if (sym->nRegs > 4) {
2752 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2753 printTypeChain (sym->type, stderr);
2754 fprintf (stderr, "\n");
2757 /* determine the type of register required */
2758 if (sym->nRegs == 1 &&
2759 IS_PTR (sym->type) &&
2761 sym->regType = REG_PTR;
2763 sym->regType = REG_GPR;
2766 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2770 /* for the first run we don't provide */
2771 /* registers for true symbols we will */
2772 /* see how things go */
2777 DEFSETFUNC (markRegFree)
2779 ((regs *)item)->isFree = 1;
2784 DEFSETFUNC (deallocReg)
2786 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2787 ((regs *)item)->isFree = 1;
2788 ((regs *)item)->wasUsed = 0;
2792 /*-----------------------------------------------------------------*/
2793 /* freeAllRegs - mark all registers as free */
2794 /*-----------------------------------------------------------------*/
2796 pic14_freeAllRegs ()
2800 debugLog ("%s\n", __FUNCTION__);
2802 applyToSet(dynAllocRegs,markRegFree);
2803 applyToSet(dynStackRegs,markRegFree);
2806 for (i = 0; i < pic14_nRegs; i++)
2807 regspic14[i].isFree = 1;
2811 /*-----------------------------------------------------------------*/
2812 /*-----------------------------------------------------------------*/
2814 pic14_deallocateAllRegs ()
2818 debugLog ("%s\n", __FUNCTION__);
2820 applyToSet(dynAllocRegs,deallocReg);
2823 for (i = 0; i < pic14_nRegs; i++) {
2824 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2825 regspic14[i].isFree = 1;
2826 regspic14[i].wasUsed = 0;
2833 /*-----------------------------------------------------------------*/
2834 /* deallocStackSpil - this will set the stack pointer back */
2835 /*-----------------------------------------------------------------*/
2837 DEFSETFUNC (deallocStackSpil)
2841 debugLog ("%s\n", __FUNCTION__);
2846 /*-----------------------------------------------------------------*/
2847 /* farSpacePackable - returns the packable icode for far variables */
2848 /*-----------------------------------------------------------------*/
2850 farSpacePackable (iCode * ic)
2854 debugLog ("%s\n", __FUNCTION__);
2855 /* go thru till we find a definition for the
2856 symbol on the right */
2857 for (dic = ic->prev; dic; dic = dic->prev)
2860 /* if the definition is a call then no */
2861 if ((dic->op == CALL || dic->op == PCALL) &&
2862 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2867 /* if shift by unknown amount then not */
2868 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2869 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2872 /* if pointer get and size > 1 */
2873 if (POINTER_GET (dic) &&
2874 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2877 if (POINTER_SET (dic) &&
2878 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2881 /* if any three is a true symbol in far space */
2882 if (IC_RESULT (dic) &&
2883 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2884 isOperandInFarSpace (IC_RESULT (dic)))
2887 if (IC_RIGHT (dic) &&
2888 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2889 isOperandInFarSpace (IC_RIGHT (dic)) &&
2890 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2893 if (IC_LEFT (dic) &&
2894 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2895 isOperandInFarSpace (IC_LEFT (dic)) &&
2896 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2899 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2901 if ((dic->op == LEFT_OP ||
2902 dic->op == RIGHT_OP ||
2904 IS_OP_LITERAL (IC_RIGHT (dic)))
2914 /*-----------------------------------------------------------------*/
2915 /* packRegsForAssign - register reduction for assignment */
2916 /*-----------------------------------------------------------------*/
2918 packRegsForAssign (iCode * ic, eBBlock * ebp)
2923 debugLog ("%s\n", __FUNCTION__);
2925 debugAopGet (" result:", IC_RESULT (ic));
2926 debugAopGet (" left:", IC_LEFT (ic));
2927 debugAopGet (" right:", IC_RIGHT (ic));
2929 /* if this is at an absolute address, then get the address. */
2930 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2931 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2932 debugLog (" %d - found config word declaration\n", __LINE__);
2933 if(IS_VALOP(IC_RIGHT(ic))) {
2934 debugLog (" setting config word to %x\n",
2935 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2936 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2937 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2940 /* remove the assignment from the iCode chain. */
2942 remiCodeFromeBBlock (ebp, ic);
2943 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2944 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2951 if (!IS_ITEMP (IC_RESULT (ic))) {
2952 allocDirReg(IC_RESULT (ic));
2953 debugLog (" %d - result is not temp\n", __LINE__);
2956 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2957 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2958 allocDirReg(IC_LEFT (ic));
2962 if (!IS_ITEMP (IC_RIGHT (ic))) {
2963 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2965 /* only pack if this is not a function pointer */
2966 if (!IS_REF (IC_RIGHT (ic)))
2967 allocDirReg(IC_RIGHT (ic));
2971 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2972 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2974 debugLog (" %d - not packing - right side fails \n", __LINE__);
2978 /* if the true symbol is defined in far space or on stack
2979 then we should not since this will increase register pressure */
2980 if (isOperandInFarSpace (IC_RESULT (ic)))
2982 if ((dic = farSpacePackable (ic)))
2988 /* find the definition of iTempNN scanning backwards if we find a
2989 a use of the true symbol before we find the definition then
2991 for (dic = ic->prev; dic; dic = dic->prev)
2994 /* if there is a function call and this is
2995 a parameter & not my parameter then don't pack it */
2996 if ((dic->op == CALL || dic->op == PCALL) &&
2997 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2998 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3000 debugLog (" %d - \n", __LINE__);
3008 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3009 IS_OP_VOLATILE (IC_RESULT (dic)))
3011 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3016 if (IS_SYMOP (IC_RESULT (dic)) &&
3017 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3019 /* A previous result was assigned to the same register - we'll our definition */
3020 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3021 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3022 if (POINTER_SET (dic))
3028 if (IS_SYMOP (IC_RIGHT (dic)) &&
3029 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3030 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3032 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3037 if (IS_SYMOP (IC_LEFT (dic)) &&
3038 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3039 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3041 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3046 if (POINTER_SET (dic) &&
3047 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3049 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3057 return 0; /* did not find */
3059 /* if the result is on stack or iaccess then it must be
3060 the same at least one of the operands */
3061 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3062 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3065 /* the operation has only one symbol
3066 operator then we can pack */
3067 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3068 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3071 if (!((IC_LEFT (dic) &&
3072 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3074 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3078 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3079 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3080 /* found the definition */
3081 /* replace the result with the result of */
3082 /* this assignment and remove this assignment */
3083 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3084 IC_RESULT (dic) = IC_RESULT (ic);
3086 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3088 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3090 /* delete from liverange table also
3091 delete from all the points inbetween and the new
3093 for (sic = dic; sic != ic; sic = sic->next)
3095 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3096 if (IS_ITEMP (IC_RESULT (dic)))
3097 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3100 remiCodeFromeBBlock (ebp, ic);
3101 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3102 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3103 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3109 /*-----------------------------------------------------------------*/
3110 /* findAssignToSym : scanning backwards looks for first assig found */
3111 /*-----------------------------------------------------------------*/
3113 findAssignToSym (operand * op, iCode * ic)
3117 debugLog ("%s\n", __FUNCTION__);
3118 for (dic = ic->prev; dic; dic = dic->prev)
3121 /* if definition by assignment */
3122 if (dic->op == '=' &&
3123 !POINTER_SET (dic) &&
3124 IC_RESULT (dic)->key == op->key
3125 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3129 /* we are interested only if defined in far space */
3130 /* or in stack space in case of + & - */
3132 /* if assigned to a non-symbol then return
3134 if (!IS_SYMOP (IC_RIGHT (dic)))
3137 /* if the symbol is in far space then
3139 if (isOperandInFarSpace (IC_RIGHT (dic)))
3142 /* for + & - operations make sure that
3143 if it is on the stack it is the same
3144 as one of the three operands */
3145 if ((ic->op == '+' || ic->op == '-') &&
3146 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3149 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3150 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3151 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3159 /* if we find an usage then we cannot delete it */
3160 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3163 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3166 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3170 /* now make sure that the right side of dic
3171 is not defined between ic & dic */
3174 iCode *sic = dic->next;
3176 for (; sic != ic; sic = sic->next)
3177 if (IC_RESULT (sic) &&
3178 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3187 /*-----------------------------------------------------------------*/
3188 /* packRegsForSupport :- reduce some registers for support calls */
3189 /*-----------------------------------------------------------------*/
3191 packRegsForSupport (iCode * ic, eBBlock * ebp)
3195 debugLog ("%s\n", __FUNCTION__);
3196 /* for the left & right operand :- look to see if the
3197 left was assigned a true symbol in far space in that
3198 case replace them */
3199 if (IS_ITEMP (IC_LEFT (ic)) &&
3200 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3202 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3208 debugAopGet ("removing left:", IC_LEFT (ic));
3210 /* found it we need to remove it from the
3212 for (sic = dic; sic != ic; sic = sic->next)
3213 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3215 IC_LEFT (ic)->operand.symOperand =
3216 IC_RIGHT (dic)->operand.symOperand;
3217 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3218 remiCodeFromeBBlock (ebp, dic);
3219 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3220 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3224 /* do the same for the right operand */
3227 IS_ITEMP (IC_RIGHT (ic)) &&
3228 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3230 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3236 /* if this is a subtraction & the result
3237 is a true symbol in far space then don't pack */
3238 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3240 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3241 if (IN_FARSPACE (SPEC_OCLS (etype)))
3245 debugAopGet ("removing right:", IC_RIGHT (ic));
3247 /* found it we need to remove it from the
3249 for (sic = dic; sic != ic; sic = sic->next)
3250 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3252 IC_RIGHT (ic)->operand.symOperand =
3253 IC_RIGHT (dic)->operand.symOperand;
3254 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3256 remiCodeFromeBBlock (ebp, dic);
3257 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3258 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3265 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3268 /*-----------------------------------------------------------------*/
3269 /* packRegsForOneuse : - will reduce some registers for single Use */
3270 /*-----------------------------------------------------------------*/
3272 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3277 debugLog ("%s\n", __FUNCTION__);
3278 /* if returning a literal then do nothing */
3282 /* only upto 2 bytes since we cannot predict
3283 the usage of b, & acc */
3284 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3289 /* this routine will mark the a symbol as used in one
3290 instruction use only && if the definition is local
3291 (ie. within the basic block) && has only one definition &&
3292 that definition is either a return value from a
3293 function or does not contain any variables in
3295 uses = bitVectCopy (OP_USES (op));
3296 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3297 if (!bitVectIsZero (uses)) /* has other uses */
3300 /* if it has only one defintion */
3301 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3302 return NULL; /* has more than one definition */
3304 /* get that definition */
3306 hTabItemWithKey (iCodehTab,
3307 bitVectFirstBit (OP_DEFS (op)))))
3310 /* found the definition now check if it is local */
3311 if (dic->seq < ebp->fSeq ||
3312 dic->seq > ebp->lSeq)
3313 return NULL; /* non-local */
3315 /* now check if it is the return from
3317 if (dic->op == CALL || dic->op == PCALL)
3319 if (ic->op != SEND && ic->op != RETURN &&
3320 !POINTER_SET(ic) && !POINTER_GET(ic))
3322 OP_SYMBOL (op)->ruonly = 1;
3329 /* otherwise check that the definition does
3330 not contain any symbols in far space */
3331 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3332 isOperandInFarSpace (IC_RIGHT (dic)) ||
3333 IS_OP_RUONLY (IC_LEFT (ic)) ||
3334 IS_OP_RUONLY (IC_RIGHT (ic)))
3339 /* if pointer set then make sure the pointer
3341 if (POINTER_SET (dic) &&
3342 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3345 if (POINTER_GET (dic) &&
3346 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3351 /* also make sure the intervenening instructions
3352 don't have any thing in far space */
3353 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3356 /* if there is an intervening function call then no */
3357 if (dic->op == CALL || dic->op == PCALL)
3359 /* if pointer set then make sure the pointer
3361 if (POINTER_SET (dic) &&
3362 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3365 if (POINTER_GET (dic) &&
3366 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3369 /* if address of & the result is remat then okay */
3370 if (dic->op == ADDRESS_OF &&
3371 OP_SYMBOL (IC_RESULT (dic))->remat)
3374 /* if operand has size of three or more & this
3375 operation is a '*','/' or '%' then 'b' may
3377 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3378 getSize (operandType (op)) >= 3)
3381 /* if left or right or result is in far space */
3382 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3383 isOperandInFarSpace (IC_RIGHT (dic)) ||
3384 isOperandInFarSpace (IC_RESULT (dic)) ||
3385 IS_OP_RUONLY (IC_LEFT (dic)) ||
3386 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3387 IS_OP_RUONLY (IC_RESULT (dic)))
3393 OP_SYMBOL (op)->ruonly = 1;
3398 /*-----------------------------------------------------------------*/
3399 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3400 /*-----------------------------------------------------------------*/
3402 isBitwiseOptimizable (iCode * ic)
3404 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3405 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3407 debugLog ("%s\n", __FUNCTION__);
3408 /* bitwise operations are considered optimizable
3409 under the following conditions (Jean-Louis VERN)
3421 if (IS_LITERAL (rtype) ||
3422 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3428 /*-----------------------------------------------------------------*/
3429 /* packRegsForAccUse - pack registers for acc use */
3430 /*-----------------------------------------------------------------*/
3432 packRegsForAccUse (iCode * ic)
3436 debugLog ("%s\n", __FUNCTION__);
3438 /* result too large for WREG? */
3439 if (getSize (operandType (IC_RESULT (ic))) > 1)
3442 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3443 * is never used as an operand to an instruction that
3444 * cannot have WREG as an operand (e.g. BTFSx cannot
3445 * operate on WREG...
3446 * For now, store all results into proper registers. */
3450 /* if this is an aggregate, e.g. a one byte char array */
3451 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3454 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3456 /* if + or - then it has to be one byte result */
3457 if ((ic->op == '+' || ic->op == '-')
3458 && getSize (operandType (IC_RESULT (ic))) > 1)
3461 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3462 /* if shift operation make sure right side is not a literal */
3463 if (ic->op == RIGHT_OP &&
3464 (isOperandLiteral (IC_RIGHT (ic)) ||
3465 getSize (operandType (IC_RESULT (ic))) > 1))
3468 if (ic->op == LEFT_OP &&
3469 (isOperandLiteral (IC_RIGHT (ic)) ||
3470 getSize (operandType (IC_RESULT (ic))) > 1))
3473 if (IS_BITWISE_OP (ic) &&
3474 getSize (operandType (IC_RESULT (ic))) > 1)
3478 /* has only one definition */
3479 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3482 /* has only one use */
3483 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3486 /* and the usage immediately follows this iCode */
3487 if (!(uic = hTabItemWithKey (iCodehTab,
3488 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3491 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3492 if (ic->next != uic)
3495 /* if it is a conditional branch then we definitely can */
3499 if (uic->op == JUMPTABLE)
3502 /* if the usage is not is an assignment
3503 or an arithmetic / bitwise / shift operation then not */
3504 if (POINTER_SET (uic) &&
3505 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3508 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3509 if (uic->op != '=' &&
3510 !IS_ARITHMETIC_OP (uic) &&
3511 !IS_BITWISE_OP (uic) &&
3512 uic->op != LEFT_OP &&
3513 uic->op != RIGHT_OP)
3516 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3517 /* if used in ^ operation then make sure right is not a
3519 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3522 /* if shift operation make sure right side is not a literal */
3523 if (uic->op == RIGHT_OP &&
3524 (isOperandLiteral (IC_RIGHT (uic)) ||
3525 getSize (operandType (IC_RESULT (uic))) > 1))
3528 if (uic->op == LEFT_OP &&
3529 (isOperandLiteral (IC_RIGHT (uic)) ||
3530 getSize (operandType (IC_RESULT (uic))) > 1))
3533 /* make sure that the result of this icode is not on the
3534 stack, since acc is used to compute stack offset */
3535 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3536 OP_SYMBOL (IC_RESULT (uic))->onStack)
3539 /* if either one of them in far space then we cannot */
3540 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3541 isOperandInFarSpace (IC_LEFT (uic))) ||
3542 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3543 isOperandInFarSpace (IC_RIGHT (uic))))
3546 /* if the usage has only one operand then we can */
3547 if (IC_LEFT (uic) == NULL ||
3548 IC_RIGHT (uic) == NULL)
3551 /* make sure this is on the left side if not
3552 a '+' since '+' is commutative */
3553 if (ic->op != '+' &&
3554 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3557 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3558 /* if one of them is a literal then we can */
3559 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3560 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3561 (getSize (operandType (IC_RESULT (uic))) <= 1))
3563 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3567 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3568 /* if the other one is not on stack then we can */
3569 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3570 (IS_ITEMP (IC_RIGHT (uic)) ||
3571 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3572 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3575 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3576 (IS_ITEMP (IC_LEFT (uic)) ||
3577 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3578 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3584 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3585 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3589 /*-----------------------------------------------------------------*/
3590 /* packForPush - hueristics to reduce iCode for pushing */
3591 /*-----------------------------------------------------------------*/
3593 packForReceive (iCode * ic, eBBlock * ebp)
3597 debugLog ("%s\n", __FUNCTION__);
3598 debugAopGet (" result:", IC_RESULT (ic));
3599 debugAopGet (" left:", IC_LEFT (ic));
3600 debugAopGet (" right:", IC_RIGHT (ic));
3605 for (dic = ic->next; dic; dic = dic->next)
3610 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3611 debugLog (" used on left\n");
3612 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3613 debugLog (" used on right\n");
3614 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3615 debugLog (" used on result\n");
3617 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3618 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3623 debugLog (" hey we can remove this unnecessary assign\n");
3625 /*-----------------------------------------------------------------*/
3626 /* packForPush - hueristics to reduce iCode for pushing */
3627 /*-----------------------------------------------------------------*/
3629 packForPush (iCode * ic, eBBlock * ebp)
3633 debugLog ("%s\n", __FUNCTION__);
3634 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3637 /* must have only definition & one usage */
3638 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3639 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3642 /* find the definition */
3643 if (!(dic = hTabItemWithKey (iCodehTab,
3644 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3647 if (dic->op != '=' || POINTER_SET (dic))
3650 /* we now we know that it has one & only one def & use
3651 and the that the definition is an assignment */
3652 IC_LEFT (ic) = IC_RIGHT (dic);
3654 remiCodeFromeBBlock (ebp, dic);
3655 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3656 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3659 void printSymType(char * str, sym_link *sl)
3661 debugLog (" %s Symbol type: ",str);
3662 printTypeChain( sl, debugF);
3667 /*-----------------------------------------------------------------*/
3668 /* some debug code to print the symbol S_TYPE. Note that
3669 * the function checkSClass in src/SDCCsymt.c dinks with
3670 * the S_TYPE in ways the PIC port doesn't fully like...*/
3671 /*-----------------------------------------------------------------*/
3672 void isData(sym_link *sl)
3682 for ( ; sl; sl=sl->next) {
3684 switch (SPEC_SCLS(sl)) {
3686 case S_DATA: fprintf (of, "data "); break;
3687 case S_XDATA: fprintf (of, "xdata "); break;
3688 case S_SFR: fprintf (of, "sfr "); break;
3689 case S_SBIT: fprintf (of, "sbit "); break;
3690 case S_CODE: fprintf (of, "code "); break;
3691 case S_IDATA: fprintf (of, "idata "); break;
3692 case S_PDATA: fprintf (of, "pdata "); break;
3693 case S_LITERAL: fprintf (of, "literal "); break;
3694 case S_STACK: fprintf (of, "stack "); break;
3695 case S_XSTACK: fprintf (of, "xstack "); break;
3696 case S_BIT: fprintf (of, "bit "); break;
3697 case S_EEPROM: fprintf (of, "eeprom "); break;
3707 /*-----------------------------------------------------------------*/
3708 /* packRegisters - does some transformations to reduce register */
3710 /*-----------------------------------------------------------------*/
3712 packRegisters (eBBlock * ebp)
3717 debugLog ("%s\n", __FUNCTION__);
3723 /* look for assignments of the form */
3724 /* iTempNN = TRueSym (someoperation) SomeOperand */
3726 /* TrueSym := iTempNN:1 */
3727 for (ic = ebp->sch; ic; ic = ic->next)
3730 /* find assignment of the form TrueSym := iTempNN:1 */
3731 if (ic->op == '=' && !POINTER_SET (ic))
3732 change += packRegsForAssign (ic, ebp);
3736 if (POINTER_SET (ic))
3737 debugLog ("pointer is set\n");
3738 debugAopGet (" result:", IC_RESULT (ic));
3739 debugAopGet (" left:", IC_LEFT (ic));
3740 debugAopGet (" right:", IC_RIGHT (ic));
3749 for (ic = ebp->sch; ic; ic = ic->next) {
3751 if(IS_SYMOP ( IC_LEFT(ic))) {
3752 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3754 debugAopGet (" left:", IC_LEFT (ic));
3755 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3756 debugLog (" is a pointer\n");
3758 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3759 debugLog (" is volatile\n");
3763 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3766 if(IS_SYMOP ( IC_RIGHT(ic))) {
3767 debugAopGet (" right:", IC_RIGHT (ic));
3768 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3771 if(IS_SYMOP ( IC_RESULT(ic))) {
3772 debugAopGet (" result:", IC_RESULT (ic));
3773 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3776 if (POINTER_SET (ic))
3777 debugLog (" %d - Pointer set\n", __LINE__);
3780 /* Look for two subsequent iCodes with */
3782 /* _c = iTemp & op; */
3783 /* and replace them by */
3786 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3788 ic->prev->op == '=' &&
3789 IS_ITEMP (IC_LEFT (ic)) &&
3790 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3791 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3793 iCode* ic_prev = ic->prev;
3794 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3796 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3797 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3799 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3800 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3801 prev_result_sym->liveTo == ic->seq)
3803 prev_result_sym->liveTo = ic_prev->seq;
3806 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3808 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3810 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3812 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3813 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3814 remiCodeFromeBBlock (ebp, ic_prev);
3815 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3819 /* if this is an itemp & result of a address of a true sym
3820 then mark this as rematerialisable */
3821 if (ic->op == ADDRESS_OF &&
3822 IS_ITEMP (IC_RESULT (ic)) &&
3823 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3824 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3825 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3828 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3830 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3831 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3832 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3836 /* if straight assignment then carry remat flag if
3837 this is the only definition */
3838 if (ic->op == '=' &&
3839 !POINTER_SET (ic) &&
3840 IS_SYMOP (IC_RIGHT (ic)) &&
3841 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3842 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3844 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3846 OP_SYMBOL (IC_RESULT (ic))->remat =
3847 OP_SYMBOL (IC_RIGHT (ic))->remat;
3848 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3849 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3852 /* if this is a +/- operation with a rematerizable
3853 then mark this as rematerializable as well */
3854 if ((ic->op == '+' || ic->op == '-') &&
3855 (IS_SYMOP (IC_LEFT (ic)) &&
3856 IS_ITEMP (IC_RESULT (ic)) &&
3857 OP_SYMBOL (IC_LEFT (ic))->remat &&
3858 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3859 IS_OP_LITERAL (IC_RIGHT (ic))))
3861 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3863 operandLitValue (IC_RIGHT (ic));
3864 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3865 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3866 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3869 /* mark the pointer usages */
3870 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3872 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3873 debugLog (" marking as a pointer (set) =>");
3874 debugAopGet (" result:", IC_RESULT (ic));
3876 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3878 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3879 debugLog (" marking as a pointer (get) =>");
3880 debugAopGet (" left:", IC_LEFT (ic));
3885 /* if we are using a symbol on the stack
3886 then we should say pic14_ptrRegReq */
3887 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3888 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3889 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3890 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3891 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3892 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3895 if (IS_SYMOP (IC_LEFT (ic)))
3896 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3897 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3898 if (IS_SYMOP (IC_RIGHT (ic)))
3899 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3900 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3901 if (IS_SYMOP (IC_RESULT (ic)))
3902 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3903 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3906 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3910 /* if the condition of an if instruction
3911 is defined in the previous instruction then
3912 mark the itemp as a conditional */
3913 if ((IS_CONDITIONAL (ic) ||
3914 ((ic->op == BITWISEAND ||
3917 isBitwiseOptimizable (ic))) &&
3918 ic->next && ic->next->op == IFX &&
3919 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3920 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3923 debugLog (" %d\n", __LINE__);
3924 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3928 /* reduce for support function calls */
3929 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3930 packRegsForSupport (ic, ebp);
3932 /* if a parameter is passed, it's in W, so we may not
3933 need to place a copy in a register */
3934 if (ic->op == RECEIVE)
3935 packForReceive (ic, ebp);
3937 /* some cases the redundant moves can
3938 can be eliminated for return statements */
3939 if ((ic->op == RETURN || ic->op == SEND) &&
3940 !isOperandInFarSpace (IC_LEFT (ic)) &&
3942 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3944 /* if pointer set & left has a size more than
3945 one and right is not in far space */
3946 if (POINTER_SET (ic) &&
3947 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3948 IS_SYMOP(IC_RESULT(ic)) &&
3949 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3950 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3951 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3953 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3955 /* if pointer get */
3956 if (POINTER_GET (ic) &&
3957 !isOperandInFarSpace (IC_RESULT (ic)) &&
3958 IS_SYMOP(IC_LEFT(ic)) &&
3959 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3960 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3961 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3963 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3966 /* if this is cast for intergral promotion then
3967 check if only use of the definition of the
3968 operand being casted/ if yes then replace
3969 the result of that arithmetic operation with
3970 this result and get rid of the cast */
3971 if (ic->op == CAST) {
3973 sym_link *fromType = operandType (IC_RIGHT (ic));
3974 sym_link *toType = operandType (IC_LEFT (ic));
3976 debugLog (" %d - casting\n", __LINE__);
3978 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3979 getSize (fromType) != getSize (toType)) {
3982 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3985 if (IS_ARITHMETIC_OP (dic)) {
3987 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3988 IC_RESULT (dic) = IC_RESULT (ic);
3989 remiCodeFromeBBlock (ebp, ic);
3990 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3991 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3992 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3996 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4000 /* if the type from and type to are the same
4001 then if this is the only use then packit */
4002 if (compareType (operandType (IC_RIGHT (ic)),
4003 operandType (IC_LEFT (ic))) == 1) {
4005 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4008 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4009 IC_RESULT (dic) = IC_RESULT (ic);
4010 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4011 remiCodeFromeBBlock (ebp, ic);
4012 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4013 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4021 iTempNN := (some variable in farspace) V1
4026 if (ic->op == IPUSH)
4028 packForPush (ic, ebp);
4032 /* pack registers for accumulator use, when the
4033 result of an arithmetic or bit wise operation
4034 has only one use, that use is immediately following
4035 the defintion and the using iCode has only one
4036 operand or has two operands but one is literal &
4037 the result of that operation is not on stack then
4038 we can leave the result of this operation in acc:b
4040 if ((IS_ARITHMETIC_OP (ic)
4042 || IS_BITWISE_OP (ic)
4044 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4047 IS_ITEMP (IC_RESULT (ic)) &&
4048 getSize (operandType (IC_RESULT (ic))) <= 2)
4050 packRegsForAccUse (ic);
4056 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4060 if (!debug || !debugF)
4063 for (i = 0; i < count; i++)
4065 fprintf (debugF, "\n----------------------------------------------------------------\n");
4066 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4067 ebbs[i]->entryLabel->name,
4070 ebbs[i]->isLastInLoop);
4071 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4076 fprintf (debugF, "visited %d : hasFcall = %d\n",
4080 fprintf (debugF, "\ndefines bitVector :");
4081 bitVectDebugOn (ebbs[i]->defSet, debugF);
4082 fprintf (debugF, "\nlocal defines bitVector :");
4083 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4084 fprintf (debugF, "\npointers Set bitvector :");
4085 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4086 fprintf (debugF, "\nin pointers Set bitvector :");
4087 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4088 fprintf (debugF, "\ninDefs Set bitvector :");
4089 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4090 fprintf (debugF, "\noutDefs Set bitvector :");
4091 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4092 fprintf (debugF, "\nusesDefs Set bitvector :");
4093 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4094 fprintf (debugF, "\n----------------------------------------------------------------\n");
4095 printiCChain (ebbs[i]->sch, debugF);
4098 /*-----------------------------------------------------------------*/
4099 /* assignRegisters - assigns registers to each live range as need */
4100 /*-----------------------------------------------------------------*/
4102 pic14_assignRegisters (ebbIndex * ebbi)
4104 eBBlock ** ebbs = ebbi->bbOrder;
4105 int count = ebbi->count;
4109 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4110 debugLog ("\nebbs before optimizing:\n");
4111 dumpEbbsToDebug (ebbs, count);
4113 setToNull ((void *) &_G.funcrUsed);
4114 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4117 /* change assignments this will remove some
4118 live ranges reducing some register pressure */
4119 for (i = 0; i < count; i++)
4120 packRegisters (ebbs[i]);
4127 debugLog("dir registers allocated so far:\n");
4128 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4131 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4132 reg = hTabNextItem(dynDirectRegNames, &hkey);
4137 if (options.dump_pack)
4138 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4140 /* first determine for each live range the number of
4141 registers & the type of registers required for each */
4144 /* and serially allocate registers */
4145 serialRegAssign (ebbs, count);
4147 /* if stack was extended then tell the user */
4150 /* werror(W_TOOMANY_SPILS,"stack", */
4151 /* _G.stackExtend,currFunc->name,""); */
4157 /* werror(W_TOOMANY_SPILS,"data space", */
4158 /* _G.dataExtend,currFunc->name,""); */
4162 /* after that create the register mask
4163 for each of the instruction */
4164 createRegMask (ebbs, count);
4166 /* redo that offsets for stacked automatic variables */
4167 redoStackOffsets ();
4169 if (options.dump_rassgn)
4170 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4172 /* now get back the chain */
4173 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4175 debugLog ("ebbs after optimizing:\n");
4176 dumpEbbsToDebug (ebbs, count);
4181 /* free up any _G.stackSpil locations allocated */
4182 applyToSet (_G.stackSpil, deallocStackSpil);
4184 setToNull ((void *) &_G.stackSpil);
4185 setToNull ((void *) &_G.spiltSet);
4186 /* mark all registers as free */
4187 //pic14_freeAllRegs ();
4189 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");