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);
157 while (isspace((unsigned char)*bufferP)) bufferP++;
159 if (bufferP && *bufferP)
160 lineCurr = (lineCurr ?
161 connectLine(lineCurr,newLineNode(lb)) :
162 (lineHead = newLineNode(lb)));
163 lineCurr->isInline = _G.inLine;
164 lineCurr->isDebug = _G.debugLine;
173 if(!pic16_ralloc_debug)return;
176 fputc ('\n', debugF);
178 /*-----------------------------------------------------------------*/
179 /* debugLogClose - closes the debug log file (if opened) */
180 /*-----------------------------------------------------------------*/
190 #define AOP(op) op->aop
193 debugAopGet (char *str, operand * op)
195 if(!pic16_ralloc_debug)return NULL;
200 printOperand (op, debugF);
207 pic16_decodeOp (unsigned int op)
209 if (op < 128 && op > ' ') {
210 buffer[0] = (op & 0xff);
216 case IDENTIFIER: return "IDENTIFIER";
217 case TYPE_NAME: return "TYPE_NAME";
218 case CONSTANT: return "CONSTANT";
219 case STRING_LITERAL: return "STRING_LITERAL";
220 case SIZEOF: return "SIZEOF";
221 case PTR_OP: return "PTR_OP";
222 case INC_OP: return "INC_OP";
223 case DEC_OP: return "DEC_OP";
224 case LEFT_OP: return "LEFT_OP";
225 case RIGHT_OP: return "RIGHT_OP";
226 case LE_OP: return "LE_OP";
227 case GE_OP: return "GE_OP";
228 case EQ_OP: return "EQ_OP";
229 case NE_OP: return "NE_OP";
230 case AND_OP: return "AND_OP";
231 case OR_OP: return "OR_OP";
232 case MUL_ASSIGN: return "MUL_ASSIGN";
233 case DIV_ASSIGN: return "DIV_ASSIGN";
234 case MOD_ASSIGN: return "MOD_ASSIGN";
235 case ADD_ASSIGN: return "ADD_ASSIGN";
236 case SUB_ASSIGN: return "SUB_ASSIGN";
237 case LEFT_ASSIGN: return "LEFT_ASSIGN";
238 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
239 case AND_ASSIGN: return "AND_ASSIGN";
240 case XOR_ASSIGN: return "XOR_ASSIGN";
241 case OR_ASSIGN: return "OR_ASSIGN";
242 case TYPEDEF: return "TYPEDEF";
243 case EXTERN: return "EXTERN";
244 case STATIC: return "STATIC";
245 case AUTO: return "AUTO";
246 case REGISTER: return "REGISTER";
247 case CODE: return "CODE";
248 case EEPROM: return "EEPROM";
249 case INTERRUPT: return "INTERRUPT";
250 case SFR: return "SFR";
251 case AT: return "AT";
252 case SBIT: return "SBIT";
253 case REENTRANT: return "REENTRANT";
254 case USING: return "USING";
255 case XDATA: return "XDATA";
256 case DATA: return "DATA";
257 case IDATA: return "IDATA";
258 case PDATA: return "PDATA";
259 case VAR_ARGS: return "VAR_ARGS";
260 case CRITICAL: return "CRITICAL";
261 case NONBANKED: return "NONBANKED";
262 case BANKED: return "BANKED";
263 case CHAR: return "CHAR";
264 case SHORT: return "SHORT";
265 case INT: return "INT";
266 case LONG: return "LONG";
267 case SIGNED: return "SIGNED";
268 case UNSIGNED: return "UNSIGNED";
269 case FLOAT: return "FLOAT";
270 case DOUBLE: return "DOUBLE";
271 case CONST: return "CONST";
272 case VOLATILE: return "VOLATILE";
273 case VOID: return "VOID";
274 case BIT: return "BIT";
275 case STRUCT: return "STRUCT";
276 case UNION: return "UNION";
277 case ENUM: return "ENUM";
278 case ELIPSIS: return "ELIPSIS";
279 case RANGE: return "RANGE";
280 case FAR: return "FAR";
281 case CASE: return "CASE";
282 case DEFAULT: return "DEFAULT";
283 case IF: return "IF";
284 case ELSE: return "ELSE";
285 case SWITCH: return "SWITCH";
286 case WHILE: return "WHILE";
287 case DO: return "DO";
288 case FOR: return "FOR";
289 case GOTO: return "GOTO";
290 case CONTINUE: return "CONTINUE";
291 case BREAK: return "BREAK";
292 case RETURN: return "RETURN";
293 case INLINEASM: return "INLINEASM";
294 case IFX: return "IFX";
295 case ADDRESS_OF: return "ADDRESS_OF";
296 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
297 case SPIL: return "SPIL";
298 case UNSPIL: return "UNSPIL";
299 case GETHBIT: return "GETHBIT";
300 case BITWISEAND: return "BITWISEAND";
301 case UNARYMINUS: return "UNARYMINUS";
302 case IPUSH: return "IPUSH";
303 case IPOP: return "IPOP";
304 case PCALL: return "PCALL";
305 case FUNCTION: return "FUNCTION";
306 case ENDFUNCTION: return "ENDFUNCTION";
307 case JUMPTABLE: return "JUMPTABLE";
308 case RRC: return "RRC";
309 case RLC: return "RLC";
310 case CAST: return "CAST";
311 case CALL: return "CALL";
312 case PARAM: return "PARAM ";
313 case NULLOP: return "NULLOP";
314 case BLOCK: return "BLOCK";
315 case LABEL: return "LABEL";
316 case RECEIVE: return "RECEIVE";
317 case SEND: return "SEND";
318 case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
320 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
324 /*-----------------------------------------------------------------*/
325 /*-----------------------------------------------------------------*/
327 debugLogRegType (short type)
329 if(!pic16_ralloc_debug)return NULL;
331 case REG_GPR: return "REG_GPR";
332 case REG_PTR: return "REG_PTR";
333 case REG_CND: return "REG_CND";
335 sprintf (buffer, "unknown reg type %d", type);
340 /*-----------------------------------------------------------------*/
341 /*-----------------------------------------------------------------*/
342 static int regname2key(char const *name)
351 key += (*name++) + 1;
355 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
359 /*-----------------------------------------------------------------*/
360 /* newReg - allocate and init memory for a new register */
361 /*-----------------------------------------------------------------*/
362 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
367 dReg = Safe_calloc(1,sizeof(regs));
369 dReg->pc_type = pc_type;
372 dReg->name = Safe_strdup(name);
374 sprintf(buffer,"r0x%02X", dReg->rIdx);
375 if(type == REG_STK) {
378 dReg->name = Safe_strdup(buffer);
386 if(type == REG_SFR) {
388 dReg->address = rIdx;
389 dReg->accessBank = 1;
393 dReg->accessBank = 0;
397 fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
401 dReg->reg_alias = NULL;
402 dReg->reglives.usedpFlows = newSet();
403 dReg->reglives.assignedpFlows = newSet();
406 if(!(type == REG_SFR && alias == 0x80))
407 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
412 /*-----------------------------------------------------------------*/
413 /* regWithIdx - Search through a set of registers that matches idx */
414 /*-----------------------------------------------------------------*/
416 regWithIdx (set *dRegs, int idx, unsigned fixed)
420 for (dReg = setFirstItem(dRegs) ; dReg ;
421 dReg = setNextItem(dRegs)) {
423 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
431 /*-----------------------------------------------------------------*/
432 /* regFindFree - Search for a free register in a set of registers */
433 /*-----------------------------------------------------------------*/
435 regFindFree (set *dRegs)
439 for (dReg = setFirstItem(dRegs) ; dReg ;
440 dReg = setNextItem(dRegs)) {
442 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
443 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
454 regFindFreeNext(set *dRegs, regs *creg)
459 /* position at current register */
460 for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
463 for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
472 /*-----------------------------------------------------------------*/
473 /* pic16_initStack - allocate registers for a pseudo stack */
474 /*-----------------------------------------------------------------*/
475 void pic16_initStack(int base_address, int size)
480 pic16_Gstack_base_addr = base_address;
481 //fprintf(stderr,"initStack");
483 for(i = 0; i<size; i++)
484 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
487 /*-----------------------------------------------------------------*
488 *-----------------------------------------------------------------*/
490 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
492 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
494 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
496 reg->wasUsed = 0; // we do not know if they are going to be used at all
497 reg->accessBank = 1; // implicit add access Bank
499 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
501 return addSet(&pic16_dynProcessorRegs, reg);
504 /*-----------------------------------------------------------------*
505 *-----------------------------------------------------------------*/
508 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
510 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
512 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
516 return addSet(&pic16_dynInternalRegs,reg);
523 /*-----------------------------------------------------------------*/
524 /* allocReg - allocates register of given type */
525 /*-----------------------------------------------------------------*/
527 allocReg (short type)
531 #define MAX_P16_NREGS 6
535 if(dynrIdx > pic16_nRegs)
539 /* try to reuse some unused registers */
540 reg = regFindFree( pic16_dynAllocRegs );
543 // fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
547 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
548 // fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
551 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
552 // debugf("allocating more registers than available\n", 0);
557 // addSet(&pic16_dynAllocRegs, reg);
560 addSet(&pic16_dynAllocRegs, reg);
561 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
565 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
568 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
569 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
572 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
573 reg->isLocal = 1; /* this is a local frame register */
578 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
579 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
582 return (reg); // addSet(&pic16_dynAllocRegs,reg);
587 /*-----------------------------------------------------------------*/
588 /* pic16_dirregWithName - search for register by name */
589 /*-----------------------------------------------------------------*/
591 pic16_dirregWithName (char *name)
599 /* hash the name to get a key */
601 hkey = regname2key(name);
603 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
605 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
609 if(STRCASECMP(reg->name, name) == 0) {
610 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
614 reg = hTabNextItemWK (dynDirectRegNames);
618 return NULL; // name wasn't found in the hash table
621 /*-----------------------------------------------------------------*/
622 /* pic16_allocregWithName - search for register by name */
623 /*-----------------------------------------------------------------*/
625 pic16_allocregWithName (char *name)
633 /* hash the name to get a key */
635 hkey = regname2key(name);
637 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
639 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
643 if(STRCASECMP(reg->name, name) == 0) {
647 reg = hTabNextItemWK (dynAllocRegNames);
651 return NULL; // name wasn't found in the hash table
656 /*-----------------------------------------------------------------*/
657 /* pic16_procregWithName - search for register by name */
658 /*-----------------------------------------------------------------*/
660 pic16_procregWithName (char *name)
668 /* hash the name to get a key */
670 hkey = regname2key(name);
672 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
674 reg = hTabFirstItemWK(dynProcRegNames, hkey);
678 if(STRCASECMP(reg->name, name) == 0) {
682 reg = hTabNextItemWK (dynProcRegNames);
686 return NULL; // name wasn't found in the hash table
690 /*-----------------------------------------------------------------*/
691 /* pic16_accessregWithName - search for register by name */
692 /*-----------------------------------------------------------------*/
694 pic16_accessregWithName (char *name)
702 /* hash the name to get a key */
704 hkey = regname2key(name);
706 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
708 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
712 if(STRCASECMP(reg->name, name) == 0) {
716 reg = hTabNextItemWK (dynAccessRegNames);
720 return NULL; // name wasn't found in the hash table
724 regs *pic16_regWithName(char *name)
728 reg = pic16_dirregWithName( name );
731 reg = pic16_procregWithName( name );
734 reg = pic16_allocregWithName( name );
737 reg = pic16_accessregWithName( name );
744 /*-----------------------------------------------------------------*/
745 /* pic16_allocDirReg - allocates register of given type */
746 /*-----------------------------------------------------------------*/
748 pic16_allocDirReg (operand *op )
754 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
755 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
759 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
762 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
764 if(pic16_debug_verbose)
766 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
767 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
773 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
774 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
777 if(pic16_debug_verbose) {
778 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
779 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
780 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
781 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
782 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
783 IN_STACK( OP_SYM_ETYPE(op)),
784 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
785 IS_REGPARM(OP_SYM_ETYPE(op)),
788 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
789 OP_SYMBOL(op)->name);
797 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
798 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
802 if(IS_ITEMP(op))return NULL;
804 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
806 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
808 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
809 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
812 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
813 debugLog(" %d const char\n",__LINE__);
814 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
815 // fprintf(stderr, " %d const char\n",__LINE__);
816 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
820 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
821 if (IS_CODE ( OP_SYM_ETYPE(op)) )
822 debugLog(" %d code space\n",__LINE__);
824 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
825 debugLog(" %d integral\n",__LINE__);
827 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
828 debugLog(" %d literal\n",__LINE__);
830 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
831 debugLog(" %d specifier\n",__LINE__);
833 debugAopGet(NULL, op);
837 reg = pic16_dirregWithName(name);
841 int regtype = REG_GPR;
843 /* if this is at an absolute address, then get the address. */
844 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
845 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
846 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
849 /* Register wasn't found in hash, so let's create
850 * a new one and put it in the hash table AND in the
851 * dynDirectRegNames set */
852 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
853 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
859 if(OP_SYMBOL(op)->onStack) {
860 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
861 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
865 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
866 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
869 if(pic16_debug_verbose)
871 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
872 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
873 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
874 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
875 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
876 IN_STACK( OP_SYM_ETYPE(op)),
877 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
879 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
880 OP_SYMBOL(op)->name);
885 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
886 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
888 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
889 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
893 checkAddReg(&pic16_dynAccessRegs, reg);
894 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
900 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
901 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
902 // reg->type = REG_SFR;
905 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
906 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
907 addSet(&pic16_dynDirectBitRegs, reg);
910 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
911 // addSet(&pic16_dynDirectRegs, reg);
914 if(!(IS_STATIC(OP_SYM_ETYPE(op))
915 && OP_SYMBOL(op)->ival
918 checkAddReg(&pic16_dynDirectRegs, reg);
922 // debugLog (" -- %s is declared at address 0x30000x\n",name);
923 return (reg); /* This was NULL before, but since we found it
924 * why not just return it?! */
927 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
929 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
931 /* work around for user defined registers in access bank */
932 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
933 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
936 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
942 /*-----------------------------------------------------------------*/
943 /* pic16_allocRegByName - allocates register of given type */
944 /*-----------------------------------------------------------------*/
946 pic16_allocRegByName (char *name, int size, operand *op)
952 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
956 /* First, search the hash table to see if there is a register with this name */
957 reg = pic16_dirregWithName(name);
961 /* Register wasn't found in hash, so let's create
962 * a new one and put it in the hash table AND in the
963 * dynDirectRegNames set */
965 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
967 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
969 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
970 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
972 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
973 addSet(&pic16_dynDirectRegs, reg);
979 /*-----------------------------------------------------------------*/
980 /* RegWithIdx - returns pointer to register with index number */
981 /*-----------------------------------------------------------------*/
982 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
987 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
988 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
993 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
995 debugLog ("Found a Dynamic Register!\n");
998 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
999 debugLog ("Found a Direct Register!\n");
1005 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1006 debugLog ("Found a Stack Register!\n");
1011 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1012 debugLog ("Found a Processor Register!\n");
1026 /*-----------------------------------------------------------------*/
1027 /* pic16_regWithIdx - returns pointer to register with index number*/
1028 /*-----------------------------------------------------------------*/
1030 pic16_regWithIdx (int idx)
1034 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1037 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1041 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1048 /*-----------------------------------------------------------------*/
1049 /* pic16_regWithIdx - returns pointer to register with index number */
1050 /*-----------------------------------------------------------------*/
1052 pic16_allocWithIdx (int idx)
1057 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1058 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1060 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1062 debugLog ("Found a Dynamic Register!\n");
1063 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1064 debugLog ("Found a Stack Register!\n");
1065 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1066 debugLog ("Found a Processor Register!\n");
1067 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1068 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1069 debugLog ("Found an Internal Register!\n");
1072 debugLog ("Dynamic Register not found\n");
1075 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1076 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1077 "regWithIdx not found");
1087 /*-----------------------------------------------------------------*/
1088 /*-----------------------------------------------------------------*/
1090 pic16_findFreeReg(short type)
1097 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1099 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1103 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1117 pic16_findFreeRegNext(short type, regs *creg)
1124 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1126 return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1130 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1142 /*-----------------------------------------------------------------*/
1143 /* freeReg - frees a register */
1144 /*-----------------------------------------------------------------*/
1146 freeReg (regs * reg)
1148 debugLog ("%s\n", __FUNCTION__);
1149 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1154 /*-----------------------------------------------------------------*/
1155 /* nFreeRegs - returns number of free registers */
1156 /*-----------------------------------------------------------------*/
1158 nFreeRegs (int type)
1164 /* although I fixed the register allocation/freeing scheme
1165 * the for loop below doesn't give valid results. I do not
1166 * know why yet. -- VR 10-Jan-2003 */
1171 /* dynamically allocate as many as we need and worry about
1172 * fitting them into a PIC later */
1174 debugLog ("%s\n", __FUNCTION__);
1176 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1177 if((reg->type == type) && reg->isFree)nfr++;
1179 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1183 /*-----------------------------------------------------------------*/
1184 /* nfreeRegsType - free registers with type */
1185 /*-----------------------------------------------------------------*/
1187 nfreeRegsType (int type)
1190 debugLog ("%s\n", __FUNCTION__);
1191 if (type == REG_PTR)
1193 if ((nfr = nFreeRegs (type)) == 0)
1194 return nFreeRegs (REG_GPR);
1197 return nFreeRegs (type);
1200 static void writeSetUsedRegs(FILE *of, set *dRegs)
1205 for (dReg = setFirstItem(dRegs) ; dReg ;
1206 dReg = setNextItem(dRegs)) {
1209 fprintf (of, "\t%s\n",dReg->name);
1215 extern void pic16_groupRegistersInSection(set *regset);
1217 extern void pic16_dump_equates(FILE *of, set *equs);
1218 extern void pic16_dump_access(FILE *of, set *section);
1219 //extern void pic16_dump_map(void);
1220 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1221 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1222 extern void pic16_dump_int_registers(FILE *of, set *section);
1223 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1225 extern void pic16_dump_gsection(FILE *of, set *sections);
1227 static void packBits(set *bregs)
1231 regs *bitfield=NULL;
1232 regs *relocbitfield=NULL;
1238 for (regset = bregs ; regset ;
1239 regset = regset->next) {
1241 breg = regset->item;
1242 breg->isBitField = 1;
1243 //fprintf(stderr,"bit reg: %s\n",breg->name);
1246 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1248 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1249 breg->rIdx = breg->address & 7;
1250 breg->address >>= 3;
1253 sprintf (buffer, "fbitfield%02x", breg->address);
1254 //fprintf(stderr,"new bit field\n");
1255 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1256 bitfield->isBitField = 1;
1257 bitfield->isFixed = 1;
1258 bitfield->address = breg->address;
1259 addSet(&pic16_dynDirectRegs,bitfield);
1260 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1262 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1265 breg->reg_alias = bitfield;
1269 if(!relocbitfield || bit_no >7) {
1272 sprintf (buffer, "bitfield%d", byte_no);
1273 //fprintf(stderr,"new relocatable bit field\n");
1274 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1275 relocbitfield->isBitField = 1;
1276 addSet(&pic16_dynDirectRegs,relocbitfield);
1277 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1281 breg->reg_alias = relocbitfield;
1282 breg->address = rDirectIdx; /* byte_no; */
1283 breg->rIdx = bit_no++;
1289 void pic16_writeUsedRegs(FILE *of)
1291 packBits(pic16_dynDirectBitRegs);
1293 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1294 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1295 pic16_groupRegistersInSection(pic16_dynStackRegs);
1296 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1297 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1298 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1299 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1302 pic16_dump_equates(of, pic16_equ_data);
1304 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1305 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1307 /* dump access bank symbols */
1308 pic16_dump_access(of, pic16_acs_udata);
1310 /* dump initialised data */
1311 pic16_dump_isection(of, rel_idataSymSet, 0);
1312 pic16_dump_isection(of, fix_idataSymSet, 1);
1315 /* dump internal registers */
1316 pic16_dump_int_registers(of, pic16_int_regs);
1319 /* dump generic section variables */
1320 pic16_dump_gsection(of, sectNames);
1322 /* dump other variables */
1323 pic16_dump_usection(of, pic16_rel_udata, 0);
1324 pic16_dump_usection(of, pic16_fix_udata, 1);
1328 /*-----------------------------------------------------------------*/
1329 /* computeSpillable - given a point find the spillable live ranges */
1330 /*-----------------------------------------------------------------*/
1332 computeSpillable (iCode * ic)
1336 debugLog ("%s\n", __FUNCTION__);
1337 /* spillable live ranges are those that are live at this
1338 point . the following categories need to be subtracted
1340 a) - those that are already spilt
1341 b) - if being used by this one
1342 c) - defined by this one */
1344 spillable = bitVectCopy (ic->rlive);
1346 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1348 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1349 bitVectUnSetBit (spillable, ic->defKey);
1350 spillable = bitVectIntersect (spillable, _G.regAssigned);
1355 /*-----------------------------------------------------------------*/
1356 /* noSpilLoc - return true if a variable has no spil location */
1357 /*-----------------------------------------------------------------*/
1359 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1361 debugLog ("%s\n", __FUNCTION__);
1362 return (sym->usl.spillLoc ? 0 : 1);
1365 /*-----------------------------------------------------------------*/
1366 /* hasSpilLoc - will return 1 if the symbol has spil location */
1367 /*-----------------------------------------------------------------*/
1369 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1371 debugLog ("%s\n", __FUNCTION__);
1372 return (sym->usl.spillLoc ? 1 : 0);
1375 /*-----------------------------------------------------------------*/
1376 /* directSpilLoc - will return 1 if the splilocation is in direct */
1377 /*-----------------------------------------------------------------*/
1379 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1381 debugLog ("%s\n", __FUNCTION__);
1382 if (sym->usl.spillLoc &&
1383 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1389 /*-----------------------------------------------------------------*/
1390 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1391 /* but is not used as a pointer */
1392 /*-----------------------------------------------------------------*/
1394 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1396 debugLog ("%s\n", __FUNCTION__);
1397 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1400 /*-----------------------------------------------------------------*/
1401 /* rematable - will return 1 if the remat flag is set */
1402 /*-----------------------------------------------------------------*/
1404 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1406 debugLog ("%s\n", __FUNCTION__);
1410 /*-----------------------------------------------------------------*/
1411 /* notUsedInRemaining - not used or defined in remain of the block */
1412 /*-----------------------------------------------------------------*/
1414 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1416 debugLog ("%s\n", __FUNCTION__);
1417 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1418 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1421 /*-----------------------------------------------------------------*/
1422 /* allLRs - return true for all */
1423 /*-----------------------------------------------------------------*/
1425 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1427 debugLog ("%s\n", __FUNCTION__);
1431 /*-----------------------------------------------------------------*/
1432 /* liveRangesWith - applies function to a given set of live range */
1433 /*-----------------------------------------------------------------*/
1435 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1436 eBBlock * ebp, iCode * ic)
1441 debugLog ("%s\n", __FUNCTION__);
1442 if (!lrs || !lrs->size)
1445 for (i = 1; i < lrs->size; i++)
1448 if (!bitVectBitValue (lrs, i))
1451 /* if we don't find it in the live range
1452 hash table we are in serious trouble */
1453 if (!(sym = hTabItemWithKey (liveRanges, i)))
1455 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1456 "liveRangesWith could not find liveRange");
1460 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1461 addSetHead (&rset, sym);
1468 /*-----------------------------------------------------------------*/
1469 /* leastUsedLR - given a set determines which is the least used */
1470 /*-----------------------------------------------------------------*/
1472 leastUsedLR (set * sset)
1474 symbol *sym = NULL, *lsym = NULL;
1476 debugLog ("%s\n", __FUNCTION__);
1477 sym = lsym = setFirstItem (sset);
1482 for (; lsym; lsym = setNextItem (sset))
1485 /* if usage is the same then prefer
1486 the spill the smaller of the two */
1487 if (lsym->used == sym->used)
1488 if (getSize (lsym->type) < getSize (sym->type))
1492 if (lsym->used < sym->used)
1497 setToNull ((void *) &sset);
1502 /*-----------------------------------------------------------------*/
1503 /* noOverLap - will iterate through the list looking for over lap */
1504 /*-----------------------------------------------------------------*/
1506 noOverLap (set * itmpStack, symbol * fsym)
1509 debugLog ("%s\n", __FUNCTION__);
1512 for (sym = setFirstItem (itmpStack); sym;
1513 sym = setNextItem (itmpStack))
1515 if (sym->liveTo > fsym->liveFrom)
1523 /*-----------------------------------------------------------------*/
1524 /* isFree - will return 1 if the a free spil location is found */
1525 /*-----------------------------------------------------------------*/
1530 V_ARG (symbol **, sloc);
1531 V_ARG (symbol *, fsym);
1533 debugLog ("%s\n", __FUNCTION__);
1534 /* if already found */
1538 /* if it is free && and the itmp assigned to
1539 this does not have any overlapping live ranges
1540 with the one currently being assigned and
1541 the size can be accomodated */
1543 noOverLap (sym->usl.itmpStack, fsym) &&
1544 getSize (sym->type) >= getSize (fsym->type))
1553 /*-----------------------------------------------------------------*/
1554 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1555 /*-----------------------------------------------------------------*/
1557 spillLRWithPtrReg (symbol * forSym)
1563 debugLog ("%s\n", __FUNCTION__);
1564 if (!_G.regAssigned ||
1565 bitVectIsZero (_G.regAssigned))
1568 r0 = pic16_regWithIdx (R0_IDX);
1569 r1 = pic16_regWithIdx (R1_IDX);
1571 /* for all live ranges */
1572 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1573 lrsym = hTabNextItem (liveRanges, &k))
1577 /* if no registers assigned to it or
1579 /* if it does not overlap with this then
1580 not need to spill it */
1582 if (lrsym->isspilt || !lrsym->nRegs ||
1583 (lrsym->liveTo < forSym->liveFrom))
1586 /* go thru the registers : if it is either
1587 r0 or r1 then spil it */
1588 for (j = 0; j < lrsym->nRegs; j++)
1589 if (lrsym->regs[j] == r0 ||
1590 lrsym->regs[j] == r1)
1599 /*-----------------------------------------------------------------*/
1600 /* createStackSpil - create a location on the stack to spil */
1601 /*-----------------------------------------------------------------*/
1603 createStackSpil (symbol * sym)
1605 symbol *sloc = NULL;
1606 int useXstack, model, noOverlay;
1608 char slocBuffer[30];
1609 debugLog ("%s\n", __FUNCTION__);
1611 /* first go try and find a free one that is already
1612 existing on the stack */
1613 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1615 /* found a free one : just update & return */
1616 sym->usl.spillLoc = sloc;
1619 addSetHead (&sloc->usl.itmpStack, sym);
1623 /* could not then have to create one , this is the hard part
1624 we need to allocate this on the stack : this is really a
1625 hack!! but cannot think of anything better at this time */
1627 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1629 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1630 __FILE__, __LINE__);
1634 sloc = newiTemp (slocBuffer);
1636 /* set the type to the spilling symbol */
1637 sloc->type = copyLinkChain (sym->type);
1638 sloc->etype = getSpec (sloc->type);
1639 SPEC_SCLS (sloc->etype) = S_DATA;
1640 SPEC_EXTR (sloc->etype) = 0;
1641 SPEC_STAT (sloc->etype) = 0;
1643 /* we don't allow it to be allocated`
1644 onto the external stack since : so we
1645 temporarily turn it off ; we also
1646 turn off memory model to prevent
1647 the spil from going to the external storage
1648 and turn off overlaying
1651 useXstack = options.useXstack;
1652 model = options.model;
1653 noOverlay = options.noOverlay;
1654 options.noOverlay = 1;
1655 options.model = options.useXstack = 0;
1659 options.useXstack = useXstack;
1660 options.model = model;
1661 options.noOverlay = noOverlay;
1662 sloc->isref = 1; /* to prevent compiler warning */
1664 /* if it is on the stack then update the stack */
1665 if (IN_STACK (sloc->etype))
1667 currFunc->stack += getSize (sloc->type);
1668 _G.stackExtend += getSize (sloc->type);
1671 _G.dataExtend += getSize (sloc->type);
1673 /* add it to the _G.stackSpil set */
1674 addSetHead (&_G.stackSpil, sloc);
1675 sym->usl.spillLoc = sloc;
1678 /* add it to the set of itempStack set
1679 of the spill location */
1680 addSetHead (&sloc->usl.itmpStack, sym);
1684 /*-----------------------------------------------------------------*/
1685 /* isSpiltOnStack - returns true if the spil location is on stack */
1686 /*-----------------------------------------------------------------*/
1688 isSpiltOnStack (symbol * sym)
1692 debugLog ("%s\n", __FUNCTION__);
1699 /* if (sym->_G.stackSpil) */
1702 if (!sym->usl.spillLoc)
1705 etype = getSpec (sym->usl.spillLoc->type);
1706 if (IN_STACK (etype))
1712 /*-----------------------------------------------------------------*/
1713 /* spillThis - spils a specific operand */
1714 /*-----------------------------------------------------------------*/
1716 spillThis (symbol * sym)
1719 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1721 /* if this is rematerializable or has a spillLocation
1722 we are okay, else we need to create a spillLocation
1724 if (!(sym->remat || sym->usl.spillLoc))
1725 createStackSpil (sym);
1728 /* mark it has spilt & put it in the spilt set */
1730 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1732 bitVectUnSetBit (_G.regAssigned, sym->key);
1734 for (i = 0; i < sym->nRegs; i++)
1738 freeReg (sym->regs[i]);
1739 sym->regs[i] = NULL;
1742 /* if spilt on stack then free up r0 & r1
1743 if they could have been assigned to some
1745 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1748 spillLRWithPtrReg (sym);
1751 if (sym->usl.spillLoc && !sym->remat)
1752 sym->usl.spillLoc->allocreq = 1;
1756 /*-----------------------------------------------------------------*/
1757 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1758 /*-----------------------------------------------------------------*/
1760 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1762 bitVect *lrcs = NULL;
1766 debugLog ("%s\n", __FUNCTION__);
1767 /* get the spillable live ranges */
1768 lrcs = computeSpillable (ic);
1770 /* get all live ranges that are rematerizable */
1771 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1774 /* return the least used of these */
1775 return leastUsedLR (selectS);
1778 /* get live ranges with spillLocations in direct space */
1779 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1781 sym = leastUsedLR (selectS);
1782 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1783 sym->usl.spillLoc->rname :
1784 sym->usl.spillLoc->name));
1786 /* mark it as allocation required */
1787 sym->usl.spillLoc->allocreq = 1;
1791 /* if the symbol is local to the block then */
1792 if (forSym->liveTo < ebp->lSeq)
1795 /* check if there are any live ranges allocated
1796 to registers that are not used in this block */
1797 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1799 sym = leastUsedLR (selectS);
1800 /* if this is not rematerializable */
1809 /* check if there are any live ranges that not
1810 used in the remainder of the block */
1811 if (!_G.blockSpil &&
1812 !isiCodeInFunctionCall (ic) &&
1813 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1815 sym = leastUsedLR (selectS);
1818 sym->remainSpil = 1;
1825 /* find live ranges with spillocation && not used as pointers */
1826 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1829 sym = leastUsedLR (selectS);
1830 /* mark this as allocation required */
1831 sym->usl.spillLoc->allocreq = 1;
1835 /* find live ranges with spillocation */
1836 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1839 sym = leastUsedLR (selectS);
1840 sym->usl.spillLoc->allocreq = 1;
1844 /* couldn't find then we need to create a spil
1845 location on the stack , for which one? the least
1847 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1850 /* return a created spil location */
1851 sym = createStackSpil (leastUsedLR (selectS));
1852 sym->usl.spillLoc->allocreq = 1;
1856 /* this is an extreme situation we will spill
1857 this one : happens very rarely but it does happen */
1863 /*-----------------------------------------------------------------*/
1864 /* spilSomething - spil some variable & mark registers as free */
1865 /*-----------------------------------------------------------------*/
1867 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1872 debugLog ("%s\n", __FUNCTION__);
1873 /* get something we can spil */
1874 ssym = selectSpil (ic, ebp, forSym);
1876 /* mark it as spilt */
1878 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1880 /* mark it as not register assigned &
1881 take it away from the set */
1882 bitVectUnSetBit (_G.regAssigned, ssym->key);
1884 /* mark the registers as free */
1885 for (i = 0; i < ssym->nRegs; i++)
1887 freeReg (ssym->regs[i]);
1889 /* if spilt on stack then free up r0 & r1
1890 if they could have been assigned to as gprs */
1891 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1894 spillLRWithPtrReg (ssym);
1897 /* if this was a block level spil then insert push & pop
1898 at the start & end of block respectively */
1899 if (ssym->blockSpil)
1901 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1902 /* add push to the start of the block */
1903 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1904 ebp->sch->next : ebp->sch));
1905 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1906 /* add pop to the end of the block */
1907 addiCodeToeBBlock (ebp, nic, NULL);
1910 /* if spilt because not used in the remainder of the
1911 block then add a push before this instruction and
1912 a pop at the end of the block */
1913 if (ssym->remainSpil)
1916 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1917 /* add push just before this instruction */
1918 addiCodeToeBBlock (ebp, nic, ic);
1920 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1921 /* add pop to the end of the block */
1922 addiCodeToeBBlock (ebp, nic, NULL);
1931 /*-----------------------------------------------------------------*/
1932 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1933 /*-----------------------------------------------------------------*/
1935 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1940 debugLog ("%s\n", __FUNCTION__);
1942 /* try for a ptr type */
1943 if ((reg = allocReg (REG_PTR)))
1946 /* try for gpr type */
1947 if ((reg = allocReg (REG_GPR)))
1950 /* we have to spil */
1951 if (!spilSomething (ic, ebp, sym))
1954 /* make sure partially assigned registers aren't reused */
1955 for (j=0; j<=sym->nRegs; j++)
1957 sym->regs[j]->isFree = 0;
1959 /* this looks like an infinite loop but
1960 in really selectSpil will abort */
1964 /*-----------------------------------------------------------------*/
1965 /* getRegGpr - will try for GPR if not spil */
1966 /*-----------------------------------------------------------------*/
1968 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1973 debugLog ("%s\n", __FUNCTION__);
1975 /* try for gpr type */
1976 if ((reg = allocReg (REG_GPR)))
1979 if (!pic16_ptrRegReq)
1980 if ((reg = allocReg (REG_PTR)))
1983 /* we have to spil */
1984 if (!spilSomething (ic, ebp, sym))
1987 /* make sure partially assigned registers aren't reused */
1988 for (j=0; j<=sym->nRegs; j++)
1990 sym->regs[j]->isFree = 0;
1992 /* this looks like an infinite loop but
1993 in really selectSpil will abort */
1997 /*-----------------------------------------------------------------*/
1998 /* symHasReg - symbol has a given register */
1999 /*-----------------------------------------------------------------*/
2001 symHasReg (symbol * sym, regs * reg)
2005 debugLog ("%s\n", __FUNCTION__);
2006 for (i = 0; i < sym->nRegs; i++)
2007 if (sym->regs[i] == reg)
2013 /*-----------------------------------------------------------------*/
2014 /* deassignLRs - check the live to and if they have registers & are */
2015 /* not spilt then free up the registers */
2016 /*-----------------------------------------------------------------*/
2018 deassignLRs (iCode * ic, eBBlock * ebp)
2024 debugLog ("%s\n", __FUNCTION__);
2025 for (sym = hTabFirstItem (liveRanges, &k); sym;
2026 sym = hTabNextItem (liveRanges, &k))
2029 symbol *psym = NULL;
2030 /* if it does not end here */
2031 if (sym->liveTo > ic->seq)
2034 /* if it was spilt on stack then we can
2035 mark the stack spil location as free */
2040 sym->usl.spillLoc->isFree = 1;
2046 if (!bitVectBitValue (_G.regAssigned, sym->key))
2049 /* special case for shifting: there is a case where shift count
2050 * can be allocated in the same register as the result, so do not
2051 * free right registers if same as result registers, cause genShiftLeft
2052 * will fail -- VR */
2053 if(ic->op == LEFT_OP)
2056 /* special case check if this is an IFX &
2057 the privious one was a pop and the
2058 previous one was not spilt then keep track
2060 if (ic->op == IFX && ic->prev &&
2061 ic->prev->op == IPOP &&
2062 !ic->prev->parmPush &&
2063 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2064 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2070 bitVectUnSetBit (_G.regAssigned, sym->key);
2072 /* if the result of this one needs registers
2073 and does not have it then assign it right
2075 if (IC_RESULT (ic) &&
2076 !(SKIP_IC2 (ic) || /* not a special icode */
2077 ic->op == JUMPTABLE ||
2082 POINTER_SET (ic)) &&
2083 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2084 result->liveTo > ic->seq && /* and will live beyond this */
2085 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2086 result->liveFrom == ic->seq && /* does not start before here */
2087 result->regType == sym->regType && /* same register types */
2088 result->nRegs && /* which needs registers */
2089 !result->isspilt && /* and does not already have them */
2091 !bitVectBitValue (_G.regAssigned, result->key) &&
2092 /* the number of free regs + number of regs in this LR
2093 can accomodate the what result Needs */
2094 ((nfreeRegsType (result->regType) +
2095 sym->nRegs) >= result->nRegs)
2100 // for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2101 /* the above does not free the unsued registers in sym,
2102 * leaving them marked as used, and increasing register usage
2103 * until the end of the function - VR 23/11/05 */
2105 for (i = 0; i < result->nRegs; i++)
2107 result->regs[i] = sym->regs[i];
2109 result->regs[i] = getRegGpr (ic, ebp, result);
2111 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2114 /* free the remaining */
2115 for (; i < sym->nRegs; i++)
2119 if (!symHasReg (psym, sym->regs[i]))
2120 freeReg (sym->regs[i]);
2123 freeReg (sym->regs[i]);
2130 /*-----------------------------------------------------------------*/
2131 /* reassignLR - reassign this to registers */
2132 /*-----------------------------------------------------------------*/
2134 reassignLR (operand * op)
2136 symbol *sym = OP_SYMBOL (op);
2139 debugLog ("%s\n", __FUNCTION__);
2140 /* not spilt any more */
2141 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2142 bitVectUnSetBit (_G.spiltSet, sym->key);
2144 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2148 for (i = 0; i < sym->nRegs; i++)
2149 sym->regs[i]->isFree = 0;
2152 /*-----------------------------------------------------------------*/
2153 /* willCauseSpill - determines if allocating will cause a spill */
2154 /*-----------------------------------------------------------------*/
2156 willCauseSpill (int nr, int rt)
2158 debugLog ("%s\n", __FUNCTION__);
2159 /* first check if there are any avlb registers
2160 of te type required */
2163 /* special case for pointer type
2164 if pointer type not avlb then
2165 check for type gpr */
2166 if (nFreeRegs (rt) >= nr)
2168 if (nFreeRegs (REG_GPR) >= nr)
2173 if (pic16_ptrRegReq)
2175 if (nFreeRegs (rt) >= nr)
2180 if (nFreeRegs (REG_PTR) +
2181 nFreeRegs (REG_GPR) >= nr)
2186 debugLog (" ... yep it will (cause a spill)\n");
2187 /* it will cause a spil */
2191 /*-----------------------------------------------------------------*/
2192 /* positionRegs - the allocator can allocate same registers to res- */
2193 /* ult and operand, if this happens make sure they are in the same */
2194 /* position as the operand otherwise chaos results */
2195 /*-----------------------------------------------------------------*/
2197 positionRegs (symbol * result, symbol * opsym, int lineno)
2199 int count = min (result->nRegs, opsym->nRegs);
2200 int i, j = 0, shared = 0;
2202 debugLog ("%s\n", __FUNCTION__);
2203 /* if the result has been spilt then cannot share */
2208 /* first make sure that they actually share */
2209 for (i = 0; i < count; i++)
2211 for (j = 0; j < count; j++)
2213 if (result->regs[i] == opsym->regs[j] && i != j)
2223 regs *tmp = result->regs[i];
2224 result->regs[i] = result->regs[j];
2225 result->regs[j] = tmp;
2230 /*------------------------------------------------------------------*/
2231 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2232 /* it should either have registers or have beed spilled. Otherwise, */
2233 /* there was an uninitialized variable, so just spill this to get */
2234 /* the operand in a valid state. */
2235 /*------------------------------------------------------------------*/
2237 verifyRegsAssigned (operand *op, iCode * ic)
2242 if (!IS_ITEMP (op)) return;
2244 sym = OP_SYMBOL (op);
2245 if (sym->isspilt) return;
2246 if (!sym->nRegs) return;
2247 if (sym->regs[0]) return;
2249 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2250 sym->prereqv ? sym->prereqv->name : sym->name);
2255 /*-----------------------------------------------------------------*/
2256 /* serialRegAssign - serially allocate registers to the variables */
2257 /*-----------------------------------------------------------------*/
2259 serialRegAssign (eBBlock ** ebbs, int count)
2264 debugLog ("%s\n", __FUNCTION__);
2265 /* for all blocks */
2266 for (i = 0; i < count; i++)
2268 if (ebbs[i]->noPath &&
2269 (ebbs[i]->entryLabel != entryLabel &&
2270 ebbs[i]->entryLabel != returnLabel))
2273 /* of all instructions do */
2274 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2277 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2279 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2280 pic16_allocDirReg(IC_RESULT(ic));
2282 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2283 pic16_allocDirReg(IC_LEFT(ic));
2285 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2286 pic16_allocDirReg(IC_RIGHT(ic));
2288 /* if this is an ipop that means some live
2289 range will have to be assigned again */
2291 reassignLR (IC_LEFT (ic));
2293 /* if result is present && is a true symbol */
2294 if (IC_RESULT (ic) && ic->op != IFX &&
2295 IS_TRUE_SYMOP (IC_RESULT (ic)))
2296 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2298 /* take away registers from live
2299 ranges that end at this instruction */
2300 deassignLRs (ic, ebbs[i]);
2302 /* some don't need registers */
2303 if (SKIP_IC2 (ic) ||
2304 ic->op == JUMPTABLE ||
2308 (IC_RESULT (ic) && POINTER_SET (ic)))
2311 /* now we need to allocate registers
2312 only for the result */
2315 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2321 /* Make sure any spill location is definately allocated */
2322 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2323 !sym->usl.spillLoc->allocreq)
2325 sym->usl.spillLoc->allocreq++;
2328 /* if it does not need or is spilt
2329 or is already assigned to registers
2330 or will not live beyond this instructions */
2333 bitVectBitValue (_G.regAssigned, sym->key) ||
2334 sym->liveTo <= ic->seq)
2337 /* if some liverange has been spilt at the block level
2338 and this one live beyond this block then spil this
2340 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2345 /* if trying to allocate this will cause
2346 a spill and there is nothing to spill
2347 or this one is rematerializable then
2349 willCS = willCauseSpill (sym->nRegs, sym->regType);
2351 /* explicit turn off register spilling */
2354 spillable = computeSpillable (ic);
2356 (willCS && bitVectIsZero (spillable)))
2364 /* If the live range preceeds the point of definition
2365 then ideally we must take into account registers that
2366 have been allocated after sym->liveFrom but freed
2367 before ic->seq. This is complicated, so spill this
2368 symbol instead and let fillGaps handle the allocation. */
2370 if (sym->liveFrom < ic->seq)
2376 /* if it has a spillocation & is used less than
2377 all other live ranges then spill this */
2379 if (sym->usl.spillLoc) {
2380 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2381 allLRs, ebbs[i], ic));
2382 if (leastUsed && leastUsed->used > sym->used) {
2387 /* if none of the liveRanges have a spillLocation then better
2388 to spill this one than anything else already assigned to registers */
2389 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2390 /* if this is local to this block then we might find a block spil */
2391 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2399 if (ic->op == RECEIVE)
2400 debugLog ("When I get clever, I'll optimize the receive logic\n");
2402 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2403 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2404 && (ic->next->op == IFX)
2405 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2407 /* skip register allocation since none will be used */
2408 for(j=0;j<sym->nRegs;j++)
2409 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2410 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2415 /* if we need ptr regs for the right side
2417 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2418 <= (unsigned) PTRSIZE)
2423 /* else we assign registers to it */
2424 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2427 bitVectDebugOn(_G.regAssigned, debugF);
2429 for (j = 0; j < sym->nRegs; j++)
2431 if (sym->regType == REG_PTR)
2432 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2434 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2436 /* if the allocation falied which means
2437 this was spilt then break */
2441 debugLog (" %d - \n", __LINE__);
2443 /* if it shares registers with operands make sure
2444 that they are in the same position */
2445 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2446 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2447 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2448 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2449 /* do the same for the right operand */
2450 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2451 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2452 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2453 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2455 debugLog (" %d - \n", __LINE__);
2458 debugLog (" %d - \n", __LINE__);
2467 /* Check for and fix any problems with uninitialized operands */
2468 for (i = 0; i < count; i++)
2472 if (ebbs[i]->noPath &&
2473 (ebbs[i]->entryLabel != entryLabel &&
2474 ebbs[i]->entryLabel != returnLabel))
2477 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2484 verifyRegsAssigned (IC_COND (ic), ic);
2488 if (ic->op == JUMPTABLE)
2490 verifyRegsAssigned (IC_JTCOND (ic), ic);
2494 verifyRegsAssigned (IC_RESULT (ic), ic);
2495 verifyRegsAssigned (IC_LEFT (ic), ic);
2496 verifyRegsAssigned (IC_RIGHT (ic), ic);
2502 /*-----------------------------------------------------------------*/
2503 /* rUmaskForOp :- returns register mask for an operand */
2504 /*-----------------------------------------------------------------*/
2506 rUmaskForOp (operand * op)
2512 debugLog ("%s\n", __FUNCTION__);
2513 /* only temporaries are assigned registers */
2517 sym = OP_SYMBOL (op);
2519 /* if spilt or no registers assigned to it
2521 if (sym->isspilt || !sym->nRegs)
2524 rumask = newBitVect (pic16_nRegs);
2526 for (j = 0; j < sym->nRegs; j++)
2528 rumask = bitVectSetBit (rumask,
2529 sym->regs[j]->rIdx);
2535 /*-----------------------------------------------------------------*/
2536 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2537 /*-----------------------------------------------------------------*/
2539 regsUsedIniCode (iCode * ic)
2541 bitVect *rmask = newBitVect (pic16_nRegs);
2543 debugLog ("%s\n", __FUNCTION__);
2544 /* do the special cases first */
2547 rmask = bitVectUnion (rmask,
2548 rUmaskForOp (IC_COND (ic)));
2552 /* for the jumptable */
2553 if (ic->op == JUMPTABLE)
2555 rmask = bitVectUnion (rmask,
2556 rUmaskForOp (IC_JTCOND (ic)));
2561 /* of all other cases */
2563 rmask = bitVectUnion (rmask,
2564 rUmaskForOp (IC_LEFT (ic)));
2568 rmask = bitVectUnion (rmask,
2569 rUmaskForOp (IC_RIGHT (ic)));
2572 rmask = bitVectUnion (rmask,
2573 rUmaskForOp (IC_RESULT (ic)));
2579 /*-----------------------------------------------------------------*/
2580 /* createRegMask - for each instruction will determine the regsUsed */
2581 /*-----------------------------------------------------------------*/
2583 createRegMask (eBBlock ** ebbs, int count)
2587 debugLog ("%s\n", __FUNCTION__);
2588 /* for all blocks */
2589 for (i = 0; i < count; i++)
2593 if (ebbs[i]->noPath &&
2594 (ebbs[i]->entryLabel != entryLabel &&
2595 ebbs[i]->entryLabel != returnLabel))
2598 /* for all instructions */
2599 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2604 if (SKIP_IC2 (ic) || !ic->rlive)
2607 /* first mark the registers used in this
2609 ic->rUsed = regsUsedIniCode (ic);
2610 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2612 /* now create the register mask for those
2613 registers that are in use : this is a
2614 super set of ic->rUsed */
2615 ic->rMask = newBitVect (pic16_nRegs + 1);
2617 /* for all live Ranges alive at this point */
2618 for (j = 1; j < ic->rlive->size; j++)
2623 /* if not alive then continue */
2624 if (!bitVectBitValue (ic->rlive, j))
2627 /* find the live range we are interested in */
2628 if (!(sym = hTabItemWithKey (liveRanges, j)))
2630 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2631 "createRegMask cannot find live range");
2635 /* if no register assigned to it */
2636 if (!sym->nRegs || sym->isspilt)
2639 /* for all the registers allocated to it */
2640 for (k = 0; k < sym->nRegs; k++)
2643 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2649 /*-----------------------------------------------------------------*/
2650 /* rematStr - returns the rematerialized string for a remat var */
2651 /*-----------------------------------------------------------------*/
2653 rematStr (symbol * sym)
2656 iCode *ic = sym->rematiCode;
2657 symbol *psym = NULL;
2659 debugLog ("%s\n", __FUNCTION__);
2661 //printf ("%s\n", s);
2663 /* if plus or minus print the right hand side */
2665 if (ic->op == '+' || ic->op == '-') {
2667 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2669 sprintf (s, "(%s %c 0x%04x)",
2670 OP_SYMBOL (IC_LEFT (ric))->rname,
2672 (int) operandLitValue (IC_RIGHT (ic)));
2675 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2677 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2678 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2683 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2684 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2686 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2691 /*-----------------------------------------------------------------*/
2692 /* rematStr - returns the rematerialized string for a remat var */
2693 /*-----------------------------------------------------------------*/
2695 rematStr (symbol * sym)
2698 iCode *ic = sym->rematiCode;
2700 debugLog ("%s\n", __FUNCTION__);
2705 /* if plus or minus print the right hand side */
2707 if (ic->op == '+' || ic->op == '-') {
2708 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2711 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2715 if (ic->op == '+' || ic->op == '-')
2717 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2718 sprintf (s, "(%s %c 0x%04x)",
2719 OP_SYMBOL (IC_LEFT (ric))->rname,
2721 (int) operandLitValue (IC_RIGHT (ic)));
2724 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2726 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2730 /* we reached the end */
2731 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2735 printf ("%s\n", buffer);
2740 /*-----------------------------------------------------------------*/
2741 /* regTypeNum - computes the type & number of registers required */
2742 /*-----------------------------------------------------------------*/
2750 debugLog ("%s\n", __FUNCTION__);
2751 /* for each live range do */
2752 for (sym = hTabFirstItem (liveRanges, &k); sym;
2753 sym = hTabNextItem (liveRanges, &k)) {
2755 debugLog (" %d - %s\n", __LINE__, sym->rname);
2756 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2758 /* if used zero times then no registers needed */
2759 if ((sym->liveTo - sym->liveFrom) == 0)
2763 /* if the live range is a temporary */
2766 debugLog (" %d - itemp register\n", __LINE__);
2768 /* if the type is marked as a conditional */
2769 if (sym->regType == REG_CND)
2772 /* if used in return only then we don't
2774 if (sym->ruonly || sym->accuse) {
2775 if (IS_AGGREGATE (sym->type) || sym->isptr)
2776 sym->type = aggrToPtr (sym->type, FALSE);
2777 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2781 /* if the symbol has only one definition &
2782 that definition is a get_pointer and the
2783 pointer we are getting is rematerializable and
2786 if (bitVectnBitsOn (sym->defs) == 1 &&
2787 (ic = hTabItemWithKey (iCodehTab,
2788 bitVectFirstBit (sym->defs))) &&
2790 !IS_BITVAR (sym->etype) &&
2791 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2793 // continue; /* FIXME -- VR */
2794 if (ptrPseudoSymSafe (sym, ic)) {
2798 debugLog (" %d - \n", __LINE__);
2800 /* create a psuedo symbol & force a spil */
2801 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2802 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2803 psym->type = sym->type;
2804 psym->etype = sym->etype;
2805 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2806 strcpy (psym->rname, psym->name);
2808 sym->usl.spillLoc = psym;
2812 /* if in data space or idata space then try to
2813 allocate pointer register */
2817 /* if not then we require registers */
2818 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2819 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2820 getSize (sym->type));
2824 if(IS_PTR_CONST (sym->type)) {
2826 if(IS_CODEPTR (sym->type)) {
2828 // what IS this ???? (HJD)
2829 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2830 sym->nRegs = 3; // patch 14
2833 if (sym->nRegs > 4) {
2834 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2835 printTypeChain (sym->type, stderr);
2836 fprintf (stderr, "\n");
2839 /* determine the type of register required */
2840 if (sym->nRegs == 1 &&
2841 IS_PTR (sym->type) &&
2843 sym->regType = REG_PTR;
2845 sym->regType = REG_GPR;
2848 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2852 /* for the first run we don't provide */
2853 /* registers for true symbols we will */
2854 /* see how things go */
2860 static DEFSETFUNC (markRegFree)
2862 ((regs *)item)->isFree = 1;
2867 DEFSETFUNC (pic16_deallocReg)
2869 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2870 ((regs *)item)->isFree = 1;
2871 ((regs *)item)->wasUsed = 0;
2875 /*-----------------------------------------------------------------*/
2876 /* freeAllRegs - mark all registers as free */
2877 /*-----------------------------------------------------------------*/
2879 pic16_freeAllRegs ()
2881 debugLog ("%s\n", __FUNCTION__);
2883 applyToSet(pic16_dynAllocRegs,markRegFree);
2884 applyToSet(pic16_dynStackRegs,markRegFree);
2887 /*-----------------------------------------------------------------*/
2888 /*-----------------------------------------------------------------*/
2890 pic16_deallocateAllRegs ()
2892 debugLog ("%s\n", __FUNCTION__);
2894 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2898 /*-----------------------------------------------------------------*/
2899 /* deallocStackSpil - this will set the stack pointer back */
2900 /*-----------------------------------------------------------------*/
2902 DEFSETFUNC (deallocStackSpil)
2906 debugLog ("%s\n", __FUNCTION__);
2911 /*-----------------------------------------------------------------*/
2912 /* farSpacePackable - returns the packable icode for far variables */
2913 /*-----------------------------------------------------------------*/
2915 farSpacePackable (iCode * ic)
2919 debugLog ("%s\n", __FUNCTION__);
2920 /* go thru till we find a definition for the
2921 symbol on the right */
2922 for (dic = ic->prev; dic; dic = dic->prev)
2925 /* if the definition is a call then no */
2926 if ((dic->op == CALL || dic->op == PCALL) &&
2927 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2932 /* if shift by unknown amount then not */
2933 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2934 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2937 /* if pointer get and size > 1 */
2938 if (POINTER_GET (dic) &&
2939 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2942 if (POINTER_SET (dic) &&
2943 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2946 /* if any three is a true symbol in far space */
2947 if (IC_RESULT (dic) &&
2948 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2949 isOperandInFarSpace (IC_RESULT (dic)))
2952 if (IC_RIGHT (dic) &&
2953 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2954 isOperandInFarSpace (IC_RIGHT (dic)) &&
2955 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2958 if (IC_LEFT (dic) &&
2959 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2960 isOperandInFarSpace (IC_LEFT (dic)) &&
2961 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2964 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2966 if ((dic->op == LEFT_OP ||
2967 dic->op == RIGHT_OP ||
2969 IS_OP_LITERAL (IC_RIGHT (dic)))
2980 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
2984 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2985 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
2986 debugAopGet (" result:", IC_RESULT (ic));
2987 debugAopGet (" left:", IC_LEFT (ic));
2988 debugAopGet (" right:", IC_RIGHT (ic));
2997 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
2999 /*-----------------------------------------------------------------*/
3000 /* packRegsForAssign - register reduction for assignment */
3001 /*-----------------------------------------------------------------*/
3003 packRegsForAssign (iCode * ic, eBBlock * ebp)
3007 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3008 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3009 debugAopGet (" result:", IC_RESULT (ic));
3010 debugAopGet (" left:", IC_LEFT (ic));
3011 debugAopGet (" right:", IC_RIGHT (ic));
3013 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3015 debugLog(" %d - actuall processing\n", __LINE__ );
3017 if (!IS_ITEMP (IC_RESULT (ic))) {
3018 pic16_allocDirReg(IC_RESULT (ic));
3019 debugLog (" %d - result is not temp\n", __LINE__);
3022 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3024 /* See BUGLOG0001 - VR */
3026 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3027 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3028 pic16_allocDirReg(IC_RIGHT (ic));
3033 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3034 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3036 debugLog (" %d - not packing - right side fails \n", __LINE__);
3040 /* if the true symbol is defined in far space or on stack
3041 then we should not since this will increase register pressure */
3042 if (isOperandInFarSpace (IC_RESULT (ic)))
3044 if ((dic = farSpacePackable (ic)))
3051 /* find the definition of iTempNN scanning backwards if we find a
3052 a use of the true symbol before we find the definition then
3054 for (dic = ic->prev; dic; dic = dic->prev)
3057 /* if there is a function call and this is
3058 a parameter & not my parameter then don't pack it */
3059 if ((dic->op == CALL || dic->op == PCALL) &&
3060 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3061 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3063 debugLog (" %d - \n", __LINE__);
3072 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3074 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3075 IS_OP_VOLATILE (IC_RESULT (dic)))
3077 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3083 if( IS_SYMOP( IC_RESULT(dic)) &&
3084 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3086 debugLog (" %d - result is bitfield\n", __LINE__);
3092 if (IS_SYMOP (IC_RESULT (dic)) &&
3093 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3095 /* A previous result was assigned to the same register - we'll our definition */
3096 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3097 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3098 if (POINTER_SET (dic))
3104 if (IS_SYMOP (IC_RIGHT (dic)) &&
3105 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3106 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3108 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3113 if (IS_SYMOP (IC_LEFT (dic)) &&
3114 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3115 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3117 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3122 if (POINTER_SET (dic) &&
3123 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3125 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3133 return 0; /* did not find */
3136 /* This code is taken from the hc08 port. Do not know
3137 * if it fits for pic16, but I leave it here just in case */
3139 /* if assignment then check that right is not a bit */
3140 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3141 sym_link *etype = operandType (IC_RIGHT (dic));
3143 if (IS_BITFIELD (etype)) {
3144 /* if result is a bit too then it's ok */
3145 etype = operandType (IC_RESULT (dic));
3146 if (!IS_BITFIELD (etype)) {
3147 debugLog(" %d bitfields\n");
3154 /* if the result is on stack or iaccess then it must be
3155 the same atleast one of the operands */
3156 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3157 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3159 /* the operation has only one symbol
3160 operator then we can pack */
3161 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3162 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3165 if (!((IC_LEFT (dic) &&
3166 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3168 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3172 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3173 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3174 /* found the definition */
3175 /* replace the result with the result of */
3176 /* this assignment and remove this assignment */
3179 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3180 IC_RESULT (dic) = IC_RESULT (ic);
3182 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3184 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3186 /* delete from liverange table also
3187 delete from all the points inbetween and the new
3189 for (sic = dic; sic != ic; sic = sic->next)
3191 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3192 if (IS_ITEMP (IC_RESULT (dic)))
3193 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3196 remiCodeFromeBBlock (ebp, ic);
3197 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3199 debugLog(" %d\n", __LINE__ );
3200 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3201 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3208 #define NO_packRegsForAccUse
3209 #define NO_packRegsForSupport
3210 #define NO_packRegsForOneuse
3211 #define NO_cast_peep
3216 #ifndef NO_packRegsForSupport
3217 /*-----------------------------------------------------------------*/
3218 /* findAssignToSym : scanning backwards looks for first assig found */
3219 /*-----------------------------------------------------------------*/
3221 findAssignToSym (operand * op, iCode * ic)
3225 debugLog ("%s\n", __FUNCTION__);
3226 for (dic = ic->prev; dic; dic = dic->prev)
3229 /* if definition by assignment */
3230 if (dic->op == '=' &&
3231 !POINTER_SET (dic) &&
3232 IC_RESULT (dic)->key == op->key
3233 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3237 /* we are interested only if defined in far space */
3238 /* or in stack space in case of + & - */
3240 /* if assigned to a non-symbol then return
3242 if (!IS_SYMOP (IC_RIGHT (dic)))
3245 /* if the symbol is in far space then
3247 if (isOperandInFarSpace (IC_RIGHT (dic)))
3250 /* for + & - operations make sure that
3251 if it is on the stack it is the same
3252 as one of the three operands */
3253 if ((ic->op == '+' || ic->op == '-') &&
3254 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3256 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3257 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3258 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3266 /* if we find an usage then we cannot delete it */
3267 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3270 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3273 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3277 /* now make sure that the right side of dic
3278 is not defined between ic & dic */
3281 iCode *sic = dic->next;
3283 for (; sic != ic; sic = sic->next)
3284 if (IC_RESULT (sic) &&
3285 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3296 #ifndef NO_packRegsForSupport
3297 /*-----------------------------------------------------------------*/
3298 /* packRegsForSupport :- reduce some registers for support calls */
3299 /*-----------------------------------------------------------------*/
3301 packRegsForSupport (iCode * ic, eBBlock * ebp)
3305 debugLog ("%s\n", __FUNCTION__);
3306 /* for the left & right operand :- look to see if the
3307 left was assigned a true symbol in far space in that
3308 case replace them */
3309 if (IS_ITEMP (IC_LEFT (ic)) &&
3310 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3312 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3318 debugAopGet ("removing left:", IC_LEFT (ic));
3320 /* found it we need to remove it from the
3322 for (sic = dic; sic != ic; sic = sic->next)
3323 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3325 IC_LEFT (ic)->operand.symOperand =
3326 IC_RIGHT (dic)->operand.symOperand;
3327 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3328 remiCodeFromeBBlock (ebp, dic);
3329 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3330 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3334 /* do the same for the right operand */
3337 IS_ITEMP (IC_RIGHT (ic)) &&
3338 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3340 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3346 /* if this is a subtraction & the result
3347 is a true symbol in far space then don't pack */
3348 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3350 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3351 if (IN_FARSPACE (SPEC_OCLS (etype)))
3355 debugAopGet ("removing right:", IC_RIGHT (ic));
3357 /* found it we need to remove it from the
3359 for (sic = dic; sic != ic; sic = sic->next)
3360 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3362 IC_RIGHT (ic)->operand.symOperand =
3363 IC_RIGHT (dic)->operand.symOperand;
3364 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3366 remiCodeFromeBBlock (ebp, dic);
3367 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3368 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3377 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3379 #ifndef NO_packRegsForOneuse
3380 /*-----------------------------------------------------------------*/
3381 /* packRegsForOneuse : - will reduce some registers for single Use */
3382 /*-----------------------------------------------------------------*/
3384 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3389 debugLog ("%s\n", __FUNCTION__);
3390 /* if returning a literal then do nothing */
3394 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3397 /* only upto 2 bytes since we cannot predict
3398 the usage of b, & acc */
3399 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3407 /* this routine will mark the a symbol as used in one
3408 instruction use only && if the definition is local
3409 (ie. within the basic block) && has only one definition &&
3410 that definition is either a return value from a
3411 function or does not contain any variables in
3415 uses = bitVectCopy (OP_USES (op));
3416 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3417 if (!bitVectIsZero (uses)) /* has other uses */
3422 if (bitVectnBitsOn (OP_USES (op)) > 1)
3426 /* if it has only one defintion */
3427 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3428 return NULL; /* has more than one definition */
3430 /* get that definition */
3432 hTabItemWithKey (iCodehTab,
3433 bitVectFirstBit (OP_DEFS (op)))))
3436 /* found the definition now check if it is local */
3437 if (dic->seq < ebp->fSeq ||
3438 dic->seq > ebp->lSeq)
3439 return NULL; /* non-local */
3441 /* now check if it is the return from
3443 if (dic->op == CALL || dic->op == PCALL)
3445 if (ic->op != SEND && ic->op != RETURN &&
3446 !POINTER_SET(ic) && !POINTER_GET(ic))
3448 OP_SYMBOL (op)->ruonly = 1;
3457 /* otherwise check that the definition does
3458 not contain any symbols in far space */
3459 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3460 isOperandInFarSpace (IC_RIGHT (dic)) ||
3461 IS_OP_RUONLY (IC_LEFT (ic)) ||
3462 IS_OP_RUONLY (IC_RIGHT (ic)))
3467 /* if pointer set then make sure the pointer
3469 if (POINTER_SET (dic) &&
3470 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3473 if (POINTER_GET (dic) &&
3474 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3480 /* also make sure the intervenening instructions
3481 don't have any thing in far space */
3482 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3485 /* if there is an intervening function call then no */
3486 if (dic->op == CALL || dic->op == PCALL)
3488 /* if pointer set then make sure the pointer
3490 if (POINTER_SET (dic) &&
3491 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3494 if (POINTER_GET (dic) &&
3495 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3498 /* if address of & the result is remat then okay */
3499 if (dic->op == ADDRESS_OF &&
3500 OP_SYMBOL (IC_RESULT (dic))->remat)
3503 /* if operand has size of three or more & this
3504 operation is a '*','/' or '%' then 'b' may
3506 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3507 getSize (operandType (op)) >= 2)
3510 /* if left or right or result is in far space */
3511 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3512 isOperandInFarSpace (IC_RIGHT (dic)) ||
3513 isOperandInFarSpace (IC_RESULT (dic)) ||
3514 IS_OP_RUONLY (IC_LEFT (dic)) ||
3515 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3516 IS_OP_RUONLY (IC_RESULT (dic)))
3522 OP_SYMBOL (op)->ruonly = 1;
3529 /*-----------------------------------------------------------------*/
3530 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3531 /*-----------------------------------------------------------------*/
3533 isBitwiseOptimizable (iCode * ic)
3535 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3536 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3538 debugLog ("%s\n", __FUNCTION__);
3539 /* bitwise operations are considered optimizable
3540 under the following conditions (Jean-Louis VERN)
3552 if (IS_LITERAL (rtype) ||
3553 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3560 #ifndef NO_packRegsForAccUse
3562 /*-----------------------------------------------------------------*/
3563 /* packRegsForAccUse - pack registers for acc use */
3564 /*-----------------------------------------------------------------*/
3566 packRegsForAccUse (iCode * ic)
3570 debugLog ("%s\n", __FUNCTION__);
3572 /* if this is an aggregate, e.g. a one byte char array */
3573 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3576 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3578 /* if + or - then it has to be one byte result */
3579 if ((ic->op == '+' || ic->op == '-')
3580 && getSize (operandType (IC_RESULT (ic))) > 1)
3583 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3584 /* if shift operation make sure right side is not a literal */
3585 if (ic->op == RIGHT_OP &&
3586 (isOperandLiteral (IC_RIGHT (ic)) ||
3587 getSize (operandType (IC_RESULT (ic))) > 1))
3590 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3591 if (ic->op == LEFT_OP &&
3592 (isOperandLiteral (IC_RIGHT (ic)) ||
3593 getSize (operandType (IC_RESULT (ic))) > 1))
3596 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3597 if (IS_BITWISE_OP (ic) &&
3598 getSize (operandType (IC_RESULT (ic))) > 1)
3602 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3603 /* has only one definition */
3604 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3607 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3608 /* has only one use */
3609 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3612 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3613 /* and the usage immediately follows this iCode */
3614 if (!(uic = hTabItemWithKey (iCodehTab,
3615 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3618 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3619 if (ic->next != uic)
3622 /* if it is a conditional branch then we definitely can */
3626 if (uic->op == JUMPTABLE)
3629 /* if the usage is not is an assignment
3630 or an arithmetic / bitwise / shift operation then not */
3631 if (POINTER_SET (uic) &&
3632 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3635 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3636 if (uic->op != '=' &&
3637 !IS_ARITHMETIC_OP (uic) &&
3638 !IS_BITWISE_OP (uic) &&
3639 uic->op != LEFT_OP &&
3640 uic->op != RIGHT_OP)
3643 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3644 /* if used in ^ operation then make sure right is not a
3646 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3649 /* if shift operation make sure right side is not a literal */
3650 if (uic->op == RIGHT_OP &&
3651 (isOperandLiteral (IC_RIGHT (uic)) ||
3652 getSize (operandType (IC_RESULT (uic))) > 1))
3655 if (uic->op == LEFT_OP &&
3656 (isOperandLiteral (IC_RIGHT (uic)) ||
3657 getSize (operandType (IC_RESULT (uic))) > 1))
3660 /* make sure that the result of this icode is not on the
3661 stack, since acc is used to compute stack offset */
3662 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3663 OP_SYMBOL (IC_RESULT (uic))->onStack)
3666 /* if either one of them in far space then we cannot */
3667 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3668 isOperandInFarSpace (IC_LEFT (uic))) ||
3669 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3670 isOperandInFarSpace (IC_RIGHT (uic))))
3673 /* if the usage has only one operand then we can */
3674 if (IC_LEFT (uic) == NULL ||
3675 IC_RIGHT (uic) == NULL)
3678 /* make sure this is on the left side if not
3679 a '+' since '+' is commutative */
3680 if (ic->op != '+' &&
3681 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3685 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3686 /* if one of them is a literal then we can */
3687 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3688 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3689 (getSize (operandType (IC_RESULT (uic))) <= 1))
3691 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3696 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3697 /* if the other one is not on stack then we can */
3698 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3699 (IS_ITEMP (IC_RIGHT (uic)) ||
3700 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3701 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3704 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3705 (IS_ITEMP (IC_LEFT (uic)) ||
3706 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3707 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3713 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3714 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3721 /*-----------------------------------------------------------------*/
3722 /* packForPush - hueristics to reduce iCode for pushing */
3723 /*-----------------------------------------------------------------*/
3725 packForReceive (iCode * ic, eBBlock * ebp)
3729 debugLog ("%s\n", __FUNCTION__);
3730 debugAopGet (" result:", IC_RESULT (ic));
3731 debugAopGet (" left:", IC_LEFT (ic));
3732 debugAopGet (" right:", IC_RIGHT (ic));
3737 for (dic = ic->next; dic; dic = dic->next)
3739 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3740 debugLog (" used on left\n");
3741 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3742 debugLog (" used on right\n");
3743 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3744 debugLog (" used on result\n");
3746 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3747 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3751 debugLog (" hey we can remove this unnecessary assign\n");
3753 /*-----------------------------------------------------------------*/
3754 /* packForPush - hueristics to reduce iCode for pushing */
3755 /*-----------------------------------------------------------------*/
3757 packForPush (iCode * ic, eBBlock * ebp)
3761 debugLog ("%s\n", __FUNCTION__);
3762 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3769 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3770 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3771 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3772 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3776 /* must have only definition & one usage */
3777 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3778 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3781 /* find the definition */
3782 if (!(dic = hTabItemWithKey (iCodehTab,
3783 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3786 /* if definition is not assignment,
3787 * or is not pointer (because pointer might have changed) */
3788 if (dic->op != '=' || POINTER_SET (dic))
3791 /* we must ensure that we can use the delete the assignment,
3792 * because the source might have been modified in between.
3793 * Until I know how to fix this, I'll use the adhoc fix
3794 * to check the liveranges */
3795 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3797 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3801 /* we now we know that it has one & only one def & use
3802 and the that the definition is an assignment */
3803 IC_LEFT (ic) = IC_RIGHT (dic);
3805 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3807 remiCodeFromeBBlock (ebp, dic);
3808 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3809 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3812 static void printSymType(char * str, sym_link *sl)
3814 if(!pic16_ralloc_debug)return;
3816 debugLog (" %s Symbol type: ",str);
3817 printTypeChain( sl, debugF);
3821 /*-----------------------------------------------------------------*/
3822 /* some debug code to print the symbol S_TYPE. Note that
3823 * the function checkSClass in src/SDCCsymt.c dinks with
3824 * the S_TYPE in ways the PIC port doesn't fully like...*/
3825 /*-----------------------------------------------------------------*/
3826 static void isData(sym_link *sl)
3830 if(!pic16_ralloc_debug)return;
3837 for ( ; sl; sl=sl->next) {
3839 switch (SPEC_SCLS(sl)) {
3840 case S_DATA: fprintf (of, "data "); break;
3841 case S_XDATA: fprintf (of, "xdata "); break;
3842 case S_SFR: fprintf (of, "sfr "); break;
3843 case S_SBIT: fprintf (of, "sbit "); break;
3844 case S_CODE: fprintf (of, "code "); break;
3845 case S_IDATA: fprintf (of, "idata "); break;
3846 case S_PDATA: fprintf (of, "pdata "); break;
3847 case S_LITERAL: fprintf (of, "literal "); break;
3848 case S_STACK: fprintf (of, "stack "); break;
3849 case S_XSTACK: fprintf (of, "xstack "); break;
3850 case S_BIT: fprintf (of, "bit "); break;
3851 case S_EEPROM: fprintf (of, "eeprom "); break;
3859 /*--------------------------------------------------------------------*/
3860 /* pic16_packRegisters - does some transformations to reduce */
3861 /* register pressure */
3863 /*--------------------------------------------------------------------*/
3865 pic16_packRegisters (eBBlock * ebp)
3870 debugLog ("%s\n", __FUNCTION__);
3876 /* look for assignments of the form */
3877 /* iTempNN = TRueSym (someoperation) SomeOperand */
3879 /* TrueSym := iTempNN:1 */
3880 for (ic = ebp->sch; ic; ic = ic->next)
3882 // debugLog("%d\n", __LINE__);
3883 /* find assignment of the form TrueSym := iTempNN:1 */
3884 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3885 change += packRegsForAssign (ic, ebp);
3889 if (POINTER_SET (ic))
3890 debugLog ("pointer is set\n");
3891 debugAopGet (" result:", IC_RESULT (ic));
3892 debugAopGet (" left:", IC_LEFT (ic));
3893 debugAopGet (" right:", IC_RIGHT (ic));
3902 for (ic = ebp->sch; ic; ic = ic->next) {
3904 if(IS_SYMOP ( IC_LEFT(ic))) {
3905 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3907 debugAopGet ("x left:", IC_LEFT (ic));
3909 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3911 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3913 debugLog (" is a pointer\n");
3915 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3916 debugLog (" is a ptr\n");
3918 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3919 debugLog (" is volatile\n");
3923 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3924 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3925 pic16_allocDirReg(IC_LEFT (ic));
3928 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3931 if(IS_SYMOP ( IC_RIGHT(ic))) {
3932 debugAopGet (" right:", IC_RIGHT (ic));
3933 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3936 if(IS_SYMOP ( IC_RESULT(ic))) {
3937 debugAopGet (" result:", IC_RESULT (ic));
3938 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3941 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3942 debugAopGet (" right:", IC_RIGHT (ic));
3943 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3944 // pic16_allocDirReg(IC_RIGHT(ic));
3947 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3948 debugAopGet (" result:", IC_RESULT (ic));
3949 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3950 // pic16_allocDirReg(IC_RESULT(ic));
3954 if (POINTER_SET (ic))
3955 debugLog (" %d - Pointer set\n", __LINE__);
3957 /* Look for two subsequent iCodes with */
3959 /* _c = iTemp & op; */
3960 /* and replace them by */
3963 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3965 && ic->prev->op == '='
3966 && IS_ITEMP (IC_LEFT (ic))
3967 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3968 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3970 iCode* ic_prev = ic->prev;
3971 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3973 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3974 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
3975 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3976 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3977 prev_result_sym->liveTo == ic->seq)
3979 prev_result_sym->liveTo = ic_prev->seq;
3982 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3984 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3986 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
3987 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3988 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3989 remiCodeFromeBBlock (ebp, ic_prev);
3990 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3994 /* if this is an itemp & result of a address of a true sym
3995 then mark this as rematerialisable */
3996 if (ic->op == ADDRESS_OF &&
3997 IS_ITEMP (IC_RESULT (ic)) &&
3998 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3999 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4000 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4003 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4005 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4006 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4007 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4011 /* if straight assignment then carry remat flag if
4012 this is the only definition */
4013 if (ic->op == '=' &&
4014 !POINTER_SET (ic) &&
4015 IS_SYMOP (IC_RIGHT (ic)) &&
4016 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4017 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4019 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4021 OP_SYMBOL (IC_RESULT (ic))->remat =
4022 OP_SYMBOL (IC_RIGHT (ic))->remat;
4023 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4024 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4027 /* if this is a +/- operation with a rematerizable
4028 then mark this as rematerializable as well */
4029 if ((ic->op == '+' || ic->op == '-') &&
4030 (IS_SYMOP (IC_LEFT (ic)) &&
4031 IS_ITEMP (IC_RESULT (ic)) &&
4032 OP_SYMBOL (IC_LEFT (ic))->remat &&
4033 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4034 IS_OP_LITERAL (IC_RIGHT (ic))))
4036 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4038 operandLitValue (IC_RIGHT (ic));
4039 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4040 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4041 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4046 /* if this is an arithmetic operation
4047 * && result or left is not rematerializable (so it is a plain arithmetic op)
4048 * && and left is not used after this iCode */
4050 if(getenv("OPTIMIZE_NEAR_POINTER_GET"))
4052 if (IS_ARITHMETIC_OP(ic)
4053 && !IS_OP_LITERAL (IC_LEFT (ic))
4054 && !OP_SYMBOL (IC_RESULT(ic))->rematiCode
4055 && !OP_SYMBOL (IC_LEFT(ic))->rematiCode
4056 && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq)
4058 iCode *dic = ic->prev;
4060 /* search backwards to find assignment from a remat pointer */
4061 while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) {
4063 /* is it a pointer_get? */
4065 && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) {
4066 fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__,
4067 OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq);
4069 /* so we can replace ic->left with dic->left, & remove assignment */
4070 ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) );
4072 bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key);
4073 bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key );
4075 // dic->op = DUMMY_READ_VOLATILE;
4077 remiCodeFromeBBlock(ebp, dic);
4078 hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4087 /* mark the pointer usages */
4088 if (POINTER_SET (ic))
4090 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4091 debugLog (" marking as a pointer (set) =>");
4092 debugAopGet (" result:", IC_RESULT (ic));
4096 if (POINTER_GET (ic))
4098 if(IS_SYMOP(IC_LEFT(ic))) {
4099 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4100 debugLog (" marking as a pointer (get) =>");
4101 debugAopGet (" left:", IC_LEFT (ic));
4104 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4105 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4106 iCode *dic = ic->prev;
4108 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4110 if(dic && dic->op == '='
4111 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4113 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4116 /* replace prev->left with ic->left */
4117 IC_LEFT(ic) = IC_RIGHT(dic);
4118 IC_RIGHT(ic->prev) = NULL;
4120 /* remove ic->prev iCode (assignment) */
4121 remiCodeFromeBBlock (ebp, dic);
4122 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4125 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4131 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4135 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4136 /* if we are using a symbol on the stack
4137 then we should say pic16_ptrRegReq */
4138 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4139 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4140 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4141 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4142 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4143 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4147 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4148 if (IS_SYMOP (IC_LEFT (ic)))
4149 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4150 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4151 if (IS_SYMOP (IC_RIGHT (ic)))
4152 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4153 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4154 if (IS_SYMOP (IC_RESULT (ic)))
4155 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4156 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4159 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4163 /* if the condition of an if instruction
4164 is defined in the previous instruction then
4165 mark the itemp as a conditional */
4166 if ((IS_CONDITIONAL (ic) ||
4167 ((ic->op == BITWISEAND ||
4170 isBitwiseOptimizable (ic))) &&
4171 ic->next && ic->next->op == IFX &&
4172 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4173 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4176 debugLog (" %d\n", __LINE__);
4177 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4181 debugLog(" %d\n", __LINE__);
4183 #ifndef NO_packRegsForSupport
4184 /* reduce for support function calls */
4185 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4186 packRegsForSupport (ic, ebp);
4189 /* if a parameter is passed, it's in W, so we may not
4190 need to place a copy in a register */
4191 if (ic->op == RECEIVE)
4192 packForReceive (ic, ebp);
4194 #ifndef NO_packRegsForOneuse
4195 /* some cases the redundant moves can
4196 can be eliminated for return statements */
4197 if ((ic->op == RETURN || ic->op == SEND) &&
4198 !isOperandInFarSpace (IC_LEFT (ic)) &&
4200 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4203 #ifndef NO_packRegsForOneuse
4204 /* if pointer set & left has a size more than
4205 one and right is not in far space */
4206 if (POINTER_SET (ic) &&
4207 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4208 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4209 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4210 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4212 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4215 #ifndef NO_packRegsForOneuse
4216 /* if pointer get */
4217 if (POINTER_GET (ic) &&
4218 !isOperandInFarSpace (IC_RESULT (ic)) &&
4219 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4220 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4221 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4223 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4224 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4227 #ifndef NO_cast_peep
4228 /* if this is cast for intergral promotion then
4229 check if only use of the definition of the
4230 operand being casted/ if yes then replace
4231 the result of that arithmetic operation with
4232 this result and get rid of the cast */
4233 if (ic->op == CAST) {
4235 sym_link *fromType = operandType (IC_RIGHT (ic));
4236 sym_link *toType = operandType (IC_LEFT (ic));
4238 debugLog (" %d - casting\n", __LINE__);
4240 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4241 getSize (fromType) != getSize (toType)) {
4244 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4247 if (IS_ARITHMETIC_OP (dic)) {
4248 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4250 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4251 IC_RESULT (dic) = IC_RESULT (ic);
4252 remiCodeFromeBBlock (ebp, ic);
4253 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4254 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4255 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4259 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4263 /* if the type from and type to are the same
4264 then if this is the only use then packit */
4265 if (compareType (operandType (IC_RIGHT (ic)),
4266 operandType (IC_LEFT (ic))) == 1) {
4268 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4271 debugLog(" %d\n", __LINE__);
4273 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4274 IC_RESULT (dic) = IC_RESULT (ic);
4275 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4276 remiCodeFromeBBlock (ebp, ic);
4277 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4278 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4287 /* there are some problems with packing variables
4288 * it seems that the live range estimator doesn't
4289 * estimate correctly the liveranges of some symbols */
4292 iTempNN := (some variable in farspace) V1
4297 if (ic->op == IPUSH)
4299 packForPush (ic, ebp);
4303 #ifndef NO_packRegsForAccUse
4304 /* pack registers for accumulator use, when the
4305 result of an arithmetic or bit wise operation
4306 has only one use, that use is immediately following
4307 the defintion and the using iCode has only one
4308 operand or has two operands but one is literal &
4309 the result of that operation is not on stack then
4310 we can leave the result of this operation in acc:b
4312 if ((IS_ARITHMETIC_OP (ic)
4314 || IS_BITWISE_OP (ic)
4316 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4319 IS_ITEMP (IC_RESULT (ic)) &&
4320 getSize (operandType (IC_RESULT (ic))) <= 1)
4322 packRegsForAccUse (ic);
4329 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4333 if (!pic16_ralloc_debug || !debugF)
4336 for (i = 0; i < count; i++)
4338 fprintf (debugF, "\n----------------------------------------------------------------\n");
4339 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4340 ebbs[i]->entryLabel->name,
4343 ebbs[i]->isLastInLoop);
4344 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4349 fprintf (debugF, "visited %d : hasFcall = %d\n",
4353 fprintf (debugF, "\ndefines bitVector :");
4354 bitVectDebugOn (ebbs[i]->defSet, debugF);
4355 fprintf (debugF, "\nlocal defines bitVector :");
4356 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4357 fprintf (debugF, "\npointers Set bitvector :");
4358 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4359 fprintf (debugF, "\nin pointers Set bitvector :");
4360 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4361 fprintf (debugF, "\ninDefs Set bitvector :");
4362 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4363 fprintf (debugF, "\noutDefs Set bitvector :");
4364 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4365 fprintf (debugF, "\nusesDefs Set bitvector :");
4366 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4367 fprintf (debugF, "\n----------------------------------------------------------------\n");
4368 printiCChain (ebbs[i]->sch, debugF);
4371 /*-----------------------------------------------------------------*/
4372 /* pic16_assignRegisters - assigns registers to each live range as need */
4373 /*-----------------------------------------------------------------*/
4375 pic16_assignRegisters (ebbIndex * ebbi)
4377 eBBlock ** ebbs = ebbi->bbOrder;
4378 int count = ebbi->count;
4382 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4383 debugLog ("\nebbs before optimizing:\n");
4384 dumpEbbsToDebug (ebbs, count);
4386 _inRegAllocator = 1;
4388 setToNull ((void *) &_G.funcrUsed);
4389 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4392 /* change assignments this will remove some
4393 live ranges reducing some register pressure */
4394 for (i = 0; i < count; i++)
4395 pic16_packRegisters (ebbs[i]);
4402 debugLog("dir registers allocated so far:\n");
4403 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4407 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4408 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4409 reg = hTabNextItem(dynDirectRegNames, &hkey);
4415 /* liveranges probably changed by register packing
4416 so we compute them again */
4417 recomputeLiveRanges (ebbs, count);
4419 if (options.dump_pack)
4420 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4422 /* first determine for each live range the number of
4423 registers & the type of registers required for each */
4426 /* start counting function temporary registers from zero */
4429 /* and serially allocate registers */
4430 serialRegAssign (ebbs, count);
4433 debugLog ("ebbs after serialRegAssign:\n");
4434 dumpEbbsToDebug (ebbs, count);
4437 //pic16_freeAllRegs();
4439 /* if stack was extended then tell the user */
4442 /* werror(W_TOOMANY_SPILS,"stack", */
4443 /* _G.stackExtend,currFunc->name,""); */
4449 /* werror(W_TOOMANY_SPILS,"data space", */
4450 /* _G.dataExtend,currFunc->name,""); */
4454 /* after that create the register mask
4455 for each of the instruction */
4456 createRegMask (ebbs, count);
4458 /* redo that offsets for stacked automatic variables */
4459 redoStackOffsets ();
4461 if (options.dump_rassgn)
4462 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4464 /* now get back the chain */
4465 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4467 debugLog ("ebbs after optimizing:\n");
4468 dumpEbbsToDebug (ebbs, count);
4471 _inRegAllocator = 0;
4475 /* free up any _G.stackSpil locations allocated */
4476 applyToSet (_G.stackSpil, deallocStackSpil);
4478 setToNull ((void *) &_G.stackSpil);
4479 setToNull ((void *) &_G.spiltSet);
4480 /* mark all registers as free */
4481 pic16_freeAllRegs ();
4484 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");