1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
41 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
43 void _debugf(char *f, int l, char *frm, ...);
45 #define NEWREG_DEBUG 0
49 /*-----------------------------------------------------------------*/
50 /* At this point we start getting processor specific although */
51 /* some routines are non-processor specific & can be reused when */
52 /* targetting other processors. The decision for this will have */
53 /* to be made on a routine by routine basis */
54 /* routines used to pack registers are most definitely not reusable */
55 /* since the pack the registers depending strictly on the MCU */
56 /*-----------------------------------------------------------------*/
58 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
59 extern void genpic16Code (iCode *);
69 bitVect *funcrUsed; /* registers used in a function */
75 /* Shared with gen.c */
76 int pic16_ptrRegReq; /* one byte pointer register required */
79 set *pic16_dynAllocRegs=NULL;
80 set *pic16_dynStackRegs=NULL;
81 set *pic16_dynProcessorRegs=NULL;
82 set *pic16_dynDirectRegs=NULL;
83 set *pic16_dynDirectBitRegs=NULL;
84 set *pic16_dynInternalRegs=NULL;
85 set *pic16_dynAccessRegs=NULL;
87 static hTab *dynDirectRegNames=NULL;
88 static hTab *dynAllocRegNames=NULL;
89 static hTab *dynProcRegNames=NULL;
90 static hTab *dynAccessRegNames=NULL;
91 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
93 extern set *sectNames;
95 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
96 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
97 set *pic16_equ_data=NULL; /* registers used by equates */
98 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
99 set *pic16_acs_udata=NULL; /* access bank variables */
101 set *pic16_builtin_functions=NULL;
103 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
104 static int rDirectIdx=0;
106 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
108 int pic16_Gstack_base_addr=0; /* The starting address of registers that
109 * are used to pass and return parameters */
112 int _inRegAllocator=0; /* flag that marks whther allocReg happens while
113 * inside the register allocator function */
116 static void spillThis (symbol *);
117 int pic16_ralloc_debug = 0;
118 static FILE *debugF = NULL;
119 /*-----------------------------------------------------------------*/
120 /* debugLog - open a file for debugging information */
121 /*-----------------------------------------------------------------*/
122 //static void debugLog(char *inst,char *fmt, ...)
124 debugLog (char *fmt,...)
126 static int append = 0; // First time through, open the file without append.
129 //char *bufferP=buffer;
132 if (!pic16_ralloc_debug || !dstFileName)
138 /* create the file name */
139 strcpy (buffer, dstFileName);
140 strcat (buffer, ".d");
142 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
144 werror (E_FILE_OPEN_ERR, buffer);
147 append = 1; // Next time debubLog is called, we'll append the debug info
153 vsprintf (buffer, fmt, ap);
155 fprintf (debugF, "%s", buffer);
156 //fprintf (stderr, "%s", buffer);
158 while (isspace((unsigned char)*bufferP)) bufferP++;
160 if (bufferP && *bufferP)
161 lineCurr = (lineCurr ?
162 connectLine(lineCurr,newLineNode(lb)) :
163 (lineHead = newLineNode(lb)));
164 lineCurr->isInline = _G.inLine;
165 lineCurr->isDebug = _G.debugLine;
174 if(!pic16_ralloc_debug)return;
177 fputc ('\n', debugF);
179 /*-----------------------------------------------------------------*/
180 /* debugLogClose - closes the debug log file (if opened) */
181 /*-----------------------------------------------------------------*/
191 #define AOP(op) op->aop
194 debugAopGet (char *str, operand * op)
196 if(!pic16_ralloc_debug)return NULL;
201 printOperand (op, debugF);
208 pic16_decodeOp (unsigned int op)
210 if (op < 128 && op > ' ') {
211 buffer[0] = (op & 0xff);
217 case IDENTIFIER: return "IDENTIFIER";
218 case TYPE_NAME: return "TYPE_NAME";
219 case CONSTANT: return "CONSTANT";
220 case STRING_LITERAL: return "STRING_LITERAL";
221 case SIZEOF: return "SIZEOF";
222 case PTR_OP: return "PTR_OP";
223 case INC_OP: return "INC_OP";
224 case DEC_OP: return "DEC_OP";
225 case LEFT_OP: return "LEFT_OP";
226 case RIGHT_OP: return "RIGHT_OP";
227 case LE_OP: return "LE_OP";
228 case GE_OP: return "GE_OP";
229 case EQ_OP: return "EQ_OP";
230 case NE_OP: return "NE_OP";
231 case AND_OP: return "AND_OP";
232 case OR_OP: return "OR_OP";
233 case MUL_ASSIGN: return "MUL_ASSIGN";
234 case DIV_ASSIGN: return "DIV_ASSIGN";
235 case MOD_ASSIGN: return "MOD_ASSIGN";
236 case ADD_ASSIGN: return "ADD_ASSIGN";
237 case SUB_ASSIGN: return "SUB_ASSIGN";
238 case LEFT_ASSIGN: return "LEFT_ASSIGN";
239 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
240 case AND_ASSIGN: return "AND_ASSIGN";
241 case XOR_ASSIGN: return "XOR_ASSIGN";
242 case OR_ASSIGN: return "OR_ASSIGN";
243 case TYPEDEF: return "TYPEDEF";
244 case EXTERN: return "EXTERN";
245 case STATIC: return "STATIC";
246 case AUTO: return "AUTO";
247 case REGISTER: return "REGISTER";
248 case CODE: return "CODE";
249 case EEPROM: return "EEPROM";
250 case INTERRUPT: return "INTERRUPT";
251 case SFR: return "SFR";
252 case AT: return "AT";
253 case SBIT: return "SBIT";
254 case REENTRANT: return "REENTRANT";
255 case USING: return "USING";
256 case XDATA: return "XDATA";
257 case DATA: return "DATA";
258 case IDATA: return "IDATA";
259 case PDATA: return "PDATA";
260 case VAR_ARGS: return "VAR_ARGS";
261 case CRITICAL: return "CRITICAL";
262 case NONBANKED: return "NONBANKED";
263 case BANKED: return "BANKED";
264 case CHAR: return "CHAR";
265 case SHORT: return "SHORT";
266 case INT: return "INT";
267 case LONG: return "LONG";
268 case SIGNED: return "SIGNED";
269 case UNSIGNED: return "UNSIGNED";
270 case FLOAT: return "FLOAT";
271 case DOUBLE: return "DOUBLE";
272 case CONST: return "CONST";
273 case VOLATILE: return "VOLATILE";
274 case VOID: return "VOID";
275 case BIT: return "BIT";
276 case STRUCT: return "STRUCT";
277 case UNION: return "UNION";
278 case ENUM: return "ENUM";
279 case ELIPSIS: return "ELIPSIS";
280 case RANGE: return "RANGE";
281 case FAR: return "FAR";
282 case CASE: return "CASE";
283 case DEFAULT: return "DEFAULT";
284 case IF: return "IF";
285 case ELSE: return "ELSE";
286 case SWITCH: return "SWITCH";
287 case WHILE: return "WHILE";
288 case DO: return "DO";
289 case FOR: return "FOR";
290 case GOTO: return "GOTO";
291 case CONTINUE: return "CONTINUE";
292 case BREAK: return "BREAK";
293 case RETURN: return "RETURN";
294 case INLINEASM: return "INLINEASM";
295 case IFX: return "IFX";
296 case ADDRESS_OF: return "ADDRESS_OF";
297 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
298 case SPIL: return "SPIL";
299 case UNSPIL: return "UNSPIL";
300 case GETHBIT: return "GETHBIT";
301 case BITWISEAND: return "BITWISEAND";
302 case UNARYMINUS: return "UNARYMINUS";
303 case IPUSH: return "IPUSH";
304 case IPOP: return "IPOP";
305 case PCALL: return "PCALL";
306 case FUNCTION: return "FUNCTION";
307 case ENDFUNCTION: return "ENDFUNCTION";
308 case JUMPTABLE: return "JUMPTABLE";
309 case RRC: return "RRC";
310 case RLC: return "RLC";
311 case CAST: return "CAST";
312 case CALL: return "CALL";
313 case PARAM: return "PARAM ";
314 case NULLOP: return "NULLOP";
315 case BLOCK: return "BLOCK";
316 case LABEL: return "LABEL";
317 case RECEIVE: return "RECEIVE";
318 case SEND: return "SEND";
319 case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
321 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
327 static char *decodeRegType(short type)
330 case REG_GPR: return "REG_GPR";
331 case REG_PTR: return "REG_PTR";
332 case REG_CND: return "REG_CNT";
340 /*-----------------------------------------------------------------*/
341 /*-----------------------------------------------------------------*/
343 debugLogRegType (short type)
345 if(!pic16_ralloc_debug)return NULL;
347 case REG_GPR: return "REG_GPR";
348 case REG_PTR: return "REG_PTR";
349 case REG_CND: return "REG_CND";
351 sprintf (buffer, "unknown reg type %d", type);
356 /*-----------------------------------------------------------------*/
357 /*-----------------------------------------------------------------*/
358 static int regname2key(char const *name)
367 key += (*name++) + 1;
371 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
375 /*-----------------------------------------------------------------*/
376 /* newReg - allocate and init memory for a new register */
377 /*-----------------------------------------------------------------*/
378 regs* newReg(int type, short pc_type, int rIdx, char *name, unsigned size, int alias, operand *refop)
383 dReg = Safe_calloc(1,sizeof(regs));
385 dReg->pc_type = pc_type;
388 dReg->name = Safe_strdup(name);
390 if(xinst && pc_type == PO_GPR_TEMP) {
391 sprintf(buffer,"0x%02x", dReg->rIdx);
393 sprintf(buffer,"r0x%02x", dReg->rIdx);
396 if(type == REG_STK) {
399 dReg->name = Safe_strdup(buffer);
407 if(type == REG_SFR) {
409 dReg->address = rIdx;
410 dReg->accessBank = 1;
414 dReg->accessBank = 0;
418 fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
422 dReg->reg_alias = NULL;
423 dReg->reglives.usedpFlows = newSet();
424 dReg->reglives.assignedpFlows = newSet();
427 if(!(type == REG_SFR && alias == 0x80))
428 hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
433 /*-----------------------------------------------------------------*/
434 /* regWithIdx - Search through a set of registers that matches idx */
435 /*-----------------------------------------------------------------*/
437 regWithIdx (set *dRegs, int idx, unsigned fixed)
441 //#define D(text) text
444 for (dReg = setFirstItem(dRegs) ; dReg ;
445 dReg = setNextItem(dRegs)) {
447 D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
448 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
449 D(fprintf(stderr, "found!\n"));
452 D(fprintf(stderr, "not found!\n"));
458 /*-----------------------------------------------------------------*/
459 /* regFindFree - Search for a free register in a set of registers */
460 /*-----------------------------------------------------------------*/
462 regFindFree (set *dRegs)
466 for (dReg = setFirstItem(dRegs) ; dReg ;
467 dReg = setNextItem(dRegs)) {
469 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
470 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
473 // fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
483 regFindFreeNext(set *dRegs, regs *creg)
488 /* position at current register */
489 for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
492 for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
501 /*-----------------------------------------------------------------*/
502 /* pic16_initStack - allocate registers for a pseudo stack */
503 /*-----------------------------------------------------------------*/
504 void pic16_initStack(int base_address, int size)
509 pic16_Gstack_base_addr = base_address;
510 //fprintf(stderr,"initStack");
512 for(i = 0; i<size; i++)
513 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
516 /*-----------------------------------------------------------------*
517 *-----------------------------------------------------------------*/
519 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
521 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
523 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
525 reg->wasUsed = 0; // we do not know if they are going to be used at all
526 reg->accessBank = 1; // implicit add access Bank
528 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
530 return addSet(&pic16_dynProcessorRegs, reg);
533 /*-----------------------------------------------------------------*
534 *-----------------------------------------------------------------*/
537 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
539 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
541 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
545 return addSet(&pic16_dynInternalRegs,reg);
552 /*-----------------------------------------------------------------*/
553 /* allocReg - allocates register of given type */
554 /*-----------------------------------------------------------------*/
556 allocReg (short type)
560 #define MAX_P16_NREGS 16
564 if(dynrIdx > pic16_nRegs)
565 werror(W_POSSBUG2, __FILE__, __LINE__);
569 /* try to reuse some unused registers */
570 reg = regFindFree( pic16_dynAllocRegs );
573 // fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
577 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
578 // fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
579 // (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
582 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
583 // debugf("allocating more registers than available\n", 0);
587 addSet(&pic16_dynAllocRegs, reg);
588 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
589 // fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
593 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
596 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
597 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
601 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
602 reg->isLocal = 1; /* this is a local frame register */
607 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
608 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
611 return (reg); // addSet(&pic16_dynAllocRegs,reg);
616 /*-----------------------------------------------------------------*/
617 /* pic16_dirregWithName - search for register by name */
618 /*-----------------------------------------------------------------*/
620 pic16_dirregWithName (char *name)
628 /* hash the name to get a key */
630 hkey = regname2key(name);
632 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
634 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
638 if(STRCASECMP(reg->name, name) == 0) {
639 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
643 reg = hTabNextItemWK (dynDirectRegNames);
647 return NULL; // name wasn't found in the hash table
650 /*-----------------------------------------------------------------*/
651 /* pic16_allocregWithName - search for register by name */
652 /*-----------------------------------------------------------------*/
654 pic16_allocregWithName (char *name)
662 /* hash the name to get a key */
664 hkey = regname2key(name);
666 //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
668 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
672 if(STRCASECMP(reg->name, name) == 0) {
676 reg = hTabNextItemWK (dynAllocRegNames);
680 return NULL; // name wasn't found in the hash table
685 /*-----------------------------------------------------------------*/
686 /* pic16_procregWithName - search for register by name */
687 /*-----------------------------------------------------------------*/
689 pic16_procregWithName (char *name)
697 /* hash the name to get a key */
699 hkey = regname2key(name);
701 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
703 reg = hTabFirstItemWK(dynProcRegNames, hkey);
707 if(STRCASECMP(reg->name, name) == 0) {
711 reg = hTabNextItemWK (dynProcRegNames);
715 return NULL; // name wasn't found in the hash table
719 /*-----------------------------------------------------------------*/
720 /* pic16_accessregWithName - search for register by name */
721 /*-----------------------------------------------------------------*/
723 pic16_accessregWithName (char *name)
731 /* hash the name to get a key */
733 hkey = regname2key(name);
735 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
737 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
741 if(STRCASECMP(reg->name, name) == 0) {
745 reg = hTabNextItemWK (dynAccessRegNames);
749 return NULL; // name wasn't found in the hash table
753 regs *pic16_regWithName(char *name)
757 reg = pic16_dirregWithName( name );
760 reg = pic16_procregWithName( name );
763 reg = pic16_allocregWithName( name );
766 reg = pic16_accessregWithName( name );
773 /*-----------------------------------------------------------------*/
774 /* pic16_allocDirReg - allocates register of given type */
775 /*-----------------------------------------------------------------*/
777 pic16_allocDirReg (operand *op )
783 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
784 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
788 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
791 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
793 if(pic16_debug_verbose)
795 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
796 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
802 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
803 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
806 if(pic16_debug_verbose) {
807 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
808 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
809 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
810 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
811 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
812 IN_STACK( OP_SYM_ETYPE(op)),
813 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
814 IS_REGPARM(OP_SYM_ETYPE(op)),
817 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
818 OP_SYMBOL(op)->name);
826 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
827 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
831 if(IS_ITEMP(op))return NULL;
833 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
835 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
837 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
838 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
841 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
842 debugLog(" %d const char\n",__LINE__);
843 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
844 // fprintf(stderr, " %d const char\n",__LINE__);
845 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
849 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
850 if (IS_CODE ( OP_SYM_ETYPE(op)) )
851 debugLog(" %d code space\n",__LINE__);
853 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
854 debugLog(" %d integral\n",__LINE__);
856 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
857 debugLog(" %d literal\n",__LINE__);
859 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
860 debugLog(" %d specifier\n",__LINE__);
862 debugAopGet(NULL, op);
866 reg = pic16_dirregWithName(name);
870 int regtype = REG_GPR;
872 /* if this is at an absolute address, then get the address. */
873 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
874 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
875 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
878 /* Register wasn't found in hash, so let's create
879 * a new one and put it in the hash table AND in the
880 * dynDirectRegNames set */
881 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
882 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
888 if(OP_SYMBOL(op)->onStack) {
889 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
890 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
894 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
895 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
898 if(pic16_debug_verbose)
900 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
901 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
902 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
903 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
904 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
905 IN_STACK( OP_SYM_ETYPE(op)),
906 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
908 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
909 OP_SYMBOL(op)->name);
914 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
915 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
917 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
918 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
922 checkAddReg(&pic16_dynAccessRegs, reg);
923 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
929 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
930 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
931 // reg->type = REG_SFR;
934 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
935 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
936 addSet(&pic16_dynDirectBitRegs, reg);
939 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
940 // addSet(&pic16_dynDirectRegs, reg);
943 if(!(IS_STATIC(OP_SYM_ETYPE(op))
944 && OP_SYMBOL(op)->ival
947 checkAddReg(&pic16_dynDirectRegs, reg);
951 // debugLog (" -- %s is declared at address 0x30000x\n",name);
952 return (reg); /* This was NULL before, but since we found it
953 * why not just return it?! */
956 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
958 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
960 /* work around for user defined registers in access bank */
961 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
962 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
965 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
971 /*-----------------------------------------------------------------*/
972 /* pic16_allocRegByName - allocates register of given type */
973 /*-----------------------------------------------------------------*/
975 pic16_allocRegByName (char *name, int size, operand *op)
981 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
985 /* First, search the hash table to see if there is a register with this name */
986 reg = pic16_dirregWithName(name);
990 /* Register wasn't found in hash, so let's create
991 * a new one and put it in the hash table AND in the
992 * dynDirectRegNames set */
994 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
996 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
998 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
999 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
1001 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
1002 addSet(&pic16_dynDirectRegs, reg);
1008 /*-----------------------------------------------------------------*/
1009 /* RegWithIdx - returns pointer to register with index number */
1010 /*-----------------------------------------------------------------*/
1011 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
1016 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
1017 // fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
1022 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
1024 debugLog ("Found a Dynamic Register!\n");
1027 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
1028 debugLog ("Found a Direct Register!\n");
1032 if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
1033 debugLog ("Found an Internal Register!\n");
1039 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1040 debugLog ("Found a Stack Register!\n");
1045 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1046 debugLog ("Found a Processor Register!\n");
1060 /*-----------------------------------------------------------------*/
1061 /* pic16_regWithIdx - returns pointer to register with index number*/
1062 /*-----------------------------------------------------------------*/
1064 pic16_regWithIdx (int idx)
1068 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1071 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1075 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1082 /*-----------------------------------------------------------------*/
1083 /* pic16_regWithIdx - returns pointer to register with index number */
1084 /*-----------------------------------------------------------------*/
1086 pic16_allocWithIdx (int idx)
1091 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1092 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1094 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1096 debugLog ("Found a Dynamic Register!\n");
1097 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1098 debugLog ("Found a Stack Register!\n");
1099 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1100 debugLog ("Found a Processor Register!\n");
1101 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1102 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1103 debugLog ("Found an Internal Register!\n");
1106 debugLog ("Dynamic Register not found\n");
1109 dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
1110 addSet(&pic16_dynAllocRegs, dReg);
1111 hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
1116 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1117 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1118 "allocWithIdx not found");
1128 /*-----------------------------------------------------------------*/
1129 /*-----------------------------------------------------------------*/
1131 pic16_findFreeReg(short type)
1138 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1140 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1141 return allocReg( REG_GPR );
1145 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1159 pic16_findFreeRegNext(short type, regs *creg)
1166 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1168 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1169 return (allocReg( REG_GPR ) );
1173 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1185 /*-----------------------------------------------------------------*/
1186 /* freeReg - frees a register */
1187 /*-----------------------------------------------------------------*/
1189 freeReg (regs * reg)
1191 debugLog ("%s\n", __FUNCTION__);
1192 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1197 /*-----------------------------------------------------------------*/
1198 /* nFreeRegs - returns number of free registers */
1199 /*-----------------------------------------------------------------*/
1201 nFreeRegs (int type)
1207 /* although I fixed the register allocation/freeing scheme
1208 * the for loop below doesn't give valid results. I do not
1209 * know why yet. -- VR 10-Jan-2003 */
1214 /* dynamically allocate as many as we need and worry about
1215 * fitting them into a PIC later */
1217 debugLog ("%s\n", __FUNCTION__);
1219 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1220 if((reg->type == type) && reg->isFree)nfr++;
1222 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1226 /*-----------------------------------------------------------------*/
1227 /* nfreeRegsType - free registers with type */
1228 /*-----------------------------------------------------------------*/
1230 nfreeRegsType (int type)
1233 debugLog ("%s\n", __FUNCTION__);
1234 if (type == REG_PTR)
1236 if ((nfr = nFreeRegs (type)) == 0)
1237 return nFreeRegs (REG_GPR);
1240 return nFreeRegs (type);
1243 static void writeSetUsedRegs(FILE *of, set *dRegs)
1248 for (dReg = setFirstItem(dRegs) ; dReg ;
1249 dReg = setNextItem(dRegs)) {
1252 fprintf (of, "\t%s\n",dReg->name);
1258 extern void pic16_groupRegistersInSection(set *regset);
1260 extern void pic16_dump_equates(FILE *of, set *equs);
1261 extern void pic16_dump_access(FILE *of, set *section);
1262 //extern void pic16_dump_map(void);
1263 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1264 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1265 extern void pic16_dump_int_registers(FILE *of, set *section);
1266 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1268 extern void pic16_dump_gsection(FILE *of, set *sections);
1270 static void packBits(set *bregs)
1274 regs *bitfield=NULL;
1275 regs *relocbitfield=NULL;
1281 for (regset = bregs ; regset ;
1282 regset = regset->next) {
1284 breg = regset->item;
1285 breg->isBitField = 1;
1286 //fprintf(stderr,"bit reg: %s\n",breg->name);
1289 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1291 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1292 breg->rIdx = breg->address & 7;
1293 breg->address >>= 3;
1296 sprintf (buffer, "fbitfield%02x", breg->address);
1297 //fprintf(stderr,"new bit field\n");
1298 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1299 bitfield->isBitField = 1;
1300 bitfield->isFixed = 1;
1301 bitfield->address = breg->address;
1302 addSet(&pic16_dynDirectRegs,bitfield);
1303 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1305 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1308 breg->reg_alias = bitfield;
1312 if(!relocbitfield || bit_no >7) {
1315 sprintf (buffer, "bitfield%d", byte_no);
1316 //fprintf(stderr,"new relocatable bit field\n");
1317 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1318 relocbitfield->isBitField = 1;
1319 addSet(&pic16_dynDirectRegs,relocbitfield);
1320 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1324 breg->reg_alias = relocbitfield;
1325 breg->address = rDirectIdx; /* byte_no; */
1326 breg->rIdx = bit_no++;
1332 void pic16_writeUsedRegs(FILE *of)
1334 packBits(pic16_dynDirectBitRegs);
1336 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1337 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1338 pic16_groupRegistersInSection(pic16_dynStackRegs);
1339 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1340 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1341 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1342 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1345 pic16_dump_equates(of, pic16_equ_data);
1347 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1348 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1350 /* dump access bank symbols */
1351 pic16_dump_access(of, pic16_acs_udata);
1353 /* dump initialised data */
1354 pic16_dump_isection(of, rel_idataSymSet, 0);
1355 pic16_dump_isection(of, fix_idataSymSet, 1);
1358 /* dump internal registers */
1359 pic16_dump_int_registers(of, pic16_int_regs);
1362 /* dump generic section variables */
1363 pic16_dump_gsection(of, sectNames);
1365 /* dump other variables */
1366 pic16_dump_usection(of, pic16_rel_udata, 0);
1367 pic16_dump_usection(of, pic16_fix_udata, 1);
1371 /*-----------------------------------------------------------------*/
1372 /* computeSpillable - given a point find the spillable live ranges */
1373 /*-----------------------------------------------------------------*/
1375 computeSpillable (iCode * ic)
1379 debugLog ("%s\n", __FUNCTION__);
1380 /* spillable live ranges are those that are live at this
1381 point . the following categories need to be subtracted
1383 a) - those that are already spilt
1384 b) - if being used by this one
1385 c) - defined by this one */
1387 spillable = bitVectCopy (ic->rlive);
1389 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1391 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1392 bitVectUnSetBit (spillable, ic->defKey);
1393 spillable = bitVectIntersect (spillable, _G.regAssigned);
1398 /*-----------------------------------------------------------------*/
1399 /* noSpilLoc - return true if a variable has no spil location */
1400 /*-----------------------------------------------------------------*/
1402 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1404 debugLog ("%s\n", __FUNCTION__);
1405 return (sym->usl.spillLoc ? 0 : 1);
1408 /*-----------------------------------------------------------------*/
1409 /* hasSpilLoc - will return 1 if the symbol has spil location */
1410 /*-----------------------------------------------------------------*/
1412 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1414 debugLog ("%s\n", __FUNCTION__);
1415 return (sym->usl.spillLoc ? 1 : 0);
1418 /*-----------------------------------------------------------------*/
1419 /* directSpilLoc - will return 1 if the splilocation is in direct */
1420 /*-----------------------------------------------------------------*/
1422 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1424 debugLog ("%s\n", __FUNCTION__);
1425 if (sym->usl.spillLoc &&
1426 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1432 /*-----------------------------------------------------------------*/
1433 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1434 /* but is not used as a pointer */
1435 /*-----------------------------------------------------------------*/
1437 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1439 debugLog ("%s\n", __FUNCTION__);
1440 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1443 /*-----------------------------------------------------------------*/
1444 /* rematable - will return 1 if the remat flag is set */
1445 /*-----------------------------------------------------------------*/
1447 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1449 debugLog ("%s\n", __FUNCTION__);
1453 /*-----------------------------------------------------------------*/
1454 /* notUsedInRemaining - not used or defined in remain of the block */
1455 /*-----------------------------------------------------------------*/
1457 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1459 debugLog ("%s\n", __FUNCTION__);
1460 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1461 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1464 /*-----------------------------------------------------------------*/
1465 /* allLRs - return true for all */
1466 /*-----------------------------------------------------------------*/
1468 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1470 debugLog ("%s\n", __FUNCTION__);
1474 /*-----------------------------------------------------------------*/
1475 /* liveRangesWith - applies function to a given set of live range */
1476 /*-----------------------------------------------------------------*/
1478 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1479 eBBlock * ebp, iCode * ic)
1484 debugLog ("%s\n", __FUNCTION__);
1485 if (!lrs || !lrs->size)
1488 for (i = 1; i < lrs->size; i++)
1491 if (!bitVectBitValue (lrs, i))
1494 /* if we don't find it in the live range
1495 hash table we are in serious trouble */
1496 if (!(sym = hTabItemWithKey (liveRanges, i)))
1498 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1499 "liveRangesWith could not find liveRange");
1503 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1504 addSetHead (&rset, sym);
1511 /*-----------------------------------------------------------------*/
1512 /* leastUsedLR - given a set determines which is the least used */
1513 /*-----------------------------------------------------------------*/
1515 leastUsedLR (set * sset)
1517 symbol *sym = NULL, *lsym = NULL;
1519 debugLog ("%s\n", __FUNCTION__);
1520 sym = lsym = setFirstItem (sset);
1525 for (; lsym; lsym = setNextItem (sset))
1528 /* if usage is the same then prefer
1529 the spill the smaller of the two */
1530 if (lsym->used == sym->used)
1531 if (getSize (lsym->type) < getSize (sym->type))
1535 if (lsym->used < sym->used)
1540 setToNull ((void *) &sset);
1545 /*-----------------------------------------------------------------*/
1546 /* noOverLap - will iterate through the list looking for over lap */
1547 /*-----------------------------------------------------------------*/
1549 noOverLap (set * itmpStack, symbol * fsym)
1552 debugLog ("%s\n", __FUNCTION__);
1555 for (sym = setFirstItem (itmpStack); sym;
1556 sym = setNextItem (itmpStack))
1558 if (sym->liveTo > fsym->liveFrom)
1566 /*-----------------------------------------------------------------*/
1567 /* isFree - will return 1 if the a free spil location is found */
1568 /*-----------------------------------------------------------------*/
1573 V_ARG (symbol **, sloc);
1574 V_ARG (symbol *, fsym);
1576 debugLog ("%s\n", __FUNCTION__);
1577 /* if already found */
1581 /* if it is free && and the itmp assigned to
1582 this does not have any overlapping live ranges
1583 with the one currently being assigned and
1584 the size can be accomodated */
1586 noOverLap (sym->usl.itmpStack, fsym) &&
1587 getSize (sym->type) >= getSize (fsym->type))
1596 /*-----------------------------------------------------------------*/
1597 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1598 /*-----------------------------------------------------------------*/
1600 spillLRWithPtrReg (symbol * forSym)
1606 debugLog ("%s\n", __FUNCTION__);
1607 if (!_G.regAssigned ||
1608 bitVectIsZero (_G.regAssigned))
1611 r0 = pic16_regWithIdx (R0_IDX);
1612 r1 = pic16_regWithIdx (R1_IDX);
1614 /* for all live ranges */
1615 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1616 lrsym = hTabNextItem (liveRanges, &k))
1620 /* if no registers assigned to it or
1622 /* if it does not overlap with this then
1623 not need to spill it */
1625 if (lrsym->isspilt || !lrsym->nRegs ||
1626 (lrsym->liveTo < forSym->liveFrom))
1629 /* go thru the registers : if it is either
1630 r0 or r1 then spil it */
1631 for (j = 0; j < lrsym->nRegs; j++)
1632 if (lrsym->regs[j] == r0 ||
1633 lrsym->regs[j] == r1)
1642 /*-----------------------------------------------------------------*/
1643 /* createStackSpil - create a location on the stack to spil */
1644 /*-----------------------------------------------------------------*/
1646 createStackSpil (symbol * sym)
1648 symbol *sloc = NULL;
1649 int useXstack, model, noOverlay;
1651 char slocBuffer[30];
1652 debugLog ("%s\n", __FUNCTION__);
1654 /* first go try and find a free one that is already
1655 existing on the stack */
1656 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1658 /* found a free one : just update & return */
1659 sym->usl.spillLoc = sloc;
1662 addSetHead (&sloc->usl.itmpStack, sym);
1666 /* could not then have to create one , this is the hard part
1667 we need to allocate this on the stack : this is really a
1668 hack!! but cannot think of anything better at this time */
1670 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1672 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1673 __FILE__, __LINE__);
1677 sloc = newiTemp (slocBuffer);
1679 /* set the type to the spilling symbol */
1680 sloc->type = copyLinkChain (sym->type);
1681 sloc->etype = getSpec (sloc->type);
1682 SPEC_SCLS (sloc->etype) = S_DATA;
1683 SPEC_EXTR (sloc->etype) = 0;
1684 SPEC_STAT (sloc->etype) = 0;
1686 /* we don't allow it to be allocated`
1687 onto the external stack since : so we
1688 temporarily turn it off ; we also
1689 turn off memory model to prevent
1690 the spil from going to the external storage
1691 and turn off overlaying
1694 useXstack = options.useXstack;
1695 model = options.model;
1696 noOverlay = options.noOverlay;
1697 options.noOverlay = 1;
1698 options.model = options.useXstack = 0;
1702 options.useXstack = useXstack;
1703 options.model = model;
1704 options.noOverlay = noOverlay;
1705 sloc->isref = 1; /* to prevent compiler warning */
1707 /* if it is on the stack then update the stack */
1708 if (IN_STACK (sloc->etype))
1710 currFunc->stack += getSize (sloc->type);
1711 _G.stackExtend += getSize (sloc->type);
1714 _G.dataExtend += getSize (sloc->type);
1716 /* add it to the _G.stackSpil set */
1717 addSetHead (&_G.stackSpil, sloc);
1718 sym->usl.spillLoc = sloc;
1721 /* add it to the set of itempStack set
1722 of the spill location */
1723 addSetHead (&sloc->usl.itmpStack, sym);
1727 /*-----------------------------------------------------------------*/
1728 /* isSpiltOnStack - returns true if the spil location is on stack */
1729 /*-----------------------------------------------------------------*/
1731 isSpiltOnStack (symbol * sym)
1735 debugLog ("%s\n", __FUNCTION__);
1742 /* if (sym->_G.stackSpil) */
1745 if (!sym->usl.spillLoc)
1748 etype = getSpec (sym->usl.spillLoc->type);
1749 if (IN_STACK (etype))
1755 /*-----------------------------------------------------------------*/
1756 /* spillThis - spils a specific operand */
1757 /*-----------------------------------------------------------------*/
1759 spillThis (symbol * sym)
1762 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1764 /* if this is rematerializable or has a spillLocation
1765 we are okay, else we need to create a spillLocation
1767 if (!(sym->remat || sym->usl.spillLoc))
1768 createStackSpil (sym);
1771 /* mark it has spilt & put it in the spilt set */
1773 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1775 bitVectUnSetBit (_G.regAssigned, sym->key);
1777 for (i = 0; i < sym->nRegs; i++)
1781 freeReg (sym->regs[i]);
1782 sym->regs[i] = NULL;
1785 /* if spilt on stack then free up r0 & r1
1786 if they could have been assigned to some
1788 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1791 spillLRWithPtrReg (sym);
1794 if (sym->usl.spillLoc && !sym->remat)
1795 sym->usl.spillLoc->allocreq = 1;
1799 /*-----------------------------------------------------------------*/
1800 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1801 /*-----------------------------------------------------------------*/
1803 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1805 bitVect *lrcs = NULL;
1809 debugLog ("%s\n", __FUNCTION__);
1810 /* get the spillable live ranges */
1811 lrcs = computeSpillable (ic);
1813 /* get all live ranges that are rematerizable */
1814 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1817 /* return the least used of these */
1818 return leastUsedLR (selectS);
1821 /* get live ranges with spillLocations in direct space */
1822 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1824 sym = leastUsedLR (selectS);
1825 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1826 sym->usl.spillLoc->rname :
1827 sym->usl.spillLoc->name));
1829 /* mark it as allocation required */
1830 sym->usl.spillLoc->allocreq = 1;
1834 /* if the symbol is local to the block then */
1835 if (forSym->liveTo < ebp->lSeq)
1838 /* check if there are any live ranges allocated
1839 to registers that are not used in this block */
1840 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1842 sym = leastUsedLR (selectS);
1843 /* if this is not rematerializable */
1852 /* check if there are any live ranges that not
1853 used in the remainder of the block */
1854 if (!_G.blockSpil &&
1855 !isiCodeInFunctionCall (ic) &&
1856 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1858 sym = leastUsedLR (selectS);
1861 sym->remainSpil = 1;
1868 /* find live ranges with spillocation && not used as pointers */
1869 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1872 sym = leastUsedLR (selectS);
1873 /* mark this as allocation required */
1874 sym->usl.spillLoc->allocreq = 1;
1878 /* find live ranges with spillocation */
1879 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1882 sym = leastUsedLR (selectS);
1883 sym->usl.spillLoc->allocreq = 1;
1887 /* couldn't find then we need to create a spil
1888 location on the stack , for which one? the least
1890 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1893 /* return a created spil location */
1894 sym = createStackSpil (leastUsedLR (selectS));
1895 sym->usl.spillLoc->allocreq = 1;
1899 /* this is an extreme situation we will spill
1900 this one : happens very rarely but it does happen */
1906 /*-----------------------------------------------------------------*/
1907 /* spilSomething - spil some variable & mark registers as free */
1908 /*-----------------------------------------------------------------*/
1910 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1915 debugLog ("%s\n", __FUNCTION__);
1916 /* get something we can spil */
1917 ssym = selectSpil (ic, ebp, forSym);
1919 /* mark it as spilt */
1921 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1923 /* mark it as not register assigned &
1924 take it away from the set */
1925 bitVectUnSetBit (_G.regAssigned, ssym->key);
1927 /* mark the registers as free */
1928 for (i = 0; i < ssym->nRegs; i++)
1930 freeReg (ssym->regs[i]);
1932 /* if spilt on stack then free up r0 & r1
1933 if they could have been assigned to as gprs */
1934 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1937 spillLRWithPtrReg (ssym);
1940 /* if this was a block level spil then insert push & pop
1941 at the start & end of block respectively */
1942 if (ssym->blockSpil)
1944 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1945 /* add push to the start of the block */
1946 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1947 ebp->sch->next : ebp->sch));
1948 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1949 /* add pop to the end of the block */
1950 addiCodeToeBBlock (ebp, nic, NULL);
1953 /* if spilt because not used in the remainder of the
1954 block then add a push before this instruction and
1955 a pop at the end of the block */
1956 if (ssym->remainSpil)
1959 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1960 /* add push just before this instruction */
1961 addiCodeToeBBlock (ebp, nic, ic);
1963 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1964 /* add pop to the end of the block */
1965 addiCodeToeBBlock (ebp, nic, NULL);
1974 /*-----------------------------------------------------------------*/
1975 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1976 /*-----------------------------------------------------------------*/
1978 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1983 debugLog ("%s\n", __FUNCTION__);
1985 /* try for a ptr type */
1986 if ((reg = allocReg (REG_PTR)))
1989 /* try for gpr type */
1990 if ((reg = allocReg (REG_GPR)))
1993 /* we have to spil */
1994 if (!spilSomething (ic, ebp, sym))
1997 /* make sure partially assigned registers aren't reused */
1998 for (j=0; j<=sym->nRegs; j++)
2000 sym->regs[j]->isFree = 0;
2002 /* this looks like an infinite loop but
2003 in really selectSpil will abort */
2007 /*-----------------------------------------------------------------*/
2008 /* getRegGpr - will try for GPR if not spil */
2009 /*-----------------------------------------------------------------*/
2011 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
2016 debugLog ("%s\n", __FUNCTION__);
2018 /* try for gpr type */
2019 if ((reg = allocReg (REG_GPR)))
2022 if (!pic16_ptrRegReq)
2023 if ((reg = allocReg (REG_PTR)))
2026 /* we have to spil */
2027 if (!spilSomething (ic, ebp, sym))
2030 /* make sure partially assigned registers aren't reused */
2031 for (j=0; j<=sym->nRegs; j++)
2033 sym->regs[j]->isFree = 0;
2035 /* this looks like an infinite loop but
2036 in really selectSpil will abort */
2040 /*-----------------------------------------------------------------*/
2041 /* symHasReg - symbol has a given register */
2042 /*-----------------------------------------------------------------*/
2044 symHasReg (symbol * sym, regs * reg)
2048 debugLog ("%s\n", __FUNCTION__);
2049 for (i = 0; i < sym->nRegs; i++)
2050 if (sym->regs[i] == reg)
2056 /*-----------------------------------------------------------------*/
2057 /* deassignLRs - check the live to and if they have registers & are */
2058 /* not spilt then free up the registers */
2059 /*-----------------------------------------------------------------*/
2061 deassignLRs (iCode * ic, eBBlock * ebp)
2067 debugLog ("%s\n", __FUNCTION__);
2068 for (sym = hTabFirstItem (liveRanges, &k); sym;
2069 sym = hTabNextItem (liveRanges, &k))
2072 symbol *psym = NULL;
2073 /* if it does not end here */
2074 if (sym->liveTo > ic->seq)
2077 /* if it was spilt on stack then we can
2078 mark the stack spil location as free */
2083 sym->usl.spillLoc->isFree = 1;
2089 if (!bitVectBitValue (_G.regAssigned, sym->key))
2092 /* special case for shifting: there is a case where shift count
2093 * can be allocated in the same register as the result, so do not
2094 * free right registers if same as result registers, cause genShiftLeft
2095 * will fail -- VR */
2096 if(ic->op == LEFT_OP)
2099 /* special case check if this is an IFX &
2100 the privious one was a pop and the
2101 previous one was not spilt then keep track
2103 if (ic->op == IFX && ic->prev &&
2104 ic->prev->op == IPOP &&
2105 !ic->prev->parmPush &&
2106 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2107 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2113 bitVectUnSetBit (_G.regAssigned, sym->key);
2115 /* if the result of this one needs registers
2116 and does not have it then assign it right
2118 if (IC_RESULT (ic) &&
2119 !(SKIP_IC2 (ic) || /* not a special icode */
2120 ic->op == JUMPTABLE ||
2125 POINTER_SET (ic)) &&
2126 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2127 result->liveTo > ic->seq && /* and will live beyond this */
2128 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2129 result->liveFrom == ic->seq && /* does not start before here */
2130 result->regType == sym->regType && /* same register types */
2131 result->nRegs && /* which needs registers */
2132 !result->isspilt && /* and does not already have them */
2134 !bitVectBitValue (_G.regAssigned, result->key) &&
2135 /* the number of free regs + number of regs in this LR
2136 can accomodate the what result Needs */
2137 ((nfreeRegsType (result->regType) +
2138 sym->nRegs) >= result->nRegs)
2143 // for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2144 /* the above does not free the unsued registers in sym,
2145 * leaving them marked as used, and increasing register usage
2146 * until the end of the function - VR 23/11/05 */
2148 for (i = 0; i < result->nRegs; i++)
2150 result->regs[i] = sym->regs[i];
2152 result->regs[i] = getRegGpr (ic, ebp, result);
2154 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2157 /* free the remaining */
2158 for (; i < sym->nRegs; i++)
2162 if (!symHasReg (psym, sym->regs[i]))
2163 freeReg (sym->regs[i]);
2166 freeReg (sym->regs[i]);
2173 /*-----------------------------------------------------------------*/
2174 /* reassignLR - reassign this to registers */
2175 /*-----------------------------------------------------------------*/
2177 reassignLR (operand * op)
2179 symbol *sym = OP_SYMBOL (op);
2182 debugLog ("%s\n", __FUNCTION__);
2183 /* not spilt any more */
2184 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2185 bitVectUnSetBit (_G.spiltSet, sym->key);
2187 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2191 for (i = 0; i < sym->nRegs; i++)
2192 sym->regs[i]->isFree = 0;
2195 /*-----------------------------------------------------------------*/
2196 /* willCauseSpill - determines if allocating will cause a spill */
2197 /*-----------------------------------------------------------------*/
2199 willCauseSpill (int nr, int rt)
2201 debugLog ("%s\n", __FUNCTION__);
2202 /* first check if there are any avlb registers
2203 of te type required */
2206 /* special case for pointer type
2207 if pointer type not avlb then
2208 check for type gpr */
2209 if (nFreeRegs (rt) >= nr)
2211 if (nFreeRegs (REG_GPR) >= nr)
2216 if (pic16_ptrRegReq)
2218 if (nFreeRegs (rt) >= nr)
2223 if (nFreeRegs (REG_PTR) +
2224 nFreeRegs (REG_GPR) >= nr)
2229 debugLog (" ... yep it will (cause a spill)\n");
2230 /* it will cause a spil */
2234 /*-----------------------------------------------------------------*/
2235 /* positionRegs - the allocator can allocate same registers to res- */
2236 /* ult and operand, if this happens make sure they are in the same */
2237 /* position as the operand otherwise chaos results */
2238 /*-----------------------------------------------------------------*/
2240 positionRegs (symbol * result, symbol * opsym, int lineno)
2242 int count = min (result->nRegs, opsym->nRegs);
2243 int i, j = 0, shared = 0;
2245 debugLog ("%s\n", __FUNCTION__);
2246 /* if the result has been spilt then cannot share */
2251 /* first make sure that they actually share */
2252 for (i = 0; i < count; i++)
2254 for (j = 0; j < count; j++)
2256 if (result->regs[i] == opsym->regs[j] && i != j)
2266 regs *tmp = result->regs[i];
2267 result->regs[i] = result->regs[j];
2268 result->regs[j] = tmp;
2273 /*------------------------------------------------------------------*/
2274 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2275 /* it should either have registers or have beed spilled. Otherwise, */
2276 /* there was an uninitialized variable, so just spill this to get */
2277 /* the operand in a valid state. */
2278 /*------------------------------------------------------------------*/
2280 verifyRegsAssigned (operand *op, iCode * ic)
2285 if (!IS_ITEMP (op)) return;
2287 sym = OP_SYMBOL (op);
2288 if (sym->isspilt) return;
2289 if (!sym->nRegs) return;
2290 if (sym->regs[0]) return;
2292 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2293 sym->prereqv ? sym->prereqv->name : sym->name);
2298 /*-----------------------------------------------------------------*/
2299 /* serialRegAssign - serially allocate registers to the variables */
2300 /*-----------------------------------------------------------------*/
2302 serialRegAssign (eBBlock ** ebbs, int count)
2307 debugLog ("%s\n", __FUNCTION__);
2308 /* for all blocks */
2309 for (i = 0; i < count; i++)
2311 if (ebbs[i]->noPath &&
2312 (ebbs[i]->entryLabel != entryLabel &&
2313 ebbs[i]->entryLabel != returnLabel))
2316 /* of all instructions do */
2317 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2320 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2322 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2323 pic16_allocDirReg(IC_RESULT(ic));
2325 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2326 pic16_allocDirReg(IC_LEFT(ic));
2328 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2329 pic16_allocDirReg(IC_RIGHT(ic));
2331 /* if this is an ipop that means some live
2332 range will have to be assigned again */
2334 reassignLR (IC_LEFT (ic));
2336 /* if result is present && is a true symbol */
2337 if (IC_RESULT (ic) && ic->op != IFX &&
2338 IS_TRUE_SYMOP (IC_RESULT (ic)))
2339 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2341 /* take away registers from live
2342 ranges that end at this instruction */
2343 deassignLRs (ic, ebbs[i]);
2345 /* some don't need registers */
2346 if (SKIP_IC2 (ic) ||
2347 ic->op == JUMPTABLE ||
2351 (IC_RESULT (ic) && POINTER_SET (ic)))
2354 /* now we need to allocate registers
2355 only for the result */
2358 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2364 /* Make sure any spill location is definately allocated */
2365 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2366 !sym->usl.spillLoc->allocreq)
2368 sym->usl.spillLoc->allocreq++;
2371 /* if it does not need or is spilt
2372 or is already assigned to registers
2373 or will not live beyond this instructions */
2376 bitVectBitValue (_G.regAssigned, sym->key) ||
2377 sym->liveTo <= ic->seq)
2380 /* if some liverange has been spilt at the block level
2381 and this one live beyond this block then spil this
2383 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2388 /* if trying to allocate this will cause
2389 a spill and there is nothing to spill
2390 or this one is rematerializable then
2392 willCS = willCauseSpill (sym->nRegs, sym->regType);
2394 /* explicit turn off register spilling */
2397 spillable = computeSpillable (ic);
2399 (willCS && bitVectIsZero (spillable)))
2407 /* If the live range preceeds the point of definition
2408 then ideally we must take into account registers that
2409 have been allocated after sym->liveFrom but freed
2410 before ic->seq. This is complicated, so spill this
2411 symbol instead and let fillGaps handle the allocation. */
2413 if (sym->liveFrom < ic->seq)
2419 /* if it has a spillocation & is used less than
2420 all other live ranges then spill this */
2422 if (sym->usl.spillLoc) {
2423 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2424 allLRs, ebbs[i], ic));
2425 if (leastUsed && leastUsed->used > sym->used) {
2430 /* if none of the liveRanges have a spillLocation then better
2431 to spill this one than anything else already assigned to registers */
2432 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2433 /* if this is local to this block then we might find a block spil */
2434 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2442 if (ic->op == RECEIVE)
2443 debugLog ("When I get clever, I'll optimize the receive logic\n");
2445 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2446 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2447 && (ic->next->op == IFX)
2448 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2450 /* skip register allocation since none will be used */
2451 for(j=0;j<sym->nRegs;j++)
2452 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2453 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2458 /* if we need ptr regs for the right side
2460 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2461 <= (unsigned) PTRSIZE)
2466 /* else we assign registers to it */
2467 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2470 bitVectDebugOn(_G.regAssigned, debugF);
2472 for (j = 0; j < sym->nRegs; j++)
2474 if (sym->regType == REG_PTR)
2475 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2477 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2479 /* if the allocation falied which means
2480 this was spilt then break */
2484 debugLog (" %d - \n", __LINE__);
2486 /* if it shares registers with operands make sure
2487 that they are in the same position */
2488 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2489 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2490 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2491 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2492 /* do the same for the right operand */
2493 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2494 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2495 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2496 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2498 debugLog (" %d - \n", __LINE__);
2501 debugLog (" %d - \n", __LINE__);
2510 /* Check for and fix any problems with uninitialized operands */
2511 for (i = 0; i < count; i++)
2515 if (ebbs[i]->noPath &&
2516 (ebbs[i]->entryLabel != entryLabel &&
2517 ebbs[i]->entryLabel != returnLabel))
2520 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2527 verifyRegsAssigned (IC_COND (ic), ic);
2531 if (ic->op == JUMPTABLE)
2533 verifyRegsAssigned (IC_JTCOND (ic), ic);
2537 verifyRegsAssigned (IC_RESULT (ic), ic);
2538 verifyRegsAssigned (IC_LEFT (ic), ic);
2539 verifyRegsAssigned (IC_RIGHT (ic), ic);
2545 /*-----------------------------------------------------------------*/
2546 /* rUmaskForOp :- returns register mask for an operand */
2547 /*-----------------------------------------------------------------*/
2549 rUmaskForOp (operand * op)
2555 debugLog ("%s\n", __FUNCTION__);
2556 /* only temporaries are assigned registers */
2560 sym = OP_SYMBOL (op);
2562 /* if spilt or no registers assigned to it
2564 if (sym->isspilt || !sym->nRegs)
2567 rumask = newBitVect (pic16_nRegs);
2569 for (j = 0; j < sym->nRegs; j++)
2571 rumask = bitVectSetBit (rumask,
2572 sym->regs[j]->rIdx);
2578 /*-----------------------------------------------------------------*/
2579 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2580 /*-----------------------------------------------------------------*/
2582 regsUsedIniCode (iCode * ic)
2584 bitVect *rmask = newBitVect (pic16_nRegs);
2586 debugLog ("%s\n", __FUNCTION__);
2587 /* do the special cases first */
2590 rmask = bitVectUnion (rmask,
2591 rUmaskForOp (IC_COND (ic)));
2595 /* for the jumptable */
2596 if (ic->op == JUMPTABLE)
2598 rmask = bitVectUnion (rmask,
2599 rUmaskForOp (IC_JTCOND (ic)));
2604 /* of all other cases */
2606 rmask = bitVectUnion (rmask,
2607 rUmaskForOp (IC_LEFT (ic)));
2611 rmask = bitVectUnion (rmask,
2612 rUmaskForOp (IC_RIGHT (ic)));
2615 rmask = bitVectUnion (rmask,
2616 rUmaskForOp (IC_RESULT (ic)));
2622 /*-----------------------------------------------------------------*/
2623 /* createRegMask - for each instruction will determine the regsUsed */
2624 /*-----------------------------------------------------------------*/
2626 createRegMask (eBBlock ** ebbs, int count)
2630 debugLog ("%s\n", __FUNCTION__);
2631 /* for all blocks */
2632 for (i = 0; i < count; i++)
2636 if (ebbs[i]->noPath &&
2637 (ebbs[i]->entryLabel != entryLabel &&
2638 ebbs[i]->entryLabel != returnLabel))
2641 /* for all instructions */
2642 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2647 if (SKIP_IC2 (ic) || !ic->rlive)
2650 /* first mark the registers used in this
2652 ic->rUsed = regsUsedIniCode (ic);
2653 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2655 /* now create the register mask for those
2656 registers that are in use : this is a
2657 super set of ic->rUsed */
2658 ic->rMask = newBitVect (pic16_nRegs + 1);
2660 /* for all live Ranges alive at this point */
2661 for (j = 1; j < ic->rlive->size; j++)
2666 /* if not alive then continue */
2667 if (!bitVectBitValue (ic->rlive, j))
2670 /* find the live range we are interested in */
2671 if (!(sym = hTabItemWithKey (liveRanges, j)))
2673 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2674 "createRegMask cannot find live range");
2678 /* if no register assigned to it */
2679 if (!sym->nRegs || sym->isspilt)
2682 /* for all the registers allocated to it */
2683 for (k = 0; k < sym->nRegs; k++)
2686 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2692 /*-----------------------------------------------------------------*/
2693 /* rematStr - returns the rematerialized string for a remat var */
2694 /*-----------------------------------------------------------------*/
2696 rematStr (symbol * sym)
2699 iCode *ic = sym->rematiCode;
2700 symbol *psym = NULL;
2702 debugLog ("%s\n", __FUNCTION__);
2704 //printf ("%s\n", s);
2706 /* if plus or minus print the right hand side */
2708 if (ic->op == '+' || ic->op == '-') {
2710 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2712 sprintf (s, "(%s %c 0x%04x)",
2713 OP_SYMBOL (IC_LEFT (ric))->rname,
2715 (int) operandLitValue (IC_RIGHT (ic)));
2718 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2720 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2721 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2726 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2727 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2729 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2734 /*-----------------------------------------------------------------*/
2735 /* rematStr - returns the rematerialized string for a remat var */
2736 /*-----------------------------------------------------------------*/
2738 rematStr (symbol * sym)
2741 iCode *ic = sym->rematiCode;
2743 debugLog ("%s\n", __FUNCTION__);
2748 /* if plus or minus print the right hand side */
2750 if (ic->op == '+' || ic->op == '-') {
2751 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2754 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2758 if (ic->op == '+' || ic->op == '-')
2760 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2761 sprintf (s, "(%s %c 0x%04x)",
2762 OP_SYMBOL (IC_LEFT (ric))->rname,
2764 (int) operandLitValue (IC_RIGHT (ic)));
2767 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2769 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2773 /* we reached the end */
2774 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2778 printf ("%s\n", buffer);
2783 /*-----------------------------------------------------------------*/
2784 /* regTypeNum - computes the type & number of registers required */
2785 /*-----------------------------------------------------------------*/
2793 debugLog ("%s\n", __FUNCTION__);
2794 /* for each live range do */
2795 for (sym = hTabFirstItem (liveRanges, &k); sym;
2796 sym = hTabNextItem (liveRanges, &k)) {
2798 debugLog (" %d - %s\n", __LINE__, sym->rname);
2799 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2801 /* if used zero times then no registers needed */
2802 if ((sym->liveTo - sym->liveFrom) == 0)
2806 /* if the live range is a temporary */
2809 debugLog (" %d - itemp register\n", __LINE__);
2811 /* if the type is marked as a conditional */
2812 if (sym->regType == REG_CND)
2815 /* if used in return only then we don't
2817 if (sym->ruonly || sym->accuse) {
2818 if (IS_AGGREGATE (sym->type) || sym->isptr)
2819 sym->type = aggrToPtr (sym->type, FALSE);
2820 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2824 /* if the symbol has only one definition &
2825 that definition is a get_pointer and the
2826 pointer we are getting is rematerializable and
2829 if (bitVectnBitsOn (sym->defs) == 1 &&
2830 (ic = hTabItemWithKey (iCodehTab,
2831 bitVectFirstBit (sym->defs))) &&
2833 !IS_BITVAR (sym->etype) &&
2834 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2836 // continue; /* FIXME -- VR */
2837 if (ptrPseudoSymSafe (sym, ic)) {
2841 debugLog (" %d - \n", __LINE__);
2843 /* create a psuedo symbol & force a spil */
2844 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2845 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2846 psym->type = sym->type;
2847 psym->etype = sym->etype;
2848 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2849 strcpy (psym->rname, psym->name);
2851 sym->usl.spillLoc = psym;
2855 /* if in data space or idata space then try to
2856 allocate pointer register */
2860 /* if not then we require registers */
2861 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2862 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2863 getSize (sym->type));
2867 if(IS_PTR_CONST (sym->type)) {
2869 if(IS_CODEPTR (sym->type)) {
2871 // what IS this ???? (HJD)
2872 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2873 sym->nRegs = 3; // patch 14
2876 if (sym->nRegs > 4) {
2877 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2878 printTypeChain (sym->type, stderr);
2879 fprintf (stderr, "\n");
2882 /* determine the type of register required */
2883 if (sym->nRegs == 1 &&
2884 IS_PTR (sym->type) &&
2886 sym->regType = REG_PTR;
2888 sym->regType = REG_GPR;
2891 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2895 /* for the first run we don't provide */
2896 /* registers for true symbols we will */
2897 /* see how things go */
2903 static DEFSETFUNC (markRegFree)
2905 ((regs *)item)->isFree = 1;
2906 // ((regs *)item)->wasUsed = 0;
2911 DEFSETFUNC (pic16_deallocReg)
2913 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2914 ((regs *)item)->isFree = 1;
2915 ((regs *)item)->wasUsed = 0;
2919 /*-----------------------------------------------------------------*/
2920 /* freeAllRegs - mark all registers as free */
2921 /*-----------------------------------------------------------------*/
2923 pic16_freeAllRegs ()
2925 debugLog ("%s\n", __FUNCTION__);
2927 applyToSet(pic16_dynAllocRegs,markRegFree);
2928 applyToSet(pic16_dynStackRegs,markRegFree);
2931 /*-----------------------------------------------------------------*/
2932 /*-----------------------------------------------------------------*/
2934 pic16_deallocateAllRegs ()
2936 debugLog ("%s\n", __FUNCTION__);
2938 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2942 /*-----------------------------------------------------------------*/
2943 /* deallocStackSpil - this will set the stack pointer back */
2944 /*-----------------------------------------------------------------*/
2946 DEFSETFUNC (deallocStackSpil)
2950 debugLog ("%s\n", __FUNCTION__);
2955 /*-----------------------------------------------------------------*/
2956 /* farSpacePackable - returns the packable icode for far variables */
2957 /*-----------------------------------------------------------------*/
2959 farSpacePackable (iCode * ic)
2963 debugLog ("%s\n", __FUNCTION__);
2964 /* go thru till we find a definition for the
2965 symbol on the right */
2966 for (dic = ic->prev; dic; dic = dic->prev)
2969 /* if the definition is a call then no */
2970 if ((dic->op == CALL || dic->op == PCALL) &&
2971 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2976 /* if shift by unknown amount then not */
2977 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2978 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2981 /* if pointer get and size > 1 */
2982 if (POINTER_GET (dic) &&
2983 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2986 if (POINTER_SET (dic) &&
2987 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2990 /* if any three is a true symbol in far space */
2991 if (IC_RESULT (dic) &&
2992 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2993 isOperandInFarSpace (IC_RESULT (dic)))
2996 if (IC_RIGHT (dic) &&
2997 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2998 isOperandInFarSpace (IC_RIGHT (dic)) &&
2999 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
3002 if (IC_LEFT (dic) &&
3003 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
3004 isOperandInFarSpace (IC_LEFT (dic)) &&
3005 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
3008 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
3010 if ((dic->op == LEFT_OP ||
3011 dic->op == RIGHT_OP ||
3013 IS_OP_LITERAL (IC_RIGHT (dic)))
3024 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
3028 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3029 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3030 debugAopGet (" result:", IC_RESULT (ic));
3031 debugAopGet (" left:", IC_LEFT (ic));
3032 debugAopGet (" right:", IC_RIGHT (ic));
3041 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3043 /*-----------------------------------------------------------------*/
3044 /* packRegsForAssign - register reduction for assignment */
3045 /*-----------------------------------------------------------------*/
3047 packRegsForAssign (iCode * ic, eBBlock * ebp)
3051 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3052 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3053 debugAopGet (" result:", IC_RESULT (ic));
3054 debugAopGet (" left:", IC_LEFT (ic));
3055 debugAopGet (" right:", IC_RIGHT (ic));
3057 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3059 debugLog(" %d - actuall processing\n", __LINE__ );
3061 if (!IS_ITEMP (IC_RESULT (ic))) {
3062 pic16_allocDirReg(IC_RESULT (ic));
3063 debugLog (" %d - result is not temp\n", __LINE__);
3066 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3068 /* See BUGLOG0001 - VR */
3070 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3071 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3072 pic16_allocDirReg(IC_RIGHT (ic));
3077 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3078 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3080 debugLog (" %d - not packing - right side fails \n", __LINE__);
3084 /* if the true symbol is defined in far space or on stack
3085 then we should not since this will increase register pressure */
3086 if (isOperandInFarSpace (IC_RESULT (ic)))
3088 if ((dic = farSpacePackable (ic)))
3095 /* find the definition of iTempNN scanning backwards if we find a
3096 a use of the true symbol before we find the definition then
3098 for (dic = ic->prev; dic; dic = dic->prev)
3101 /* if there is a function call and this is
3102 a parameter & not my parameter then don't pack it */
3103 if ((dic->op == CALL || dic->op == PCALL) &&
3104 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3105 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3107 debugLog (" %d - \n", __LINE__);
3116 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3118 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3119 IS_OP_VOLATILE (IC_RESULT (dic)))
3121 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3127 if( IS_SYMOP( IC_RESULT(dic)) &&
3128 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3130 debugLog (" %d - result is bitfield\n", __LINE__);
3136 if (IS_SYMOP (IC_RESULT (dic)) &&
3137 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3139 /* A previous result was assigned to the same register - we'll our definition */
3140 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3141 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3142 if (POINTER_SET (dic))
3148 if (IS_SYMOP (IC_RIGHT (dic)) &&
3149 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3150 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3152 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3157 if (IS_SYMOP (IC_LEFT (dic)) &&
3158 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3159 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3161 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3166 if (POINTER_SET (dic) &&
3167 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3169 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3177 return 0; /* did not find */
3180 /* This code is taken from the hc08 port. Do not know
3181 * if it fits for pic16, but I leave it here just in case */
3183 /* if assignment then check that right is not a bit */
3184 if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
3185 sym_link *etype = operandType (IC_RESULT (dic));
3187 if (IS_BITFIELD (etype)) {
3188 /* if result is a bit too then it's ok */
3189 etype = operandType (IC_RESULT (ic));
3190 if (!IS_BITFIELD (etype)) {
3191 debugLog(" %d bitfields\n");
3198 /* if the result is on stack or iaccess then it must be
3199 the same atleast one of the operands */
3200 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3201 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3203 /* the operation has only one symbol
3204 operator then we can pack */
3205 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3206 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3209 if (!((IC_LEFT (dic) &&
3210 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3212 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3216 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3217 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3218 /* found the definition */
3219 /* replace the result with the result of */
3220 /* this assignment and remove this assignment */
3223 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3224 IC_RESULT (dic) = IC_RESULT (ic);
3226 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3228 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3230 /* delete from liverange table also
3231 delete from all the points inbetween and the new
3233 for (sic = dic; sic != ic; sic = sic->next)
3235 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3236 if (IS_ITEMP (IC_RESULT (dic)))
3237 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3240 remiCodeFromeBBlock (ebp, ic);
3241 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3243 debugLog(" %d\n", __LINE__ );
3244 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3245 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3252 #define NO_packRegsForAccUse
3253 #define NO_packRegsForSupport
3254 #define NO_packRegsForOneuse
3255 #define NO_cast_peep
3260 #ifndef NO_packRegsForSupport
3261 /*-----------------------------------------------------------------*/
3262 /* findAssignToSym : scanning backwards looks for first assig found */
3263 /*-----------------------------------------------------------------*/
3265 findAssignToSym (operand * op, iCode * ic)
3269 debugLog ("%s\n", __FUNCTION__);
3270 for (dic = ic->prev; dic; dic = dic->prev)
3273 /* if definition by assignment */
3274 if (dic->op == '=' &&
3275 !POINTER_SET (dic) &&
3276 IC_RESULT (dic)->key == op->key
3277 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3281 /* we are interested only if defined in far space */
3282 /* or in stack space in case of + & - */
3284 /* if assigned to a non-symbol then return
3286 if (!IS_SYMOP (IC_RIGHT (dic)))
3289 /* if the symbol is in far space then
3291 if (isOperandInFarSpace (IC_RIGHT (dic)))
3294 /* for + & - operations make sure that
3295 if it is on the stack it is the same
3296 as one of the three operands */
3297 if ((ic->op == '+' || ic->op == '-') &&
3298 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3300 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3301 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3302 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3310 /* if we find an usage then we cannot delete it */
3311 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3314 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3317 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3321 /* now make sure that the right side of dic
3322 is not defined between ic & dic */
3325 iCode *sic = dic->next;
3327 for (; sic != ic; sic = sic->next)
3328 if (IC_RESULT (sic) &&
3329 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3340 #ifndef NO_packRegsForSupport
3341 /*-----------------------------------------------------------------*/
3342 /* packRegsForSupport :- reduce some registers for support calls */
3343 /*-----------------------------------------------------------------*/
3345 packRegsForSupport (iCode * ic, eBBlock * ebp)
3349 debugLog ("%s\n", __FUNCTION__);
3350 /* for the left & right operand :- look to see if the
3351 left was assigned a true symbol in far space in that
3352 case replace them */
3353 if (IS_ITEMP (IC_LEFT (ic)) &&
3354 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3356 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3362 debugAopGet ("removing left:", IC_LEFT (ic));
3364 /* found it we need to remove it from the
3366 for (sic = dic; sic != ic; sic = sic->next)
3367 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3369 IC_LEFT (ic)->operand.symOperand =
3370 IC_RIGHT (dic)->operand.symOperand;
3371 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3372 remiCodeFromeBBlock (ebp, dic);
3373 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3374 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3378 /* do the same for the right operand */
3381 IS_ITEMP (IC_RIGHT (ic)) &&
3382 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3384 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3390 /* if this is a subtraction & the result
3391 is a true symbol in far space then don't pack */
3392 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3394 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3395 if (IN_FARSPACE (SPEC_OCLS (etype)))
3399 debugAopGet ("removing right:", IC_RIGHT (ic));
3401 /* found it we need to remove it from the
3403 for (sic = dic; sic != ic; sic = sic->next)
3404 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3406 IC_RIGHT (ic)->operand.symOperand =
3407 IC_RIGHT (dic)->operand.symOperand;
3408 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3410 remiCodeFromeBBlock (ebp, dic);
3411 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3412 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3421 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3423 #ifndef NO_packRegsForOneuse
3424 /*-----------------------------------------------------------------*/
3425 /* packRegsForOneuse : - will reduce some registers for single Use */
3426 /*-----------------------------------------------------------------*/
3428 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3435 debugLog ("%s\n", __FUNCTION__);
3436 /* if returning a literal then do nothing */
3440 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3443 /* only upto 2 bytes since we cannot predict
3444 the usage of b, & acc */
3445 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3453 /* this routine will mark the a symbol as used in one
3454 instruction use only && if the definition is local
3455 (ie. within the basic block) && has only one definition &&
3456 that definition is either a return value from a
3457 function or does not contain any variables in
3461 uses = bitVectCopy (OP_USES (op));
3462 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3463 if (!bitVectIsZero (uses)) /* has other uses */
3468 if (bitVectnBitsOn (OP_USES (op)) > 1)
3472 /* if it has only one defintion */
3473 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3474 return NULL; /* has more than one definition */
3476 /* get that definition */
3478 hTabItemWithKey (iCodehTab,
3479 bitVectFirstBit (OP_DEFS (op)))))
3482 /* found the definition now check if it is local */
3483 if (dic->seq < ebp->fSeq ||
3484 dic->seq > ebp->lSeq)
3485 return NULL; /* non-local */
3487 /* now check if it is the return from
3489 if (dic->op == CALL || dic->op == PCALL)
3491 if (ic->op != SEND && ic->op != RETURN &&
3492 !POINTER_SET(ic) && !POINTER_GET(ic))
3494 OP_SYMBOL (op)->ruonly = 1;
3503 /* otherwise check that the definition does
3504 not contain any symbols in far space */
3505 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3506 isOperandInFarSpace (IC_RIGHT (dic)) ||
3507 IS_OP_RUONLY (IC_LEFT (ic)) ||
3508 IS_OP_RUONLY (IC_RIGHT (ic)))
3513 /* if pointer set then make sure the pointer
3515 if (POINTER_SET (dic) &&
3516 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3519 if (POINTER_GET (dic) &&
3520 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3526 /* also make sure the intervenening instructions
3527 don't have any thing in far space */
3528 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3531 /* if there is an intervening function call then no */
3532 if (dic->op == CALL || dic->op == PCALL)
3534 /* if pointer set then make sure the pointer
3536 if (POINTER_SET (dic) &&
3537 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3540 if (POINTER_GET (dic) &&
3541 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3544 /* if address of & the result is remat then okay */
3545 if (dic->op == ADDRESS_OF &&
3546 OP_SYMBOL (IC_RESULT (dic))->remat)
3549 /* if operand has size of three or more & this
3550 operation is a '*','/' or '%' then 'b' may
3552 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3553 getSize (operandType (op)) >= 2)
3556 /* if left or right or result is in far space */
3557 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3558 isOperandInFarSpace (IC_RIGHT (dic)) ||
3559 isOperandInFarSpace (IC_RESULT (dic)) ||
3560 IS_OP_RUONLY (IC_LEFT (dic)) ||
3561 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3562 IS_OP_RUONLY (IC_RESULT (dic)))
3568 OP_SYMBOL (op)->ruonly = 1;
3575 /*-----------------------------------------------------------------*/
3576 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3577 /*-----------------------------------------------------------------*/
3579 isBitwiseOptimizable (iCode * ic)
3581 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3582 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3584 debugLog ("%s\n", __FUNCTION__);
3585 /* bitwise operations are considered optimizable
3586 under the following conditions (Jean-Louis VERN)
3598 if (IS_LITERAL (rtype) ||
3599 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3606 #ifndef NO_packRegsForAccUse
3608 /*-----------------------------------------------------------------*/
3609 /* packRegsForAccUse - pack registers for acc use */
3610 /*-----------------------------------------------------------------*/
3612 packRegsForAccUse (iCode * ic)
3616 debugLog ("%s\n", __FUNCTION__);
3618 /* if this is an aggregate, e.g. a one byte char array */
3619 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3622 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3624 /* if + or - then it has to be one byte result */
3625 if ((ic->op == '+' || ic->op == '-')
3626 && getSize (operandType (IC_RESULT (ic))) > 1)
3629 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3630 /* if shift operation make sure right side is not a literal */
3631 if (ic->op == RIGHT_OP &&
3632 (isOperandLiteral (IC_RIGHT (ic)) ||
3633 getSize (operandType (IC_RESULT (ic))) > 1))
3636 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3637 if (ic->op == LEFT_OP &&
3638 (isOperandLiteral (IC_RIGHT (ic)) ||
3639 getSize (operandType (IC_RESULT (ic))) > 1))
3642 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3643 if (IS_BITWISE_OP (ic) &&
3644 getSize (operandType (IC_RESULT (ic))) > 1)
3648 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3649 /* has only one definition */
3650 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3653 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3654 /* has only one use */
3655 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3658 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3659 /* and the usage immediately follows this iCode */
3660 if (!(uic = hTabItemWithKey (iCodehTab,
3661 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3664 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3665 if (ic->next != uic)
3668 /* if it is a conditional branch then we definitely can */
3672 if (uic->op == JUMPTABLE)
3675 /* if the usage is not is an assignment
3676 or an arithmetic / bitwise / shift operation then not */
3677 if (POINTER_SET (uic) &&
3678 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3681 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3682 if (uic->op != '=' &&
3683 !IS_ARITHMETIC_OP (uic) &&
3684 !IS_BITWISE_OP (uic) &&
3685 uic->op != LEFT_OP &&
3686 uic->op != RIGHT_OP)
3689 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3690 /* if used in ^ operation then make sure right is not a
3692 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3695 /* if shift operation make sure right side is not a literal */
3696 if (uic->op == RIGHT_OP &&
3697 (isOperandLiteral (IC_RIGHT (uic)) ||
3698 getSize (operandType (IC_RESULT (uic))) > 1))
3701 if (uic->op == LEFT_OP &&
3702 (isOperandLiteral (IC_RIGHT (uic)) ||
3703 getSize (operandType (IC_RESULT (uic))) > 1))
3706 /* make sure that the result of this icode is not on the
3707 stack, since acc is used to compute stack offset */
3708 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3709 OP_SYMBOL (IC_RESULT (uic))->onStack)
3712 /* if either one of them in far space then we cannot */
3713 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3714 isOperandInFarSpace (IC_LEFT (uic))) ||
3715 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3716 isOperandInFarSpace (IC_RIGHT (uic))))
3719 /* if the usage has only one operand then we can */
3720 if (IC_LEFT (uic) == NULL ||
3721 IC_RIGHT (uic) == NULL)
3724 /* make sure this is on the left side if not
3725 a '+' since '+' is commutative */
3726 if (ic->op != '+' &&
3727 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3731 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3732 /* if one of them is a literal then we can */
3733 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3734 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3735 (getSize (operandType (IC_RESULT (uic))) <= 1))
3737 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3742 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3743 /* if the other one is not on stack then we can */
3744 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3745 (IS_ITEMP (IC_RIGHT (uic)) ||
3746 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3747 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3750 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3751 (IS_ITEMP (IC_LEFT (uic)) ||
3752 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3753 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3759 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3760 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3767 /*-----------------------------------------------------------------*/
3768 /* packForPush - hueristics to reduce iCode for pushing */
3769 /*-----------------------------------------------------------------*/
3771 packForReceive (iCode * ic, eBBlock * ebp)
3775 debugLog ("%s\n", __FUNCTION__);
3776 debugAopGet (" result:", IC_RESULT (ic));
3777 debugAopGet (" left:", IC_LEFT (ic));
3778 debugAopGet (" right:", IC_RIGHT (ic));
3783 for (dic = ic->next; dic; dic = dic->next)
3785 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3786 debugLog (" used on left\n");
3787 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3788 debugLog (" used on right\n");
3789 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3790 debugLog (" used on result\n");
3792 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3793 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3797 debugLog (" hey we can remove this unnecessary assign\n");
3799 /*-----------------------------------------------------------------*/
3800 /* packForPush - hueristics to reduce iCode for pushing */
3801 /*-----------------------------------------------------------------*/
3803 packForPush (iCode * ic, eBBlock * ebp)
3807 debugLog ("%s\n", __FUNCTION__);
3808 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3815 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3816 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3817 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3818 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3822 /* must have only definition & one usage */
3823 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3824 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3827 /* find the definition */
3828 if (!(dic = hTabItemWithKey (iCodehTab,
3829 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3832 /* if definition is not assignment,
3833 * or is not pointer (because pointer might have changed) */
3834 if (dic->op != '=' || POINTER_SET (dic))
3837 /* we must ensure that we can use the delete the assignment,
3838 * because the source might have been modified in between.
3839 * Until I know how to fix this, I'll use the adhoc fix
3840 * to check the liveranges */
3841 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3843 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3847 /* we now we know that it has one & only one def & use
3848 and the that the definition is an assignment */
3849 IC_LEFT (ic) = IC_RIGHT (dic);
3851 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3853 remiCodeFromeBBlock (ebp, dic);
3854 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3855 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3858 static void printSymType(char * str, sym_link *sl)
3860 if(!pic16_ralloc_debug)return;
3862 debugLog (" %s Symbol type: ",str);
3863 printTypeChain( sl, debugF);
3867 /*-----------------------------------------------------------------*/
3868 /* some debug code to print the symbol S_TYPE. Note that
3869 * the function checkSClass in src/SDCCsymt.c dinks with
3870 * the S_TYPE in ways the PIC port doesn't fully like...*/
3871 /*-----------------------------------------------------------------*/
3872 static void isData(sym_link *sl)
3876 if(!pic16_ralloc_debug)return;
3883 for ( ; sl; sl=sl->next) {
3885 switch (SPEC_SCLS(sl)) {
3886 case S_DATA: fprintf (of, "data "); break;
3887 case S_XDATA: fprintf (of, "xdata "); break;
3888 case S_SFR: fprintf (of, "sfr "); break;
3889 case S_SBIT: fprintf (of, "sbit "); break;
3890 case S_CODE: fprintf (of, "code "); break;
3891 case S_IDATA: fprintf (of, "idata "); break;
3892 case S_PDATA: fprintf (of, "pdata "); break;
3893 case S_LITERAL: fprintf (of, "literal "); break;
3894 case S_STACK: fprintf (of, "stack "); break;
3895 case S_XSTACK: fprintf (of, "xstack "); break;
3896 case S_BIT: fprintf (of, "bit "); break;
3897 case S_EEPROM: fprintf (of, "eeprom "); break;
3905 /*--------------------------------------------------------------------*/
3906 /* pic16_packRegisters - does some transformations to reduce */
3907 /* register pressure */
3909 /*--------------------------------------------------------------------*/
3911 pic16_packRegisters (eBBlock * ebp)
3916 debugLog ("%s\n", __FUNCTION__);
3922 /* look for assignments of the form */
3923 /* iTempNN = TRueSym (someoperation) SomeOperand */
3925 /* TrueSym := iTempNN:1 */
3926 for (ic = ebp->sch; ic; ic = ic->next)
3928 // debugLog("%d\n", __LINE__);
3929 /* find assignment of the form TrueSym := iTempNN:1 */
3930 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3931 change += packRegsForAssign (ic, ebp);
3935 if (POINTER_SET (ic))
3936 debugLog ("pointer is set\n");
3937 debugAopGet (" result:", IC_RESULT (ic));
3938 debugAopGet (" left:", IC_LEFT (ic));
3939 debugAopGet (" right:", IC_RIGHT (ic));
3948 for (ic = ebp->sch; ic; ic = ic->next) {
3950 if(IS_SYMOP ( IC_LEFT(ic))) {
3951 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3953 debugAopGet ("x left:", IC_LEFT (ic));
3955 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3957 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3959 debugLog (" is a pointer\n");
3961 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3962 debugLog (" is a ptr\n");
3964 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3965 debugLog (" is volatile\n");
3969 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3970 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3971 pic16_allocDirReg(IC_LEFT (ic));
3974 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3977 if(IS_SYMOP ( IC_RIGHT(ic))) {
3978 debugAopGet (" right:", IC_RIGHT (ic));
3979 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3982 if(IS_SYMOP ( IC_RESULT(ic))) {
3983 debugAopGet (" result:", IC_RESULT (ic));
3984 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3987 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3988 debugAopGet (" right:", IC_RIGHT (ic));
3989 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3990 // pic16_allocDirReg(IC_RIGHT(ic));
3993 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3994 debugAopGet (" result:", IC_RESULT (ic));
3995 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3996 // pic16_allocDirReg(IC_RESULT(ic));
4000 if (POINTER_SET (ic))
4001 debugLog (" %d - Pointer set\n", __LINE__);
4003 /* Look for two subsequent iCodes with */
4005 /* _c = iTemp & op; */
4006 /* and replace them by */
4009 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
4011 && ic->prev->op == '='
4012 && IS_ITEMP (IC_LEFT (ic))
4013 && IC_LEFT (ic) == IC_RESULT (ic->prev)
4014 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
4016 iCode* ic_prev = ic->prev;
4017 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
4019 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
4020 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
4021 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
4022 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
4023 prev_result_sym->liveTo == ic->seq)
4025 prev_result_sym->liveTo = ic_prev->seq;
4028 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
4030 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
4032 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
4033 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
4034 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
4035 remiCodeFromeBBlock (ebp, ic_prev);
4036 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
4040 /* if this is an itemp & result of a address of a true sym
4041 then mark this as rematerialisable */
4042 if (ic->op == ADDRESS_OF &&
4043 IS_ITEMP (IC_RESULT (ic)) &&
4044 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4045 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4046 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4049 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4051 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4052 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4053 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4057 /* if straight assignment then carry remat flag if
4058 this is the only definition */
4059 if (ic->op == '=' &&
4060 !POINTER_SET (ic) &&
4061 IS_SYMOP (IC_RIGHT (ic)) &&
4062 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4063 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4065 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4067 OP_SYMBOL (IC_RESULT (ic))->remat =
4068 OP_SYMBOL (IC_RIGHT (ic))->remat;
4069 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4070 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4073 /* if this is a +/- operation with a rematerizable
4074 then mark this as rematerializable as well */
4075 if ((ic->op == '+' || ic->op == '-') &&
4076 (IS_SYMOP (IC_LEFT (ic)) &&
4077 IS_ITEMP (IC_RESULT (ic)) &&
4078 OP_SYMBOL (IC_LEFT (ic))->remat &&
4079 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4080 IS_OP_LITERAL (IC_RIGHT (ic))))
4082 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4084 operandLitValue (IC_RIGHT (ic));
4085 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4086 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4087 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4092 /* try to optimize FSR0 usage when reading data memory pointers */
4094 if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4095 static int fsr0usage=0;
4098 if(POINTER_GET(ic) /* this is a memory read */
4099 && ic->loop /* this is in a loop */
4101 fprintf(stderr, "might optimize FSR0 usage\n");
4106 /* mark the pointer usages */
4107 if (POINTER_SET (ic))
4109 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4110 debugLog (" marking as a pointer (set) =>");
4111 debugAopGet (" result:", IC_RESULT (ic));
4115 if (POINTER_GET (ic))
4117 if(IS_SYMOP(IC_LEFT(ic))) {
4118 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4119 debugLog (" marking as a pointer (get) =>");
4120 debugAopGet (" left:", IC_LEFT (ic));
4123 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4124 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4125 iCode *dic = ic->prev;
4127 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4129 if(dic && dic->op == '='
4130 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4132 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4135 /* replace prev->left with ic->left */
4136 IC_LEFT(ic) = IC_RIGHT(dic);
4137 IC_RIGHT(ic->prev) = NULL;
4139 /* remove ic->prev iCode (assignment) */
4140 remiCodeFromeBBlock (ebp, dic);
4141 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4144 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4150 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4154 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4155 /* if we are using a symbol on the stack
4156 then we should say pic16_ptrRegReq */
4157 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4158 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4159 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4160 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4161 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4162 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4166 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4167 if (IS_SYMOP (IC_LEFT (ic)))
4168 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4169 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4170 if (IS_SYMOP (IC_RIGHT (ic)))
4171 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4172 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4173 if (IS_SYMOP (IC_RESULT (ic)))
4174 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4175 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4178 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4182 /* if the condition of an if instruction
4183 is defined in the previous instruction then
4184 mark the itemp as a conditional */
4185 if ((IS_CONDITIONAL (ic) ||
4186 ((ic->op == BITWISEAND ||
4189 isBitwiseOptimizable (ic))) &&
4190 ic->next && ic->next->op == IFX &&
4191 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4192 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4195 debugLog (" %d\n", __LINE__);
4196 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4200 debugLog(" %d\n", __LINE__);
4202 #ifndef NO_packRegsForSupport
4203 /* reduce for support function calls */
4204 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4205 packRegsForSupport (ic, ebp);
4208 /* if a parameter is passed, it's in W, so we may not
4209 need to place a copy in a register */
4210 if (ic->op == RECEIVE)
4211 packForReceive (ic, ebp);
4213 #ifndef NO_packRegsForOneuse
4214 /* some cases the redundant moves can
4215 can be eliminated for return statements */
4216 if ((ic->op == RETURN || ic->op == SEND) &&
4217 !isOperandInFarSpace (IC_LEFT (ic)) &&
4219 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4222 #ifndef NO_packRegsForOneuse
4223 /* if pointer set & left has a size more than
4224 one and right is not in far space */
4225 if (POINTER_SET (ic) &&
4226 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4227 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4228 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4229 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4231 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4234 #ifndef NO_packRegsForOneuse
4235 /* if pointer get */
4236 if (POINTER_GET (ic) &&
4237 !isOperandInFarSpace (IC_RESULT (ic)) &&
4238 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4239 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4240 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4242 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4243 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4246 #ifndef NO_cast_peep
4247 /* if this is cast for intergral promotion then
4248 check if only use of the definition of the
4249 operand being casted/ if yes then replace
4250 the result of that arithmetic operation with
4251 this result and get rid of the cast */
4252 if (ic->op == CAST) {
4254 sym_link *fromType = operandType (IC_RIGHT (ic));
4255 sym_link *toType = operandType (IC_LEFT (ic));
4257 debugLog (" %d - casting\n", __LINE__);
4259 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4260 getSize (fromType) != getSize (toType)) {
4263 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4266 if (IS_ARITHMETIC_OP (dic)) {
4267 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4269 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4270 IC_RESULT (dic) = IC_RESULT (ic);
4271 remiCodeFromeBBlock (ebp, ic);
4272 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4273 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4274 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4278 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4282 /* if the type from and type to are the same
4283 then if this is the only use then packit */
4284 if (compareType (operandType (IC_RIGHT (ic)),
4285 operandType (IC_LEFT (ic))) == 1) {
4287 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4290 debugLog(" %d\n", __LINE__);
4292 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4293 IC_RESULT (dic) = IC_RESULT (ic);
4294 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4295 remiCodeFromeBBlock (ebp, ic);
4296 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4297 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4306 /* there are some problems with packing variables
4307 * it seems that the live range estimator doesn't
4308 * estimate correctly the liveranges of some symbols */
4311 iTempNN := (some variable in farspace) V1
4316 if (ic->op == IPUSH)
4318 packForPush (ic, ebp);
4322 #ifndef NO_packRegsForAccUse
4323 /* pack registers for accumulator use, when the
4324 result of an arithmetic or bit wise operation
4325 has only one use, that use is immediately following
4326 the defintion and the using iCode has only one
4327 operand or has two operands but one is literal &
4328 the result of that operation is not on stack then
4329 we can leave the result of this operation in acc:b
4331 if ((IS_ARITHMETIC_OP (ic)
4333 || IS_BITWISE_OP (ic)
4335 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4338 IS_ITEMP (IC_RESULT (ic)) &&
4339 getSize (operandType (IC_RESULT (ic))) <= 1)
4341 packRegsForAccUse (ic);
4348 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4352 if (!pic16_ralloc_debug || !debugF)
4355 for (i = 0; i < count; i++)
4357 fprintf (debugF, "\n----------------------------------------------------------------\n");
4358 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4359 ebbs[i]->entryLabel->name,
4362 ebbs[i]->isLastInLoop);
4363 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4368 fprintf (debugF, "visited %d : hasFcall = %d\n",
4372 fprintf (debugF, "\ndefines bitVector :");
4373 bitVectDebugOn (ebbs[i]->defSet, debugF);
4374 fprintf (debugF, "\nlocal defines bitVector :");
4375 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4376 fprintf (debugF, "\npointers Set bitvector :");
4377 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4378 fprintf (debugF, "\nin pointers Set bitvector :");
4379 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4380 fprintf (debugF, "\ninDefs Set bitvector :");
4381 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4382 fprintf (debugF, "\noutDefs Set bitvector :");
4383 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4384 fprintf (debugF, "\nusesDefs Set bitvector :");
4385 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4386 fprintf (debugF, "\n----------------------------------------------------------------\n");
4387 printiCChain (ebbs[i]->sch, debugF);
4391 void dbg_dumpregusage(void);
4393 /*-----------------------------------------------------------------*/
4394 /* pic16_assignRegisters - assigns registers to each live range as need */
4395 /*-----------------------------------------------------------------*/
4397 pic16_assignRegisters (ebbIndex * ebbi)
4399 eBBlock ** ebbs = ebbi->bbOrder;
4400 int count = ebbi->count;
4404 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4405 debugLog ("\nebbs before optimizing:\n");
4406 dumpEbbsToDebug (ebbs, count);
4408 _inRegAllocator = 1;
4410 pic16_freeAllRegs();
4413 /* clear whats left over from peephole parser */
4414 pic16_dynAllocRegs= newSet(); //NULL;
4415 // pic16_dynStackRegs= newSet(); //NULL;
4416 // pic16_dynProcessorRegs=newSet(); //NULL;
4417 // pic16_dynDirectRegs=newSet(); //NULL;
4418 // pic16_dynDirectBitRegs=newSet(); //NULL;
4419 // pic16_dynInternalRegs=newSet(); //NULL;
4420 // pic16_dynAccessRegs=newSet(); //NULL;
4422 // dynDirectRegNames=NULL;
4423 dynAllocRegNames=NULL;
4424 // dynProcRegNames=NULL;
4425 // dynAccessRegNames=NULL;
4428 setToNull ((void *) &_G.funcrUsed);
4429 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4432 /* change assignments this will remove some
4433 live ranges reducing some register pressure */
4434 for (i = 0; i < count; i++)
4435 pic16_packRegisters (ebbs[i]);
4442 debugLog("dir registers allocated so far:\n");
4443 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4447 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4448 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4449 reg = hTabNextItem(dynDirectRegNames, &hkey);
4455 /* liveranges probably changed by register packing
4456 so we compute them again */
4457 recomputeLiveRanges (ebbs, count);
4459 if (options.dump_pack)
4460 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4462 /* first determine for each live range the number of
4463 registers & the type of registers required for each */
4466 /* start counting function temporary registers from zero */
4467 /* XXX: Resetting dynrIdx breaks register allocation,
4468 * see #1489055, #1483693 (?), and #1445850! */
4471 /* and serially allocate registers */
4472 serialRegAssign (ebbs, count);
4475 debugLog ("ebbs after serialRegAssign:\n");
4476 dumpEbbsToDebug (ebbs, count);
4479 //pic16_freeAllRegs();
4481 /* if stack was extended then tell the user */
4484 /* werror(W_TOOMANY_SPILS,"stack", */
4485 /* _G.stackExtend,currFunc->name,""); */
4491 /* werror(W_TOOMANY_SPILS,"data space", */
4492 /* _G.dataExtend,currFunc->name,""); */
4496 /* after that create the register mask
4497 for each of the instruction */
4498 createRegMask (ebbs, count);
4500 /* redo that offsets for stacked automatic variables */
4501 redoStackOffsets ();
4503 if (options.dump_rassgn)
4504 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4506 // dumpLR(ebbs, count);
4508 /* now get back the chain */
4509 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4511 debugLog ("ebbs after optimizing:\n");
4512 dumpEbbsToDebug (ebbs, count);
4515 _inRegAllocator = 0;
4519 /* free up any _G.stackSpil locations allocated */
4520 applyToSet (_G.stackSpil, deallocStackSpil);
4522 setToNull ((void *) &_G.stackSpil);
4523 setToNull ((void *) &_G.spiltSet);
4524 /* mark all registers as free */
4525 pic16_freeAllRegs ();
4528 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");