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, ...);
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(*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 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 ENDFUNCTION: return "ENDFUNCTION";
306 case JUMPTABLE: return "JUMPTABLE";
307 case RRC: return "RRC";
308 case RLC: return "RLC";
309 case CAST: return "CAST";
310 case CALL: return "CALL";
311 case PARAM: return "PARAM ";
312 case NULLOP: return "NULLOP";
313 case BLOCK: return "BLOCK";
314 case LABEL: return "LABEL";
315 case RECEIVE: return "RECEIVE";
316 case SEND: return "SEND";
318 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
322 /*-----------------------------------------------------------------*/
323 /*-----------------------------------------------------------------*/
325 debugLogRegType (short type)
327 if(!pic16_ralloc_debug)return NULL;
329 case REG_GPR: return "REG_GPR";
330 case REG_PTR: return "REG_PTR";
331 case REG_CND: return "REG_CND";
333 sprintf (buffer, "unknown reg type %d", type);
338 /*-----------------------------------------------------------------*/
339 /*-----------------------------------------------------------------*/
340 static int regname2key(char const *name)
349 key += (*name++) + 1;
353 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
357 /*-----------------------------------------------------------------*/
358 /* newReg - allocate and init memory for a new register */
359 /*-----------------------------------------------------------------*/
360 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
365 dReg = Safe_calloc(1,sizeof(regs));
367 dReg->pc_type = pc_type;
370 dReg->name = Safe_strdup(name);
372 sprintf(buffer,"r0x%02X", dReg->rIdx);
375 dReg->name = Safe_strdup(buffer);
383 if(type == REG_SFR) {
385 dReg->address = rIdx;
386 dReg->accessBank = 1;
390 dReg->accessBank = 0;
393 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
397 dReg->reg_alias = NULL;
398 dReg->reglives.usedpFlows = newSet();
399 dReg->reglives.assignedpFlows = newSet();
402 if(!(type == REG_SFR && alias == 0x80))
403 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
408 /*-----------------------------------------------------------------*/
409 /* regWithIdx - Search through a set of registers that matches idx */
410 /*-----------------------------------------------------------------*/
412 regWithIdx (set *dRegs, int idx, unsigned fixed)
416 for (dReg = setFirstItem(dRegs) ; dReg ;
417 dReg = setNextItem(dRegs)) {
419 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
427 /*-----------------------------------------------------------------*/
428 /* regFindFree - Search for a free register in a set of registers */
429 /*-----------------------------------------------------------------*/
431 regFindFree (set *dRegs)
435 for (dReg = setFirstItem(dRegs) ; dReg ;
436 dReg = setNextItem(dRegs)) {
438 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
439 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
448 /*-----------------------------------------------------------------*/
449 /* pic16_initStack - allocate registers for a pseudo stack */
450 /*-----------------------------------------------------------------*/
451 void pic16_initStack(int base_address, int size)
456 pic16_Gstack_base_addr = base_address;
457 //fprintf(stderr,"initStack");
459 for(i = 0; i<size; i++)
460 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
463 /*-----------------------------------------------------------------*
464 *-----------------------------------------------------------------*/
466 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
468 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
470 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
472 reg->wasUsed = 0; // we do not know if they are going to be used at all
473 reg->accessBank = 1; // implicit add access Bank
475 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
477 return addSet(&pic16_dynProcessorRegs, reg);
480 /*-----------------------------------------------------------------*
481 *-----------------------------------------------------------------*/
484 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
486 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
488 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
492 return addSet(&pic16_dynInternalRegs,reg);
499 /*-----------------------------------------------------------------*/
500 /* allocReg - allocates register of given type */
501 /*-----------------------------------------------------------------*/
503 allocReg (short type)
507 #define MAX_P16_NREGS 6
511 if(dynrIdx > pic16_nRegs)
515 /* try to reuse some unused registers */
516 reg = regFindFree( pic16_dynAllocRegs );
519 // fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
523 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
524 // fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
527 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
528 // debugf("allocating more registers than available\n", 0);
533 // addSet(&pic16_dynAllocRegs, reg);
536 addSet(&pic16_dynAllocRegs, reg);
537 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
541 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
543 // fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
544 // __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
547 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
548 reg->isLocal = 1; /* this is a local frame register */
553 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
554 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
557 return (reg); // addSet(&pic16_dynAllocRegs,reg);
562 /*-----------------------------------------------------------------*/
563 /* pic16_dirregWithName - search for register by name */
564 /*-----------------------------------------------------------------*/
566 pic16_dirregWithName (char *name)
574 /* hash the name to get a key */
576 hkey = regname2key(name);
578 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
580 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
584 if(STRCASECMP(reg->name, name) == 0) {
585 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
589 reg = hTabNextItemWK (dynDirectRegNames);
593 return NULL; // name wasn't found in the hash table
596 /*-----------------------------------------------------------------*/
597 /* pic16_allocregWithName - search for register by name */
598 /*-----------------------------------------------------------------*/
600 pic16_allocregWithName (char *name)
608 /* hash the name to get a key */
610 hkey = regname2key(name);
612 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
614 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
618 if(STRCASECMP(reg->name, name) == 0) {
622 reg = hTabNextItemWK (dynAllocRegNames);
626 return NULL; // name wasn't found in the hash table
631 /*-----------------------------------------------------------------*/
632 /* pic16_procregWithName - search for register by name */
633 /*-----------------------------------------------------------------*/
635 pic16_procregWithName (char *name)
643 /* hash the name to get a key */
645 hkey = regname2key(name);
647 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
649 reg = hTabFirstItemWK(dynProcRegNames, hkey);
653 if(STRCASECMP(reg->name, name) == 0) {
657 reg = hTabNextItemWK (dynProcRegNames);
661 return NULL; // name wasn't found in the hash table
665 /*-----------------------------------------------------------------*/
666 /* pic16_accessregWithName - search for register by name */
667 /*-----------------------------------------------------------------*/
669 pic16_accessregWithName (char *name)
677 /* hash the name to get a key */
679 hkey = regname2key(name);
681 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
683 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
687 if(STRCASECMP(reg->name, name) == 0) {
691 reg = hTabNextItemWK (dynAccessRegNames);
695 return NULL; // name wasn't found in the hash table
699 regs *pic16_regWithName(char *name)
703 reg = pic16_dirregWithName( name );
706 reg = pic16_procregWithName( name );
709 reg = pic16_allocregWithName( name );
712 reg = pic16_accessregWithName( name );
719 /*-----------------------------------------------------------------*/
720 /* pic16_allocDirReg - allocates register of given type */
721 /*-----------------------------------------------------------------*/
723 pic16_allocDirReg (operand *op )
729 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
730 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
734 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
737 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
739 if(pic16_debug_verbose)
741 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
742 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
748 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
749 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
752 if(pic16_debug_verbose) {
753 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
754 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
755 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
756 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
757 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
758 IN_STACK( OP_SYM_ETYPE(op)),
759 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
760 IS_REGPARM(OP_SYM_ETYPE(op)),
763 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
764 OP_SYMBOL(op)->name);
772 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
773 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
777 if(IS_ITEMP(op))return NULL;
779 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
780 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
783 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
784 debugLog(" %d const char\n",__LINE__);
785 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
786 // fprintf(stderr, " %d const char\n",__LINE__);
787 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
791 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
792 if (IS_CODE ( OP_SYM_ETYPE(op)) )
793 debugLog(" %d code space\n",__LINE__);
795 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
796 debugLog(" %d integral\n",__LINE__);
798 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
799 debugLog(" %d literal\n",__LINE__);
801 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
802 debugLog(" %d specifier\n",__LINE__);
804 debugAopGet(NULL, op);
808 reg = pic16_dirregWithName(name);
812 int regtype = REG_GPR;
814 /* if this is at an absolute address, then get the address. */
815 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
816 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
817 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
820 /* Register wasn't found in hash, so let's create
821 * a new one and put it in the hash table AND in the
822 * dynDirectRegNames set */
823 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
824 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
830 if(OP_SYMBOL(op)->onStack) {
831 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
832 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
836 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
837 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
840 if(pic16_debug_verbose)
842 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
843 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
844 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
845 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
846 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
847 IN_STACK( OP_SYM_ETYPE(op)),
848 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
850 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
851 OP_SYMBOL(op)->name);
856 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
857 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
859 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
860 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
864 checkAddReg(&pic16_dynAccessRegs, reg);
865 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
871 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
872 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
873 // reg->type = REG_SFR;
876 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
877 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
878 addSet(&pic16_dynDirectBitRegs, reg);
881 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
882 // addSet(&pic16_dynDirectRegs, reg);
885 if(!(IS_STATIC(OP_SYM_ETYPE(op))
886 && OP_SYMBOL(op)->ival
889 checkAddReg(&pic16_dynDirectRegs, reg);
893 // debugLog (" -- %s is declared at address 0x30000x\n",name);
894 return (reg); /* This was NULL before, but since we found it
895 * why not just return it?! */
898 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
900 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
902 /* work around for user defined registers in access bank */
903 if((reg->address>= 0x00 && reg->address < 0x80)
904 || (reg->address >= 0xf80 && reg->address <= 0xfff))
907 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
913 /*-----------------------------------------------------------------*/
914 /* pic16_allocRegByName - allocates register of given type */
915 /*-----------------------------------------------------------------*/
917 pic16_allocRegByName (char *name, int size, operand *op)
923 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
927 /* First, search the hash table to see if there is a register with this name */
928 reg = pic16_dirregWithName(name);
932 /* Register wasn't found in hash, so let's create
933 * a new one and put it in the hash table AND in the
934 * dynDirectRegNames set */
936 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
938 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
940 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
941 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
943 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
944 addSet(&pic16_dynDirectRegs, reg);
950 /*-----------------------------------------------------------------*/
951 /* RegWithIdx - returns pointer to register with index number */
952 /*-----------------------------------------------------------------*/
953 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
958 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
959 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
964 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
966 debugLog ("Found a Dynamic Register!\n");
969 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
970 debugLog ("Found a Direct Register!\n");
976 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
977 debugLog ("Found a Stack Register!\n");
982 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
983 debugLog ("Found a Processor Register!\n");
997 /*-----------------------------------------------------------------*/
998 /* pic16_regWithIdx - returns pointer to register with index number*/
999 /*-----------------------------------------------------------------*/
1001 pic16_regWithIdx (int idx)
1005 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1008 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1012 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1019 /*-----------------------------------------------------------------*/
1020 /* pic16_regWithIdx - returns pointer to register with index number */
1021 /*-----------------------------------------------------------------*/
1023 pic16_allocWithIdx (int idx)
1028 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1029 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1031 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1033 debugLog ("Found a Dynamic Register!\n");
1034 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1035 debugLog ("Found a Stack Register!\n");
1036 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1037 debugLog ("Found a Processor Register!\n");
1038 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1039 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1040 debugLog ("Found an Internal Register!\n");
1043 debugLog ("Dynamic Register not found\n");
1046 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1047 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1048 "regWithIdx not found");
1058 /*-----------------------------------------------------------------*/
1059 /*-----------------------------------------------------------------*/
1061 pic16_findFreeReg(short type)
1068 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1070 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1074 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1086 /*-----------------------------------------------------------------*/
1087 /* freeReg - frees a register */
1088 /*-----------------------------------------------------------------*/
1090 freeReg (regs * reg)
1092 debugLog ("%s\n", __FUNCTION__);
1093 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1098 /*-----------------------------------------------------------------*/
1099 /* nFreeRegs - returns number of free registers */
1100 /*-----------------------------------------------------------------*/
1102 nFreeRegs (int type)
1108 /* although I fixed the register allocation/freeing scheme
1109 * the for loop below doesn't give valid results. I do not
1110 * know why yet. -- VR 10-Jan-2003 */
1115 /* dynamically allocate as many as we need and worry about
1116 * fitting them into a PIC later */
1118 debugLog ("%s\n", __FUNCTION__);
1120 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1121 if((reg->type == type) && reg->isFree)nfr++;
1123 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1127 /*-----------------------------------------------------------------*/
1128 /* nfreeRegsType - free registers with type */
1129 /*-----------------------------------------------------------------*/
1131 nfreeRegsType (int type)
1134 debugLog ("%s\n", __FUNCTION__);
1135 if (type == REG_PTR)
1137 if ((nfr = nFreeRegs (type)) == 0)
1138 return nFreeRegs (REG_GPR);
1141 return nFreeRegs (type);
1144 static void writeSetUsedRegs(FILE *of, set *dRegs)
1149 for (dReg = setFirstItem(dRegs) ; dReg ;
1150 dReg = setNextItem(dRegs)) {
1153 fprintf (of, "\t%s\n",dReg->name);
1159 extern void pic16_groupRegistersInSection(set *regset);
1161 extern void pic16_dump_equates(FILE *of, set *equs);
1162 extern void pic16_dump_access(FILE *of, set *section);
1163 //extern void pic16_dump_map(void);
1164 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1165 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1166 extern void pic16_dump_int_registers(FILE *of, set *section);
1167 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1169 extern void pic16_dump_gsection(FILE *of, set *sections);
1171 static void packBits(set *bregs)
1175 regs *bitfield=NULL;
1176 regs *relocbitfield=NULL;
1182 for (regset = bregs ; regset ;
1183 regset = regset->next) {
1185 breg = regset->item;
1186 breg->isBitField = 1;
1187 //fprintf(stderr,"bit reg: %s\n",breg->name);
1190 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1192 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1193 breg->rIdx = breg->address & 7;
1194 breg->address >>= 3;
1197 sprintf (buffer, "fbitfield%02x", breg->address);
1198 //fprintf(stderr,"new bit field\n");
1199 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1200 bitfield->isBitField = 1;
1201 bitfield->isFixed = 1;
1202 bitfield->address = breg->address;
1203 addSet(&pic16_dynDirectRegs,bitfield);
1204 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1206 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1209 breg->reg_alias = bitfield;
1213 if(!relocbitfield || bit_no >7) {
1216 sprintf (buffer, "bitfield%d", byte_no);
1217 //fprintf(stderr,"new relocatable bit field\n");
1218 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1219 relocbitfield->isBitField = 1;
1220 addSet(&pic16_dynDirectRegs,relocbitfield);
1221 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1225 breg->reg_alias = relocbitfield;
1226 breg->address = rDirectIdx; /* byte_no; */
1227 breg->rIdx = bit_no++;
1233 void pic16_writeUsedRegs(FILE *of)
1235 packBits(pic16_dynDirectBitRegs);
1237 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1238 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1240 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1241 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1243 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1244 pic16_groupRegistersInSection(pic16_dynStackRegs);
1246 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1247 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1249 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1250 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1252 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1253 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1255 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1256 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1259 pic16_dump_equates(of, pic16_equ_data);
1261 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1262 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1264 /* dump access bank symbols */
1265 pic16_dump_access(of, pic16_acs_udata);
1267 /* dump initialised data */
1268 pic16_dump_isection(of, rel_idataSymSet, 0);
1269 pic16_dump_isection(of, fix_idataSymSet, 1);
1271 /* dump internal registers */
1272 pic16_dump_int_registers(of, pic16_int_regs);
1274 /* dump generic section variables */
1275 pic16_dump_gsection(of, sectNames);
1277 /* dump other variables */
1278 pic16_dump_usection(of, pic16_rel_udata, 0);
1279 pic16_dump_usection(of, pic16_fix_udata, 1);
1284 /*-----------------------------------------------------------------*/
1285 /* computeSpillable - given a point find the spillable live ranges */
1286 /*-----------------------------------------------------------------*/
1288 computeSpillable (iCode * ic)
1292 debugLog ("%s\n", __FUNCTION__);
1293 /* spillable live ranges are those that are live at this
1294 point . the following categories need to be subtracted
1296 a) - those that are already spilt
1297 b) - if being used by this one
1298 c) - defined by this one */
1300 spillable = bitVectCopy (ic->rlive);
1302 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1304 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1305 bitVectUnSetBit (spillable, ic->defKey);
1306 spillable = bitVectIntersect (spillable, _G.regAssigned);
1311 /*-----------------------------------------------------------------*/
1312 /* noSpilLoc - return true if a variable has no spil location */
1313 /*-----------------------------------------------------------------*/
1315 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1317 debugLog ("%s\n", __FUNCTION__);
1318 return (sym->usl.spillLoc ? 0 : 1);
1321 /*-----------------------------------------------------------------*/
1322 /* hasSpilLoc - will return 1 if the symbol has spil location */
1323 /*-----------------------------------------------------------------*/
1325 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1327 debugLog ("%s\n", __FUNCTION__);
1328 return (sym->usl.spillLoc ? 1 : 0);
1331 /*-----------------------------------------------------------------*/
1332 /* directSpilLoc - will return 1 if the splilocation is in direct */
1333 /*-----------------------------------------------------------------*/
1335 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1337 debugLog ("%s\n", __FUNCTION__);
1338 if (sym->usl.spillLoc &&
1339 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1345 /*-----------------------------------------------------------------*/
1346 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1347 /* but is not used as a pointer */
1348 /*-----------------------------------------------------------------*/
1350 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1352 debugLog ("%s\n", __FUNCTION__);
1353 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1356 /*-----------------------------------------------------------------*/
1357 /* rematable - will return 1 if the remat flag is set */
1358 /*-----------------------------------------------------------------*/
1360 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1362 debugLog ("%s\n", __FUNCTION__);
1366 /*-----------------------------------------------------------------*/
1367 /* notUsedInRemaining - not used or defined in remain of the block */
1368 /*-----------------------------------------------------------------*/
1370 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1372 debugLog ("%s\n", __FUNCTION__);
1373 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1374 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1377 /*-----------------------------------------------------------------*/
1378 /* allLRs - return true for all */
1379 /*-----------------------------------------------------------------*/
1381 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1383 debugLog ("%s\n", __FUNCTION__);
1387 /*-----------------------------------------------------------------*/
1388 /* liveRangesWith - applies function to a given set of live range */
1389 /*-----------------------------------------------------------------*/
1391 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1392 eBBlock * ebp, iCode * ic)
1397 debugLog ("%s\n", __FUNCTION__);
1398 if (!lrs || !lrs->size)
1401 for (i = 1; i < lrs->size; i++)
1404 if (!bitVectBitValue (lrs, i))
1407 /* if we don't find it in the live range
1408 hash table we are in serious trouble */
1409 if (!(sym = hTabItemWithKey (liveRanges, i)))
1411 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1412 "liveRangesWith could not find liveRange");
1416 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1417 addSetHead (&rset, sym);
1424 /*-----------------------------------------------------------------*/
1425 /* leastUsedLR - given a set determines which is the least used */
1426 /*-----------------------------------------------------------------*/
1428 leastUsedLR (set * sset)
1430 symbol *sym = NULL, *lsym = NULL;
1432 debugLog ("%s\n", __FUNCTION__);
1433 sym = lsym = setFirstItem (sset);
1438 for (; lsym; lsym = setNextItem (sset))
1441 /* if usage is the same then prefer
1442 the spill the smaller of the two */
1443 if (lsym->used == sym->used)
1444 if (getSize (lsym->type) < getSize (sym->type))
1448 if (lsym->used < sym->used)
1453 setToNull ((void *) &sset);
1458 /*-----------------------------------------------------------------*/
1459 /* noOverLap - will iterate through the list looking for over lap */
1460 /*-----------------------------------------------------------------*/
1462 noOverLap (set * itmpStack, symbol * fsym)
1465 debugLog ("%s\n", __FUNCTION__);
1468 for (sym = setFirstItem (itmpStack); sym;
1469 sym = setNextItem (itmpStack))
1471 if (sym->liveTo > fsym->liveFrom)
1479 /*-----------------------------------------------------------------*/
1480 /* isFree - will return 1 if the a free spil location is found */
1481 /*-----------------------------------------------------------------*/
1486 V_ARG (symbol **, sloc);
1487 V_ARG (symbol *, fsym);
1489 debugLog ("%s\n", __FUNCTION__);
1490 /* if already found */
1494 /* if it is free && and the itmp assigned to
1495 this does not have any overlapping live ranges
1496 with the one currently being assigned and
1497 the size can be accomodated */
1499 noOverLap (sym->usl.itmpStack, fsym) &&
1500 getSize (sym->type) >= getSize (fsym->type))
1509 /*-----------------------------------------------------------------*/
1510 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1511 /*-----------------------------------------------------------------*/
1513 spillLRWithPtrReg (symbol * forSym)
1519 debugLog ("%s\n", __FUNCTION__);
1520 if (!_G.regAssigned ||
1521 bitVectIsZero (_G.regAssigned))
1524 r0 = pic16_regWithIdx (R0_IDX);
1525 r1 = pic16_regWithIdx (R1_IDX);
1527 /* for all live ranges */
1528 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1529 lrsym = hTabNextItem (liveRanges, &k))
1533 /* if no registers assigned to it or
1535 /* if it does not overlap with this then
1536 not need to spill it */
1538 if (lrsym->isspilt || !lrsym->nRegs ||
1539 (lrsym->liveTo < forSym->liveFrom))
1542 /* go thru the registers : if it is either
1543 r0 or r1 then spil it */
1544 for (j = 0; j < lrsym->nRegs; j++)
1545 if (lrsym->regs[j] == r0 ||
1546 lrsym->regs[j] == r1)
1555 /*-----------------------------------------------------------------*/
1556 /* createStackSpil - create a location on the stack to spil */
1557 /*-----------------------------------------------------------------*/
1559 createStackSpil (symbol * sym)
1561 symbol *sloc = NULL;
1562 int useXstack, model, noOverlay;
1564 char slocBuffer[30];
1565 debugLog ("%s\n", __FUNCTION__);
1567 /* first go try and find a free one that is already
1568 existing on the stack */
1569 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1571 /* found a free one : just update & return */
1572 sym->usl.spillLoc = sloc;
1575 addSetHead (&sloc->usl.itmpStack, sym);
1579 /* could not then have to create one , this is the hard part
1580 we need to allocate this on the stack : this is really a
1581 hack!! but cannot think of anything better at this time */
1583 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1585 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1586 __FILE__, __LINE__);
1590 sloc = newiTemp (slocBuffer);
1592 /* set the type to the spilling symbol */
1593 sloc->type = copyLinkChain (sym->type);
1594 sloc->etype = getSpec (sloc->type);
1595 SPEC_SCLS (sloc->etype) = S_DATA;
1596 SPEC_EXTR (sloc->etype) = 0;
1597 SPEC_STAT (sloc->etype) = 0;
1599 /* we don't allow it to be allocated`
1600 onto the external stack since : so we
1601 temporarily turn it off ; we also
1602 turn off memory model to prevent
1603 the spil from going to the external storage
1604 and turn off overlaying
1607 useXstack = options.useXstack;
1608 model = options.model;
1609 noOverlay = options.noOverlay;
1610 options.noOverlay = 1;
1611 options.model = options.useXstack = 0;
1615 options.useXstack = useXstack;
1616 options.model = model;
1617 options.noOverlay = noOverlay;
1618 sloc->isref = 1; /* to prevent compiler warning */
1620 /* if it is on the stack then update the stack */
1621 if (IN_STACK (sloc->etype))
1623 currFunc->stack += getSize (sloc->type);
1624 _G.stackExtend += getSize (sloc->type);
1627 _G.dataExtend += getSize (sloc->type);
1629 /* add it to the _G.stackSpil set */
1630 addSetHead (&_G.stackSpil, sloc);
1631 sym->usl.spillLoc = sloc;
1634 /* add it to the set of itempStack set
1635 of the spill location */
1636 addSetHead (&sloc->usl.itmpStack, sym);
1640 /*-----------------------------------------------------------------*/
1641 /* isSpiltOnStack - returns true if the spil location is on stack */
1642 /*-----------------------------------------------------------------*/
1644 isSpiltOnStack (symbol * sym)
1648 debugLog ("%s\n", __FUNCTION__);
1655 /* if (sym->_G.stackSpil) */
1658 if (!sym->usl.spillLoc)
1661 etype = getSpec (sym->usl.spillLoc->type);
1662 if (IN_STACK (etype))
1668 /*-----------------------------------------------------------------*/
1669 /* spillThis - spils a specific operand */
1670 /*-----------------------------------------------------------------*/
1672 spillThis (symbol * sym)
1675 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1677 /* if this is rematerializable or has a spillLocation
1678 we are okay, else we need to create a spillLocation
1680 if (!(sym->remat || sym->usl.spillLoc))
1681 createStackSpil (sym);
1684 /* mark it has spilt & put it in the spilt set */
1686 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1688 bitVectUnSetBit (_G.regAssigned, sym->key);
1690 for (i = 0; i < sym->nRegs; i++)
1694 freeReg (sym->regs[i]);
1695 sym->regs[i] = NULL;
1698 /* if spilt on stack then free up r0 & r1
1699 if they could have been assigned to some
1701 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1704 spillLRWithPtrReg (sym);
1707 if (sym->usl.spillLoc && !sym->remat)
1708 sym->usl.spillLoc->allocreq = 1;
1712 /*-----------------------------------------------------------------*/
1713 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1714 /*-----------------------------------------------------------------*/
1716 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1718 bitVect *lrcs = NULL;
1722 debugLog ("%s\n", __FUNCTION__);
1723 /* get the spillable live ranges */
1724 lrcs = computeSpillable (ic);
1726 /* get all live ranges that are rematerizable */
1727 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1730 /* return the least used of these */
1731 return leastUsedLR (selectS);
1734 /* get live ranges with spillLocations in direct space */
1735 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1737 sym = leastUsedLR (selectS);
1738 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1739 sym->usl.spillLoc->rname :
1740 sym->usl.spillLoc->name));
1742 /* mark it as allocation required */
1743 sym->usl.spillLoc->allocreq = 1;
1747 /* if the symbol is local to the block then */
1748 if (forSym->liveTo < ebp->lSeq)
1751 /* check if there are any live ranges allocated
1752 to registers that are not used in this block */
1753 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1755 sym = leastUsedLR (selectS);
1756 /* if this is not rematerializable */
1765 /* check if there are any live ranges that not
1766 used in the remainder of the block */
1767 if (!_G.blockSpil &&
1768 !isiCodeInFunctionCall (ic) &&
1769 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1771 sym = leastUsedLR (selectS);
1774 sym->remainSpil = 1;
1781 /* find live ranges with spillocation && not used as pointers */
1782 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1785 sym = leastUsedLR (selectS);
1786 /* mark this as allocation required */
1787 sym->usl.spillLoc->allocreq = 1;
1791 /* find live ranges with spillocation */
1792 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1795 sym = leastUsedLR (selectS);
1796 sym->usl.spillLoc->allocreq = 1;
1800 /* couldn't find then we need to create a spil
1801 location on the stack , for which one? the least
1803 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1806 /* return a created spil location */
1807 sym = createStackSpil (leastUsedLR (selectS));
1808 sym->usl.spillLoc->allocreq = 1;
1812 /* this is an extreme situation we will spill
1813 this one : happens very rarely but it does happen */
1819 /*-----------------------------------------------------------------*/
1820 /* spilSomething - spil some variable & mark registers as free */
1821 /*-----------------------------------------------------------------*/
1823 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1828 debugLog ("%s\n", __FUNCTION__);
1829 /* get something we can spil */
1830 ssym = selectSpil (ic, ebp, forSym);
1832 /* mark it as spilt */
1834 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1836 /* mark it as not register assigned &
1837 take it away from the set */
1838 bitVectUnSetBit (_G.regAssigned, ssym->key);
1840 /* mark the registers as free */
1841 for (i = 0; i < ssym->nRegs; i++)
1843 freeReg (ssym->regs[i]);
1845 /* if spilt on stack then free up r0 & r1
1846 if they could have been assigned to as gprs */
1847 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1850 spillLRWithPtrReg (ssym);
1853 /* if this was a block level spil then insert push & pop
1854 at the start & end of block respectively */
1855 if (ssym->blockSpil)
1857 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1858 /* add push to the start of the block */
1859 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1860 ebp->sch->next : ebp->sch));
1861 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1862 /* add pop to the end of the block */
1863 addiCodeToeBBlock (ebp, nic, NULL);
1866 /* if spilt because not used in the remainder of the
1867 block then add a push before this instruction and
1868 a pop at the end of the block */
1869 if (ssym->remainSpil)
1872 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1873 /* add push just before this instruction */
1874 addiCodeToeBBlock (ebp, nic, ic);
1876 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1877 /* add pop to the end of the block */
1878 addiCodeToeBBlock (ebp, nic, NULL);
1887 /*-----------------------------------------------------------------*/
1888 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1889 /*-----------------------------------------------------------------*/
1891 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1896 debugLog ("%s\n", __FUNCTION__);
1898 /* try for a ptr type */
1899 if ((reg = allocReg (REG_PTR)))
1902 /* try for gpr type */
1903 if ((reg = allocReg (REG_GPR)))
1906 /* we have to spil */
1907 if (!spilSomething (ic, ebp, sym))
1910 /* make sure partially assigned registers aren't reused */
1911 for (j=0; j<=sym->nRegs; j++)
1913 sym->regs[j]->isFree = 0;
1915 /* this looks like an infinite loop but
1916 in really selectSpil will abort */
1920 /*-----------------------------------------------------------------*/
1921 /* getRegGpr - will try for GPR if not spil */
1922 /*-----------------------------------------------------------------*/
1924 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1929 debugLog ("%s\n", __FUNCTION__);
1931 /* try for gpr type */
1932 if ((reg = allocReg (REG_GPR)))
1935 if (!pic16_ptrRegReq)
1936 if ((reg = allocReg (REG_PTR)))
1939 /* we have to spil */
1940 if (!spilSomething (ic, ebp, sym))
1943 /* make sure partially assigned registers aren't reused */
1944 for (j=0; j<=sym->nRegs; j++)
1946 sym->regs[j]->isFree = 0;
1948 /* this looks like an infinite loop but
1949 in really selectSpil will abort */
1953 /*-----------------------------------------------------------------*/
1954 /* symHasReg - symbol has a given register */
1955 /*-----------------------------------------------------------------*/
1957 symHasReg (symbol * sym, regs * reg)
1961 debugLog ("%s\n", __FUNCTION__);
1962 for (i = 0; i < sym->nRegs; i++)
1963 if (sym->regs[i] == reg)
1969 /*-----------------------------------------------------------------*/
1970 /* deassignLRs - check the live to and if they have registers & are */
1971 /* not spilt then free up the registers */
1972 /*-----------------------------------------------------------------*/
1974 deassignLRs (iCode * ic, eBBlock * ebp)
1980 debugLog ("%s\n", __FUNCTION__);
1981 for (sym = hTabFirstItem (liveRanges, &k); sym;
1982 sym = hTabNextItem (liveRanges, &k))
1985 symbol *psym = NULL;
1986 /* if it does not end here */
1987 if (sym->liveTo > ic->seq)
1990 /* if it was spilt on stack then we can
1991 mark the stack spil location as free */
1996 sym->usl.spillLoc->isFree = 1;
2002 if (!bitVectBitValue (_G.regAssigned, sym->key))
2005 /* special case for shifting: there is a case where shift count
2006 * can be allocated in the same register as the result, so do not
2007 * free right registers if same as result registers, cause genShiftLeft
2008 * will fail -- VR */
2009 if(ic->op == LEFT_OP)
2012 /* special case check if this is an IFX &
2013 the privious one was a pop and the
2014 previous one was not spilt then keep track
2016 if (ic->op == IFX && ic->prev &&
2017 ic->prev->op == IPOP &&
2018 !ic->prev->parmPush &&
2019 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2020 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2026 bitVectUnSetBit (_G.regAssigned, sym->key);
2028 /* if the result of this one needs registers
2029 and does not have it then assign it right
2031 if (IC_RESULT (ic) &&
2032 !(SKIP_IC2 (ic) || /* not a special icode */
2033 ic->op == JUMPTABLE ||
2038 POINTER_SET (ic)) &&
2039 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2040 result->liveTo > ic->seq && /* and will live beyond this */
2041 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2042 result->liveFrom == ic->seq && /* does not start before here */
2043 result->regType == sym->regType && /* same register types */
2044 result->nRegs && /* which needs registers */
2045 !result->isspilt && /* and does not already have them */
2047 !bitVectBitValue (_G.regAssigned, result->key) &&
2048 /* the number of free regs + number of regs in this LR
2049 can accomodate the what result Needs */
2050 ((nfreeRegsType (result->regType) +
2051 sym->nRegs) >= result->nRegs)
2055 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2057 result->regs[i] = sym->regs[i];
2059 result->regs[i] = getRegGpr (ic, ebp, result);
2061 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2065 /* free the remaining */
2066 for (; i < sym->nRegs; i++)
2070 if (!symHasReg (psym, sym->regs[i]))
2071 freeReg (sym->regs[i]);
2074 freeReg (sym->regs[i]);
2081 /*-----------------------------------------------------------------*/
2082 /* reassignLR - reassign this to registers */
2083 /*-----------------------------------------------------------------*/
2085 reassignLR (operand * op)
2087 symbol *sym = OP_SYMBOL (op);
2090 debugLog ("%s\n", __FUNCTION__);
2091 /* not spilt any more */
2092 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2093 bitVectUnSetBit (_G.spiltSet, sym->key);
2095 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2099 for (i = 0; i < sym->nRegs; i++)
2100 sym->regs[i]->isFree = 0;
2103 /*-----------------------------------------------------------------*/
2104 /* willCauseSpill - determines if allocating will cause a spill */
2105 /*-----------------------------------------------------------------*/
2107 willCauseSpill (int nr, int rt)
2109 debugLog ("%s\n", __FUNCTION__);
2110 /* first check if there are any avlb registers
2111 of te type required */
2114 /* special case for pointer type
2115 if pointer type not avlb then
2116 check for type gpr */
2117 if (nFreeRegs (rt) >= nr)
2119 if (nFreeRegs (REG_GPR) >= nr)
2124 if (pic16_ptrRegReq)
2126 if (nFreeRegs (rt) >= nr)
2131 if (nFreeRegs (REG_PTR) +
2132 nFreeRegs (REG_GPR) >= nr)
2137 debugLog (" ... yep it will (cause a spill)\n");
2138 /* it will cause a spil */
2142 /*-----------------------------------------------------------------*/
2143 /* positionRegs - the allocator can allocate same registers to res- */
2144 /* ult and operand, if this happens make sure they are in the same */
2145 /* position as the operand otherwise chaos results */
2146 /*-----------------------------------------------------------------*/
2148 positionRegs (symbol * result, symbol * opsym, int lineno)
2150 int count = min (result->nRegs, opsym->nRegs);
2151 int i, j = 0, shared = 0;
2153 debugLog ("%s\n", __FUNCTION__);
2154 /* if the result has been spilt then cannot share */
2159 /* first make sure that they actually share */
2160 for (i = 0; i < count; i++)
2162 for (j = 0; j < count; j++)
2164 if (result->regs[i] == opsym->regs[j] && i != j)
2174 regs *tmp = result->regs[i];
2175 result->regs[i] = result->regs[j];
2176 result->regs[j] = tmp;
2181 /*------------------------------------------------------------------*/
2182 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2183 /* it should either have registers or have beed spilled. Otherwise, */
2184 /* there was an uninitialized variable, so just spill this to get */
2185 /* the operand in a valid state. */
2186 /*------------------------------------------------------------------*/
2188 verifyRegsAssigned (operand *op, iCode * ic)
2193 if (!IS_ITEMP (op)) return;
2195 sym = OP_SYMBOL (op);
2196 if (sym->isspilt) return;
2197 if (!sym->nRegs) return;
2198 if (sym->regs[0]) return;
2200 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2201 sym->prereqv ? sym->prereqv->name : sym->name);
2206 /*-----------------------------------------------------------------*/
2207 /* serialRegAssign - serially allocate registers to the variables */
2208 /*-----------------------------------------------------------------*/
2210 serialRegAssign (eBBlock ** ebbs, int count)
2214 debugLog ("%s\n", __FUNCTION__);
2215 /* for all blocks */
2216 for (i = 0; i < count; i++)
2221 if (ebbs[i]->noPath &&
2222 (ebbs[i]->entryLabel != entryLabel &&
2223 ebbs[i]->entryLabel != returnLabel))
2226 /* of all instructions do */
2227 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2230 debugLog (" op: %s\n", decodeOp (ic->op));
2232 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2233 pic16_allocDirReg(IC_RESULT(ic));
2235 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2236 pic16_allocDirReg(IC_LEFT(ic));
2238 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2239 pic16_allocDirReg(IC_RIGHT(ic));
2241 /* if this is an ipop that means some live
2242 range will have to be assigned again */
2244 reassignLR (IC_LEFT (ic));
2246 /* if result is present && is a true symbol */
2247 if (IC_RESULT (ic) && ic->op != IFX &&
2248 IS_TRUE_SYMOP (IC_RESULT (ic)))
2249 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2251 /* take away registers from live
2252 ranges that end at this instruction */
2253 deassignLRs (ic, ebbs[i]);
2255 /* some don't need registers */
2256 if (SKIP_IC2 (ic) ||
2257 ic->op == JUMPTABLE ||
2261 (IC_RESULT (ic) && POINTER_SET (ic)))
2264 /* now we need to allocate registers
2265 only for the result */
2268 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2274 /* if it does not need or is spilt
2275 or is already assigned to registers
2276 or will not live beyond this instructions */
2279 bitVectBitValue (_G.regAssigned, sym->key) ||
2280 sym->liveTo <= ic->seq)
2283 /* if some liverange has been spilt at the block level
2284 and this one live beyond this block then spil this
2286 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2291 /* if trying to allocate this will cause
2292 a spill and there is nothing to spill
2293 or this one is rematerializable then
2295 willCS = willCauseSpill (sym->nRegs, sym->regType);
2296 spillable = computeSpillable (ic);
2298 (willCS && bitVectIsZero (spillable)))
2306 /* If the live range preceeds the point of definition
2307 then ideally we must take into account registers that
2308 have been allocated after sym->liveFrom but freed
2309 before ic->seq. This is complicated, so spill this
2310 symbol instead and let fillGaps handle the allocation. */
2311 if (sym->liveFrom < ic->seq)
2317 /* if it has a spillocation & is used less than
2318 all other live ranges then spill this */
2320 if (sym->usl.spillLoc) {
2321 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2322 allLRs, ebbs[i], ic));
2323 if (leastUsed && leastUsed->used > sym->used) {
2328 /* if none of the liveRanges have a spillLocation then better
2329 to spill this one than anything else already assigned to registers */
2330 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2331 /* if this is local to this block then we might find a block spil */
2332 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2340 if (ic->op == RECEIVE)
2341 debugLog ("When I get clever, I'll optimize the receive logic\n");
2343 /* if we need ptr regs for the right side
2345 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2346 <= (unsigned) PTRSIZE)
2351 /* else we assign registers to it */
2352 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2355 bitVectDebugOn(_G.regAssigned, debugF);
2357 for (j = 0; j < sym->nRegs; j++)
2359 if (sym->regType == REG_PTR)
2360 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2362 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2364 /* if the allocation falied which means
2365 this was spilt then break */
2369 debugLog (" %d - \n", __LINE__);
2371 /* if it shares registers with operands make sure
2372 that they are in the same position */
2373 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2374 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2375 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2376 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2377 /* do the same for the right operand */
2378 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2379 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2380 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2381 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2383 debugLog (" %d - \n", __LINE__);
2386 debugLog (" %d - \n", __LINE__);
2395 /* Check for and fix any problems with uninitialized operands */
2396 for (i = 0; i < count; i++)
2400 if (ebbs[i]->noPath &&
2401 (ebbs[i]->entryLabel != entryLabel &&
2402 ebbs[i]->entryLabel != returnLabel))
2405 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2412 verifyRegsAssigned (IC_COND (ic), ic);
2416 if (ic->op == JUMPTABLE)
2418 verifyRegsAssigned (IC_JTCOND (ic), ic);
2422 verifyRegsAssigned (IC_RESULT (ic), ic);
2423 verifyRegsAssigned (IC_LEFT (ic), ic);
2424 verifyRegsAssigned (IC_RIGHT (ic), ic);
2430 /*-----------------------------------------------------------------*/
2431 /* rUmaskForOp :- returns register mask for an operand */
2432 /*-----------------------------------------------------------------*/
2434 rUmaskForOp (operand * op)
2440 debugLog ("%s\n", __FUNCTION__);
2441 /* only temporaries are assigned registers */
2445 sym = OP_SYMBOL (op);
2447 /* if spilt or no registers assigned to it
2449 if (sym->isspilt || !sym->nRegs)
2452 rumask = newBitVect (pic16_nRegs);
2454 for (j = 0; j < sym->nRegs; j++)
2456 rumask = bitVectSetBit (rumask,
2457 sym->regs[j]->rIdx);
2463 /*-----------------------------------------------------------------*/
2464 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2465 /*-----------------------------------------------------------------*/
2467 regsUsedIniCode (iCode * ic)
2469 bitVect *rmask = newBitVect (pic16_nRegs);
2471 debugLog ("%s\n", __FUNCTION__);
2472 /* do the special cases first */
2475 rmask = bitVectUnion (rmask,
2476 rUmaskForOp (IC_COND (ic)));
2480 /* for the jumptable */
2481 if (ic->op == JUMPTABLE)
2483 rmask = bitVectUnion (rmask,
2484 rUmaskForOp (IC_JTCOND (ic)));
2489 /* of all other cases */
2491 rmask = bitVectUnion (rmask,
2492 rUmaskForOp (IC_LEFT (ic)));
2496 rmask = bitVectUnion (rmask,
2497 rUmaskForOp (IC_RIGHT (ic)));
2500 rmask = bitVectUnion (rmask,
2501 rUmaskForOp (IC_RESULT (ic)));
2507 /*-----------------------------------------------------------------*/
2508 /* createRegMask - for each instruction will determine the regsUsed */
2509 /*-----------------------------------------------------------------*/
2511 createRegMask (eBBlock ** ebbs, int count)
2515 debugLog ("%s\n", __FUNCTION__);
2516 /* for all blocks */
2517 for (i = 0; i < count; i++)
2521 if (ebbs[i]->noPath &&
2522 (ebbs[i]->entryLabel != entryLabel &&
2523 ebbs[i]->entryLabel != returnLabel))
2526 /* for all instructions */
2527 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2532 if (SKIP_IC2 (ic) || !ic->rlive)
2535 /* first mark the registers used in this
2537 ic->rUsed = regsUsedIniCode (ic);
2538 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2540 /* now create the register mask for those
2541 registers that are in use : this is a
2542 super set of ic->rUsed */
2543 ic->rMask = newBitVect (pic16_nRegs + 1);
2545 /* for all live Ranges alive at this point */
2546 for (j = 1; j < ic->rlive->size; j++)
2551 /* if not alive then continue */
2552 if (!bitVectBitValue (ic->rlive, j))
2555 /* find the live range we are interested in */
2556 if (!(sym = hTabItemWithKey (liveRanges, j)))
2558 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2559 "createRegMask cannot find live range");
2563 /* if no register assigned to it */
2564 if (!sym->nRegs || sym->isspilt)
2567 /* for all the registers allocated to it */
2568 for (k = 0; k < sym->nRegs; k++)
2571 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2577 /*-----------------------------------------------------------------*/
2578 /* rematStr - returns the rematerialized string for a remat var */
2579 /*-----------------------------------------------------------------*/
2581 rematStr (symbol * sym)
2584 iCode *ic = sym->rematiCode;
2585 symbol *psym = NULL;
2587 debugLog ("%s\n", __FUNCTION__);
2589 //printf ("%s\n", s);
2591 /* if plus or minus print the right hand side */
2593 if (ic->op == '+' || ic->op == '-') {
2595 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2597 sprintf (s, "(%s %c 0x%04x)",
2598 OP_SYMBOL (IC_LEFT (ric))->rname,
2600 (int) operandLitValue (IC_RIGHT (ic)));
2603 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2605 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2606 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2611 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2612 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2614 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2619 /*-----------------------------------------------------------------*/
2620 /* rematStr - returns the rematerialized string for a remat var */
2621 /*-----------------------------------------------------------------*/
2623 rematStr (symbol * sym)
2626 iCode *ic = sym->rematiCode;
2628 debugLog ("%s\n", __FUNCTION__);
2633 /* if plus or minus print the right hand side */
2635 if (ic->op == '+' || ic->op == '-') {
2636 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2639 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2643 if (ic->op == '+' || ic->op == '-')
2645 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2646 sprintf (s, "(%s %c 0x%04x)",
2647 OP_SYMBOL (IC_LEFT (ric))->rname,
2649 (int) operandLitValue (IC_RIGHT (ic)));
2652 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2654 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2658 /* we reached the end */
2659 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2663 printf ("%s\n", buffer);
2668 /*-----------------------------------------------------------------*/
2669 /* regTypeNum - computes the type & number of registers required */
2670 /*-----------------------------------------------------------------*/
2678 debugLog ("%s\n", __FUNCTION__);
2679 /* for each live range do */
2680 for (sym = hTabFirstItem (liveRanges, &k); sym;
2681 sym = hTabNextItem (liveRanges, &k)) {
2683 debugLog (" %d - %s\n", __LINE__, sym->rname);
2684 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2686 /* if used zero times then no registers needed */
2687 if ((sym->liveTo - sym->liveFrom) == 0)
2691 /* if the live range is a temporary */
2694 debugLog (" %d - itemp register\n", __LINE__);
2696 /* if the type is marked as a conditional */
2697 if (sym->regType == REG_CND)
2700 /* if used in return only then we don't
2702 if (sym->ruonly || sym->accuse) {
2703 if (IS_AGGREGATE (sym->type) || sym->isptr)
2704 sym->type = aggrToPtr (sym->type, FALSE);
2705 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2709 /* if the symbol has only one definition &
2710 that definition is a get_pointer and the
2711 pointer we are getting is rematerializable and
2714 if (bitVectnBitsOn (sym->defs) == 1 &&
2715 (ic = hTabItemWithKey (iCodehTab,
2716 bitVectFirstBit (sym->defs))) &&
2718 !IS_BITVAR (sym->etype) &&
2719 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2721 if (ptrPseudoSymSafe (sym, ic)) {
2725 debugLog (" %d - \n", __LINE__);
2727 /* create a psuedo symbol & force a spil */
2728 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2729 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2730 psym->type = sym->type;
2731 psym->etype = sym->etype;
2732 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2733 strcpy (psym->rname, psym->name);
2735 sym->usl.spillLoc = psym;
2739 /* if in data space or idata space then try to
2740 allocate pointer register */
2744 /* if not then we require registers */
2745 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2746 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2747 getSize (sym->type));
2751 if(IS_PTR_CONST (sym->type)) {
2753 if(IS_CODEPTR (sym->type)) {
2755 // what IS this ???? (HJD)
2756 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2757 sym->nRegs = 3; // patch 14
2760 if (sym->nRegs > 4) {
2761 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2762 printTypeChain (sym->type, stderr);
2763 fprintf (stderr, "\n");
2766 /* determine the type of register required */
2767 if (sym->nRegs == 1 &&
2768 IS_PTR (sym->type) &&
2770 sym->regType = REG_PTR;
2772 sym->regType = REG_GPR;
2775 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2779 /* for the first run we don't provide */
2780 /* registers for true symbols we will */
2781 /* see how things go */
2787 static DEFSETFUNC (markRegFree)
2789 ((regs *)item)->isFree = 1;
2794 DEFSETFUNC (pic16_deallocReg)
2796 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2797 ((regs *)item)->isFree = 1;
2798 ((regs *)item)->wasUsed = 0;
2802 /*-----------------------------------------------------------------*/
2803 /* freeAllRegs - mark all registers as free */
2804 /*-----------------------------------------------------------------*/
2806 pic16_freeAllRegs ()
2808 debugLog ("%s\n", __FUNCTION__);
2810 applyToSet(pic16_dynAllocRegs,markRegFree);
2811 applyToSet(pic16_dynStackRegs,markRegFree);
2814 /*-----------------------------------------------------------------*/
2815 /*-----------------------------------------------------------------*/
2817 pic16_deallocateAllRegs ()
2819 debugLog ("%s\n", __FUNCTION__);
2821 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2825 /*-----------------------------------------------------------------*/
2826 /* deallocStackSpil - this will set the stack pointer back */
2827 /*-----------------------------------------------------------------*/
2829 DEFSETFUNC (deallocStackSpil)
2833 debugLog ("%s\n", __FUNCTION__);
2838 /*-----------------------------------------------------------------*/
2839 /* farSpacePackable - returns the packable icode for far variables */
2840 /*-----------------------------------------------------------------*/
2842 farSpacePackable (iCode * ic)
2846 debugLog ("%s\n", __FUNCTION__);
2847 /* go thru till we find a definition for the
2848 symbol on the right */
2849 for (dic = ic->prev; dic; dic = dic->prev)
2852 /* if the definition is a call then no */
2853 if ((dic->op == CALL || dic->op == PCALL) &&
2854 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2859 /* if shift by unknown amount then not */
2860 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2861 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2864 /* if pointer get and size > 1 */
2865 if (POINTER_GET (dic) &&
2866 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2869 if (POINTER_SET (dic) &&
2870 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2873 /* if any three is a true symbol in far space */
2874 if (IC_RESULT (dic) &&
2875 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2876 isOperandInFarSpace (IC_RESULT (dic)))
2879 if (IC_RIGHT (dic) &&
2880 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2881 isOperandInFarSpace (IC_RIGHT (dic)) &&
2882 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2885 if (IC_LEFT (dic) &&
2886 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2887 isOperandInFarSpace (IC_LEFT (dic)) &&
2888 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2891 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2893 if ((dic->op == LEFT_OP ||
2894 dic->op == RIGHT_OP ||
2896 IS_OP_LITERAL (IC_RIGHT (dic)))
2906 /*-----------------------------------------------------------------*/
2907 /* packRegsForAssign - register reduction for assignment */
2908 /*-----------------------------------------------------------------*/
2910 packRegsForAssign (iCode * ic, eBBlock * ebp)
2915 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2916 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2917 debugAopGet (" result:", IC_RESULT (ic));
2918 debugAopGet (" left:", IC_LEFT (ic));
2919 debugAopGet (" right:", IC_RIGHT (ic));
2921 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2923 debugLog(" %d - actuall processing\n", __LINE__ );
2925 if (!IS_ITEMP (IC_RESULT (ic))) {
2926 pic16_allocDirReg(IC_RESULT (ic));
2927 debugLog (" %d - result is not temp\n", __LINE__);
2931 /* See BUGLOG0001 - VR */
2933 if (!IS_ITEMP (IC_RIGHT (ic))) {
2934 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2935 pic16_allocDirReg(IC_RIGHT (ic));
2940 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2941 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2943 debugLog (" %d - not packing - right side fails \n", __LINE__);
2947 /* if the true symbol is defined in far space or on stack
2948 then we should not since this will increase register pressure */
2949 if (isOperandInFarSpace (IC_RESULT (ic)))
2951 if ((dic = farSpacePackable (ic)))
2958 /* find the definition of iTempNN scanning backwards if we find a
2959 a use of the true symbol before we find the definition then
2961 for (dic = ic->prev; dic; dic = dic->prev)
2964 /* if there is a function call and this is
2965 a parameter & not my parameter then don't pack it */
2966 if ((dic->op == CALL || dic->op == PCALL) &&
2967 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2968 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2970 debugLog (" %d - \n", __LINE__);
2979 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2981 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2982 IS_OP_VOLATILE (IC_RESULT (dic)))
2984 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2990 if( IS_SYMOP( IC_RESULT(dic)) &&
2991 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2993 debugLog (" %d - result is bitfield\n", __LINE__);
2999 if (IS_SYMOP (IC_RESULT (dic)) &&
3000 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3002 /* A previous result was assigned to the same register - we'll our definition */
3003 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3004 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3005 if (POINTER_SET (dic))
3011 if (IS_SYMOP (IC_RIGHT (dic)) &&
3012 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3013 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3015 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3020 if (IS_SYMOP (IC_LEFT (dic)) &&
3021 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3022 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3024 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3029 if (POINTER_SET (dic) &&
3030 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3032 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3040 return 0; /* did not find */
3043 /* This code is taken from the hc08 port. Do not know
3044 * if it fits for pic16, but I leave it here just in case */
3046 /* if assignment then check that right is not a bit */
3047 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3048 sym_link *etype = operandType (IC_RIGHT (dic));
3050 if (IS_BITFIELD (etype)) {
3051 /* if result is a bit too then it's ok */
3052 etype = operandType (IC_RESULT (dic));
3053 if (!IS_BITFIELD (etype)) {
3054 debugLog(" %d bitfields\n");
3061 /* if the result is on stack or iaccess then it must be
3062 the same atleast one of the operands */
3063 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3064 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3066 /* the operation has only one symbol
3067 operator then we can pack */
3068 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3069 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3072 if (!((IC_LEFT (dic) &&
3073 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3075 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3079 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3080 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3081 /* found the definition */
3082 /* replace the result with the result of */
3083 /* this assignment and remove this assignment */
3084 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3085 IC_RESULT (dic) = IC_RESULT (ic);
3087 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3089 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3091 /* delete from liverange table also
3092 delete from all the points inbetween and the new
3094 for (sic = dic; sic != ic; sic = sic->next)
3096 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3097 if (IS_ITEMP (IC_RESULT (dic)))
3098 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3101 remiCodeFromeBBlock (ebp, ic);
3102 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3104 debugLog(" %d\n", __LINE__ );
3105 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3106 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3114 #define NO_packRegsForAccUse
3115 #define NO_packRegsForSupport
3116 #define NO_packRegsForOneuse
3117 #define NO_cast_peep
3122 #ifndef NO_packRegsForSupport
3123 /*-----------------------------------------------------------------*/
3124 /* findAssignToSym : scanning backwards looks for first assig found */
3125 /*-----------------------------------------------------------------*/
3127 findAssignToSym (operand * op, iCode * ic)
3131 debugLog ("%s\n", __FUNCTION__);
3132 for (dic = ic->prev; dic; dic = dic->prev)
3135 /* if definition by assignment */
3136 if (dic->op == '=' &&
3137 !POINTER_SET (dic) &&
3138 IC_RESULT (dic)->key == op->key
3139 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3143 /* we are interested only if defined in far space */
3144 /* or in stack space in case of + & - */
3146 /* if assigned to a non-symbol then return
3148 if (!IS_SYMOP (IC_RIGHT (dic)))
3151 /* if the symbol is in far space then
3153 if (isOperandInFarSpace (IC_RIGHT (dic)))
3156 /* for + & - operations make sure that
3157 if it is on the stack it is the same
3158 as one of the three operands */
3159 if ((ic->op == '+' || ic->op == '-') &&
3160 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3162 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3163 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3164 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3172 /* if we find an usage then we cannot delete it */
3173 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3176 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3179 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3183 /* now make sure that the right side of dic
3184 is not defined between ic & dic */
3187 iCode *sic = dic->next;
3189 for (; sic != ic; sic = sic->next)
3190 if (IC_RESULT (sic) &&
3191 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3202 #ifndef NO_packRegsForSupport
3203 /*-----------------------------------------------------------------*/
3204 /* packRegsForSupport :- reduce some registers for support calls */
3205 /*-----------------------------------------------------------------*/
3207 packRegsForSupport (iCode * ic, eBBlock * ebp)
3211 debugLog ("%s\n", __FUNCTION__);
3212 /* for the left & right operand :- look to see if the
3213 left was assigned a true symbol in far space in that
3214 case replace them */
3215 if (IS_ITEMP (IC_LEFT (ic)) &&
3216 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3218 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3224 debugAopGet ("removing left:", IC_LEFT (ic));
3226 /* found it we need to remove it from the
3228 for (sic = dic; sic != ic; sic = sic->next)
3229 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3231 IC_LEFT (ic)->operand.symOperand =
3232 IC_RIGHT (dic)->operand.symOperand;
3233 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3234 remiCodeFromeBBlock (ebp, dic);
3235 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3236 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3240 /* do the same for the right operand */
3243 IS_ITEMP (IC_RIGHT (ic)) &&
3244 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3246 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3252 /* if this is a subtraction & the result
3253 is a true symbol in far space then don't pack */
3254 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3256 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3257 if (IN_FARSPACE (SPEC_OCLS (etype)))
3261 debugAopGet ("removing right:", IC_RIGHT (ic));
3263 /* found it we need to remove it from the
3265 for (sic = dic; sic != ic; sic = sic->next)
3266 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3268 IC_RIGHT (ic)->operand.symOperand =
3269 IC_RIGHT (dic)->operand.symOperand;
3270 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3272 remiCodeFromeBBlock (ebp, dic);
3273 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3274 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3283 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3285 #ifndef NO_packRegsForOneuse
3286 /*-----------------------------------------------------------------*/
3287 /* packRegsForOneuse : - will reduce some registers for single Use */
3288 /*-----------------------------------------------------------------*/
3290 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3295 debugLog ("%s\n", __FUNCTION__);
3296 /* if returning a literal then do nothing */
3300 /* only upto 2 bytes since we cannot predict
3301 the usage of b, & acc */
3302 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3307 /* this routine will mark the a symbol as used in one
3308 instruction use only && if the definition is local
3309 (ie. within the basic block) && has only one definition &&
3310 that definition is either a return value from a
3311 function or does not contain any variables in
3313 uses = bitVectCopy (OP_USES (op));
3314 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3315 if (!bitVectIsZero (uses)) /* has other uses */
3318 /* if it has only one defintion */
3319 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3320 return NULL; /* has more than one definition */
3322 /* get that definition */
3324 hTabItemWithKey (iCodehTab,
3325 bitVectFirstBit (OP_DEFS (op)))))
3328 /* found the definition now check if it is local */
3329 if (dic->seq < ebp->fSeq ||
3330 dic->seq > ebp->lSeq)
3331 return NULL; /* non-local */
3333 /* now check if it is the return from
3335 if (dic->op == CALL || dic->op == PCALL)
3337 if (ic->op != SEND && ic->op != RETURN &&
3338 !POINTER_SET(ic) && !POINTER_GET(ic))
3340 OP_SYMBOL (op)->ruonly = 1;
3347 /* otherwise check that the definition does
3348 not contain any symbols in far space */
3349 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3350 isOperandInFarSpace (IC_RIGHT (dic)) ||
3351 IS_OP_RUONLY (IC_LEFT (ic)) ||
3352 IS_OP_RUONLY (IC_RIGHT (ic)))
3357 /* if pointer set then make sure the pointer
3359 if (POINTER_SET (dic) &&
3360 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3363 if (POINTER_GET (dic) &&
3364 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3369 /* also make sure the intervenening instructions
3370 don't have any thing in far space */
3371 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3374 /* if there is an intervening function call then no */
3375 if (dic->op == CALL || dic->op == PCALL)
3377 /* if pointer set then make sure the pointer
3379 if (POINTER_SET (dic) &&
3380 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3383 if (POINTER_GET (dic) &&
3384 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3387 /* if address of & the result is remat then okay */
3388 if (dic->op == ADDRESS_OF &&
3389 OP_SYMBOL (IC_RESULT (dic))->remat)
3392 /* if operand has size of three or more & this
3393 operation is a '*','/' or '%' then 'b' may
3395 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3396 getSize (operandType (op)) >= 3)
3399 /* if left or right or result is in far space */
3400 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3401 isOperandInFarSpace (IC_RIGHT (dic)) ||
3402 isOperandInFarSpace (IC_RESULT (dic)) ||
3403 IS_OP_RUONLY (IC_LEFT (dic)) ||
3404 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3405 IS_OP_RUONLY (IC_RESULT (dic)))
3411 OP_SYMBOL (op)->ruonly = 1;
3418 /*-----------------------------------------------------------------*/
3419 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3420 /*-----------------------------------------------------------------*/
3422 isBitwiseOptimizable (iCode * ic)
3424 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3425 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3427 debugLog ("%s\n", __FUNCTION__);
3428 /* bitwise operations are considered optimizable
3429 under the following conditions (Jean-Louis VERN)
3441 if (IS_LITERAL (rtype) ||
3442 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3449 #ifndef NO_packRegsForAccUse
3451 /*-----------------------------------------------------------------*/
3452 /* packRegsForAccUse - pack registers for acc use */
3453 /*-----------------------------------------------------------------*/
3455 packRegsForAccUse (iCode * ic)
3459 debugLog ("%s\n", __FUNCTION__);
3461 /* if this is an aggregate, e.g. a one byte char array */
3462 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3465 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3467 /* if + or - then it has to be one byte result */
3468 if ((ic->op == '+' || ic->op == '-')
3469 && getSize (operandType (IC_RESULT (ic))) > 1)
3472 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3473 /* if shift operation make sure right side is not a literal */
3474 if (ic->op == RIGHT_OP &&
3475 (isOperandLiteral (IC_RIGHT (ic)) ||
3476 getSize (operandType (IC_RESULT (ic))) > 1))
3479 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3480 if (ic->op == LEFT_OP &&
3481 (isOperandLiteral (IC_RIGHT (ic)) ||
3482 getSize (operandType (IC_RESULT (ic))) > 1))
3485 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3486 if (IS_BITWISE_OP (ic) &&
3487 getSize (operandType (IC_RESULT (ic))) > 1)
3491 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3492 /* has only one definition */
3493 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3496 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3497 /* has only one use */
3498 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3501 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3502 /* and the usage immediately follows this iCode */
3503 if (!(uic = hTabItemWithKey (iCodehTab,
3504 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3507 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3508 if (ic->next != uic)
3511 /* if it is a conditional branch then we definitely can */
3515 if (uic->op == JUMPTABLE)
3518 /* if the usage is not is an assignment
3519 or an arithmetic / bitwise / shift operation then not */
3520 if (POINTER_SET (uic) &&
3521 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3524 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3525 if (uic->op != '=' &&
3526 !IS_ARITHMETIC_OP (uic) &&
3527 !IS_BITWISE_OP (uic) &&
3528 uic->op != LEFT_OP &&
3529 uic->op != RIGHT_OP)
3532 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3533 /* if used in ^ operation then make sure right is not a
3535 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3538 /* if shift operation make sure right side is not a literal */
3539 if (uic->op == RIGHT_OP &&
3540 (isOperandLiteral (IC_RIGHT (uic)) ||
3541 getSize (operandType (IC_RESULT (uic))) > 1))
3544 if (uic->op == LEFT_OP &&
3545 (isOperandLiteral (IC_RIGHT (uic)) ||
3546 getSize (operandType (IC_RESULT (uic))) > 1))
3549 /* make sure that the result of this icode is not on the
3550 stack, since acc is used to compute stack offset */
3551 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3552 OP_SYMBOL (IC_RESULT (uic))->onStack)
3555 /* if either one of them in far space then we cannot */
3556 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3557 isOperandInFarSpace (IC_LEFT (uic))) ||
3558 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3559 isOperandInFarSpace (IC_RIGHT (uic))))
3562 /* if the usage has only one operand then we can */
3563 if (IC_LEFT (uic) == NULL ||
3564 IC_RIGHT (uic) == NULL)
3567 /* make sure this is on the left side if not
3568 a '+' since '+' is commutative */
3569 if (ic->op != '+' &&
3570 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3574 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3575 /* if one of them is a literal then we can */
3576 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3577 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3578 (getSize (operandType (IC_RESULT (uic))) <= 1))
3580 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3585 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3586 /* if the other one is not on stack then we can */
3587 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3588 (IS_ITEMP (IC_RIGHT (uic)) ||
3589 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3590 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3593 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3594 (IS_ITEMP (IC_LEFT (uic)) ||
3595 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3596 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3602 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3603 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3610 /*-----------------------------------------------------------------*/
3611 /* packForPush - hueristics to reduce iCode for pushing */
3612 /*-----------------------------------------------------------------*/
3614 packForReceive (iCode * ic, eBBlock * ebp)
3618 debugLog ("%s\n", __FUNCTION__);
3619 debugAopGet (" result:", IC_RESULT (ic));
3620 debugAopGet (" left:", IC_LEFT (ic));
3621 debugAopGet (" right:", IC_RIGHT (ic));
3626 for (dic = ic->next; dic; dic = dic->next)
3631 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3632 debugLog (" used on left\n");
3633 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3634 debugLog (" used on right\n");
3635 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3636 debugLog (" used on result\n");
3638 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3639 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3644 debugLog (" hey we can remove this unnecessary assign\n");
3646 /*-----------------------------------------------------------------*/
3647 /* packForPush - hueristics to reduce iCode for pushing */
3648 /*-----------------------------------------------------------------*/
3650 packForPush (iCode * ic, eBBlock * ebp)
3654 debugLog ("%s\n", __FUNCTION__);
3655 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3662 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3663 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3664 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3665 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3669 /* must have only definition & one usage */
3670 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3671 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3674 /* find the definition */
3675 if (!(dic = hTabItemWithKey (iCodehTab,
3676 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3679 /* if definition is not assignment,
3680 * or is not pointer (because pointer might have changed) */
3681 if (dic->op != '=' || POINTER_SET (dic))
3684 /* we must ensure that we can use the delete the assignment,
3685 * because the source might have been modified in between.
3686 * Until I know how to fix this, I'll use the adhoc fix
3687 * to check the liveranges */
3688 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3690 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3694 /* we now we know that it has one & only one def & use
3695 and the that the definition is an assignment */
3696 IC_LEFT (ic) = IC_RIGHT (dic);
3698 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3700 remiCodeFromeBBlock (ebp, dic);
3701 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3702 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3705 static void printSymType(char * str, sym_link *sl)
3707 if(!pic16_ralloc_debug)return;
3709 debugLog (" %s Symbol type: ",str);
3710 printTypeChain( sl, debugF);
3714 /*-----------------------------------------------------------------*/
3715 /* some debug code to print the symbol S_TYPE. Note that
3716 * the function checkSClass in src/SDCCsymt.c dinks with
3717 * the S_TYPE in ways the PIC port doesn't fully like...*/
3718 /*-----------------------------------------------------------------*/
3719 static void isData(sym_link *sl)
3723 if(!pic16_ralloc_debug)return;
3730 for ( ; sl; sl=sl->next) {
3732 switch (SPEC_SCLS(sl)) {
3733 case S_DATA: fprintf (of, "data "); break;
3734 case S_XDATA: fprintf (of, "xdata "); break;
3735 case S_SFR: fprintf (of, "sfr "); break;
3736 case S_SBIT: fprintf (of, "sbit "); break;
3737 case S_CODE: fprintf (of, "code "); break;
3738 case S_IDATA: fprintf (of, "idata "); break;
3739 case S_PDATA: fprintf (of, "pdata "); break;
3740 case S_LITERAL: fprintf (of, "literal "); break;
3741 case S_STACK: fprintf (of, "stack "); break;
3742 case S_XSTACK: fprintf (of, "xstack "); break;
3743 case S_BIT: fprintf (of, "bit "); break;
3744 case S_EEPROM: fprintf (of, "eeprom "); break;
3752 /*--------------------------------------------------------------------*/
3753 /* pic16_packRegisters - does some transformations to reduce */
3754 /* register pressure */
3756 /*--------------------------------------------------------------------*/
3758 pic16_packRegisters (eBBlock * ebp)
3763 debugLog ("%s\n", __FUNCTION__);
3769 /* look for assignments of the form */
3770 /* iTempNN = TRueSym (someoperation) SomeOperand */
3772 /* TrueSym := iTempNN:1 */
3773 for (ic = ebp->sch; ic; ic = ic->next)
3775 // debugLog("%d\n", __LINE__);
3776 /* find assignment of the form TrueSym := iTempNN:1 */
3777 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3778 change += packRegsForAssign (ic, ebp);
3782 if (POINTER_SET (ic))
3783 debugLog ("pointer is set\n");
3784 debugAopGet (" result:", IC_RESULT (ic));
3785 debugAopGet (" left:", IC_LEFT (ic));
3786 debugAopGet (" right:", IC_RIGHT (ic));
3795 for (ic = ebp->sch; ic; ic = ic->next) {
3797 if(IS_SYMOP ( IC_LEFT(ic))) {
3798 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3800 debugAopGet ("x left:", IC_LEFT (ic));
3802 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3804 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3806 debugLog (" is a pointer\n");
3808 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3809 debugLog (" is a ptr\n");
3811 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3812 debugLog (" is volatile\n");
3816 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3817 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3818 pic16_allocDirReg(IC_LEFT (ic));
3821 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3824 if(IS_SYMOP ( IC_RIGHT(ic))) {
3825 debugAopGet (" right:", IC_RIGHT (ic));
3826 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3829 if(IS_SYMOP ( IC_RESULT(ic))) {
3830 debugAopGet (" result:", IC_RESULT (ic));
3831 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3834 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3835 debugAopGet (" right:", IC_RIGHT (ic));
3836 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3837 // pic16_allocDirReg(IC_RIGHT(ic));
3840 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3841 debugAopGet (" result:", IC_RESULT (ic));
3842 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3843 // pic16_allocDirReg(IC_RESULT(ic));
3847 if (POINTER_SET (ic))
3848 debugLog (" %d - Pointer set\n", __LINE__);
3850 /* Look for two subsequent iCodes with */
3852 /* _c = iTemp & op; */
3853 /* and replace them by */
3856 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3858 && ic->prev->op == '='
3859 && IS_ITEMP (IC_LEFT (ic))
3860 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3861 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3863 iCode* ic_prev = ic->prev;
3864 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3866 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3867 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
3868 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3869 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3870 prev_result_sym->liveTo == ic->seq)
3872 prev_result_sym->liveTo = ic_prev->seq;
3875 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3877 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3879 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
3880 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3881 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3882 remiCodeFromeBBlock (ebp, ic_prev);
3883 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3887 /* if this is an itemp & result of a address of a true sym
3888 then mark this as rematerialisable */
3889 if (ic->op == ADDRESS_OF &&
3890 IS_ITEMP (IC_RESULT (ic)) &&
3891 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3892 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3893 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3896 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3898 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3899 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3900 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3904 /* if straight assignment then carry remat flag if
3905 this is the only definition */
3906 if (ic->op == '=' &&
3907 !POINTER_SET (ic) &&
3908 IS_SYMOP (IC_RIGHT (ic)) &&
3909 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3910 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3912 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3914 OP_SYMBOL (IC_RESULT (ic))->remat =
3915 OP_SYMBOL (IC_RIGHT (ic))->remat;
3916 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3917 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3920 /* if this is a +/- operation with a rematerizable
3921 then mark this as rematerializable as well */
3922 if ((ic->op == '+' || ic->op == '-') &&
3923 (IS_SYMOP (IC_LEFT (ic)) &&
3924 IS_ITEMP (IC_RESULT (ic)) &&
3925 OP_SYMBOL (IC_LEFT (ic))->remat &&
3926 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3927 IS_OP_LITERAL (IC_RIGHT (ic))))
3929 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3931 operandLitValue (IC_RIGHT (ic));
3932 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3933 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3934 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3937 /* mark the pointer usages */
3938 if (POINTER_SET (ic))
3940 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3941 debugLog (" marking as a pointer (set) =>");
3942 debugAopGet (" result:", IC_RESULT (ic));
3944 if (POINTER_GET (ic))
3946 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3947 debugLog (" marking as a pointer (get) =>");
3948 debugAopGet (" left:", IC_LEFT (ic));
3951 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3955 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3956 /* if we are using a symbol on the stack
3957 then we should say pic16_ptrRegReq */
3958 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3959 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3960 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3961 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3962 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3963 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3967 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3968 if (IS_SYMOP (IC_LEFT (ic)))
3969 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3970 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3971 if (IS_SYMOP (IC_RIGHT (ic)))
3972 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3973 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3974 if (IS_SYMOP (IC_RESULT (ic)))
3975 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3976 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3979 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3983 /* if the condition of an if instruction
3984 is defined in the previous instruction then
3985 mark the itemp as a conditional */
3986 if ((IS_CONDITIONAL (ic) ||
3987 ((ic->op == BITWISEAND ||
3990 isBitwiseOptimizable (ic))) &&
3991 ic->next && ic->next->op == IFX &&
3992 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3993 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3996 debugLog (" %d\n", __LINE__);
3997 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4001 debugLog(" %d\n", __LINE__);
4003 #ifndef NO_packRegsForSupport
4004 /* reduce for support function calls */
4005 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4006 packRegsForSupport (ic, ebp);
4009 /* if a parameter is passed, it's in W, so we may not
4010 need to place a copy in a register */
4011 if (ic->op == RECEIVE)
4012 packForReceive (ic, ebp);
4014 #ifndef NO_packRegsForOneuse
4015 /* some cases the redundant moves can
4016 can be eliminated for return statements */
4017 if ((ic->op == RETURN || ic->op == SEND) &&
4018 !isOperandInFarSpace (IC_LEFT (ic)) &&
4020 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4023 #ifndef NO_packRegsForOneuse
4024 /* if pointer set & left has a size more than
4025 one and right is not in far space */
4026 if (POINTER_SET (ic) &&
4027 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4028 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4029 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4030 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4032 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4035 #ifndef NO_packRegsForOneuse
4036 /* if pointer get */
4037 if (POINTER_GET (ic) &&
4038 !isOperandInFarSpace (IC_RESULT (ic)) &&
4039 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4040 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4041 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4043 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4044 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4047 #ifndef NO_cast_peep
4048 /* if this is cast for intergral promotion then
4049 check if only use of the definition of the
4050 operand being casted/ if yes then replace
4051 the result of that arithmetic operation with
4052 this result and get rid of the cast */
4053 if (ic->op == CAST) {
4055 sym_link *fromType = operandType (IC_RIGHT (ic));
4056 sym_link *toType = operandType (IC_LEFT (ic));
4058 debugLog (" %d - casting\n", __LINE__);
4060 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4061 getSize (fromType) != getSize (toType)) {
4064 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4067 if (IS_ARITHMETIC_OP (dic)) {
4068 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4070 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4071 IC_RESULT (dic) = IC_RESULT (ic);
4072 remiCodeFromeBBlock (ebp, ic);
4073 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4074 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4075 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4079 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4083 /* if the type from and type to are the same
4084 then if this is the only use then packit */
4085 if (compareType (operandType (IC_RIGHT (ic)),
4086 operandType (IC_LEFT (ic))) == 1) {
4088 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4091 debugLog(" %d\n", __LINE__);
4093 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4094 IC_RESULT (dic) = IC_RESULT (ic);
4095 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4096 remiCodeFromeBBlock (ebp, ic);
4097 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4098 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4107 /* there are some problems with packing variables
4108 * it seems that the live range estimator doesn't
4109 * estimate correctly the liveranges of some symbols */
4112 iTempNN := (some variable in farspace) V1
4117 if (ic->op == IPUSH)
4119 packForPush (ic, ebp);
4123 #ifndef NO_packRegsForAccUse
4124 /* pack registers for accumulator use, when the
4125 result of an arithmetic or bit wise operation
4126 has only one use, that use is immediately following
4127 the defintion and the using iCode has only one
4128 operand or has two operands but one is literal &
4129 the result of that operation is not on stack then
4130 we can leave the result of this operation in acc:b
4132 if ((IS_ARITHMETIC_OP (ic)
4134 || IS_BITWISE_OP (ic)
4136 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4139 IS_ITEMP (IC_RESULT (ic)) &&
4140 getSize (operandType (IC_RESULT (ic))) <= 1)
4142 packRegsForAccUse (ic);
4149 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4153 if (!pic16_ralloc_debug || !debugF)
4156 for (i = 0; i < count; i++)
4158 fprintf (debugF, "\n----------------------------------------------------------------\n");
4159 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4160 ebbs[i]->entryLabel->name,
4163 ebbs[i]->isLastInLoop);
4164 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4169 fprintf (debugF, "visited %d : hasFcall = %d\n",
4173 fprintf (debugF, "\ndefines bitVector :");
4174 bitVectDebugOn (ebbs[i]->defSet, debugF);
4175 fprintf (debugF, "\nlocal defines bitVector :");
4176 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4177 fprintf (debugF, "\npointers Set bitvector :");
4178 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4179 fprintf (debugF, "\nin pointers Set bitvector :");
4180 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4181 fprintf (debugF, "\ninDefs Set bitvector :");
4182 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4183 fprintf (debugF, "\noutDefs Set bitvector :");
4184 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4185 fprintf (debugF, "\nusesDefs Set bitvector :");
4186 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4187 fprintf (debugF, "\n----------------------------------------------------------------\n");
4188 printiCChain (ebbs[i]->sch, debugF);
4191 /*-----------------------------------------------------------------*/
4192 /* pic16_assignRegisters - assigns registers to each live range as need */
4193 /*-----------------------------------------------------------------*/
4195 pic16_assignRegisters (eBBlock ** ebbs, int count)
4200 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4201 debugLog ("\nebbs before optimizing:\n");
4202 dumpEbbsToDebug (ebbs, count);
4204 _inRegAllocator = 1;
4206 setToNull ((void *) &_G.funcrUsed);
4207 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4210 /* change assignments this will remove some
4211 live ranges reducing some register pressure */
4212 for (i = 0; i < count; i++)
4213 pic16_packRegisters (ebbs[i]);
4220 debugLog("dir registers allocated so far:\n");
4221 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4224 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4225 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4226 reg = hTabNextItem(dynDirectRegNames, &hkey);
4231 /* liveranges probably changed by register packing
4232 so we compute them again */
4233 recomputeLiveRanges (ebbs, count);
4235 if (options.dump_pack)
4236 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4238 /* first determine for each live range the number of
4239 registers & the type of registers required for each */
4242 /* and serially allocate registers */
4243 serialRegAssign (ebbs, count);
4246 debugLog ("ebbs after serialRegAssign:\n");
4247 dumpEbbsToDebug (ebbs, count);
4250 //pic16_freeAllRegs();
4252 /* if stack was extended then tell the user */
4255 /* werror(W_TOOMANY_SPILS,"stack", */
4256 /* _G.stackExtend,currFunc->name,""); */
4262 /* werror(W_TOOMANY_SPILS,"data space", */
4263 /* _G.dataExtend,currFunc->name,""); */
4267 /* after that create the register mask
4268 for each of the instruction */
4269 createRegMask (ebbs, count);
4271 /* redo that offsets for stacked automatic variables */
4272 redoStackOffsets ();
4274 if (options.dump_rassgn)
4275 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4277 /* now get back the chain */
4278 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4280 debugLog ("ebbs after optimizing:\n");
4281 dumpEbbsToDebug (ebbs, count);
4283 _inRegAllocator = 0;
4287 /* free up any _G.stackSpil locations allocated */
4288 applyToSet (_G.stackSpil, deallocStackSpil);
4290 setToNull ((void *) &_G.stackSpil);
4291 setToNull ((void *) &_G.spiltSet);
4292 /* mark all registers as free */
4293 pic16_freeAllRegs ();
4296 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");