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);
884 checkAddReg(&pic16_dynDirectRegs, reg);
888 // debugLog (" -- %s is declared at address 0x30000x\n",name);
889 return (reg); /* This was NULL before, but since we found it
890 * why not just return it?! */
893 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
895 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
897 /* work around for user defined registers in access bank */
898 if((reg->address>= 0x00 && reg->address < 0x80)
899 || (reg->address >= 0xf80 && reg->address <= 0xfff))
902 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
908 /*-----------------------------------------------------------------*/
909 /* pic16_allocRegByName - allocates register of given type */
910 /*-----------------------------------------------------------------*/
912 pic16_allocRegByName (char *name, int size, operand *op)
918 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
922 /* First, search the hash table to see if there is a register with this name */
923 reg = pic16_dirregWithName(name);
927 /* Register wasn't found in hash, so let's create
928 * a new one and put it in the hash table AND in the
929 * dynDirectRegNames set */
931 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
933 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
935 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
936 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
938 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
939 addSet(&pic16_dynDirectRegs, reg);
945 /*-----------------------------------------------------------------*/
946 /* RegWithIdx - returns pointer to register with index number */
947 /*-----------------------------------------------------------------*/
948 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
953 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
954 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
959 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
961 debugLog ("Found a Dynamic Register!\n");
964 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
965 debugLog ("Found a Direct Register!\n");
971 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
972 debugLog ("Found a Stack Register!\n");
977 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
978 debugLog ("Found a Processor Register!\n");
992 /*-----------------------------------------------------------------*/
993 /* pic16_regWithIdx - returns pointer to register with index number*/
994 /*-----------------------------------------------------------------*/
996 pic16_regWithIdx (int idx)
1000 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1003 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1007 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1014 /*-----------------------------------------------------------------*/
1015 /* pic16_regWithIdx - returns pointer to register with index number */
1016 /*-----------------------------------------------------------------*/
1018 pic16_allocWithIdx (int idx)
1023 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1024 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1026 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1028 debugLog ("Found a Dynamic Register!\n");
1029 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1030 debugLog ("Found a Stack Register!\n");
1031 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1032 debugLog ("Found a Processor Register!\n");
1033 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1034 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1035 debugLog ("Found an Internal Register!\n");
1038 debugLog ("Dynamic Register not found\n");
1041 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1042 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1043 "regWithIdx not found");
1053 /*-----------------------------------------------------------------*/
1054 /*-----------------------------------------------------------------*/
1056 pic16_findFreeReg(short type)
1063 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1065 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1069 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1081 /*-----------------------------------------------------------------*/
1082 /* freeReg - frees a register */
1083 /*-----------------------------------------------------------------*/
1085 freeReg (regs * reg)
1087 debugLog ("%s\n", __FUNCTION__);
1088 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1093 /*-----------------------------------------------------------------*/
1094 /* nFreeRegs - returns number of free registers */
1095 /*-----------------------------------------------------------------*/
1097 nFreeRegs (int type)
1103 /* although I fixed the register allocation/freeing scheme
1104 * the for loop below doesn't give valid results. I do not
1105 * know why yet. -- VR 10-Jan-2003 */
1110 /* dynamically allocate as many as we need and worry about
1111 * fitting them into a PIC later */
1113 debugLog ("%s\n", __FUNCTION__);
1115 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1116 if((reg->type == type) && reg->isFree)nfr++;
1118 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1122 /*-----------------------------------------------------------------*/
1123 /* nfreeRegsType - free registers with type */
1124 /*-----------------------------------------------------------------*/
1126 nfreeRegsType (int type)
1129 debugLog ("%s\n", __FUNCTION__);
1130 if (type == REG_PTR)
1132 if ((nfr = nFreeRegs (type)) == 0)
1133 return nFreeRegs (REG_GPR);
1136 return nFreeRegs (type);
1139 static void writeSetUsedRegs(FILE *of, set *dRegs)
1144 for (dReg = setFirstItem(dRegs) ; dReg ;
1145 dReg = setNextItem(dRegs)) {
1148 fprintf (of, "\t%s\n",dReg->name);
1154 extern void pic16_groupRegistersInSection(set *regset);
1156 extern void pic16_dump_equates(FILE *of, set *equs);
1157 extern void pic16_dump_access(FILE *of, set *section);
1158 //extern void pic16_dump_map(void);
1159 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1160 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1161 extern void pic16_dump_int_registers(FILE *of, set *section);
1162 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1164 extern void pic16_dump_gsection(FILE *of, set *sections);
1166 static void packBits(set *bregs)
1170 regs *bitfield=NULL;
1171 regs *relocbitfield=NULL;
1177 for (regset = bregs ; regset ;
1178 regset = regset->next) {
1180 breg = regset->item;
1181 breg->isBitField = 1;
1182 //fprintf(stderr,"bit reg: %s\n",breg->name);
1185 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1187 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1188 breg->rIdx = breg->address & 7;
1189 breg->address >>= 3;
1192 sprintf (buffer, "fbitfield%02x", breg->address);
1193 //fprintf(stderr,"new bit field\n");
1194 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1195 bitfield->isBitField = 1;
1196 bitfield->isFixed = 1;
1197 bitfield->address = breg->address;
1198 addSet(&pic16_dynDirectRegs,bitfield);
1199 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1201 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1204 breg->reg_alias = bitfield;
1208 if(!relocbitfield || bit_no >7) {
1211 sprintf (buffer, "bitfield%d", byte_no);
1212 //fprintf(stderr,"new relocatable bit field\n");
1213 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1214 relocbitfield->isBitField = 1;
1215 addSet(&pic16_dynDirectRegs,relocbitfield);
1216 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1220 breg->reg_alias = relocbitfield;
1221 breg->address = rDirectIdx; /* byte_no; */
1222 breg->rIdx = bit_no++;
1228 void pic16_writeUsedRegs(FILE *of)
1230 packBits(pic16_dynDirectBitRegs);
1232 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1233 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1235 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1236 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1238 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1239 pic16_groupRegistersInSection(pic16_dynStackRegs);
1241 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1242 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1244 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1245 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1247 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1248 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1250 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1251 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1254 pic16_dump_equates(of, pic16_equ_data);
1256 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1257 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1259 /* dump access bank symbols */
1260 pic16_dump_access(of, pic16_acs_udata);
1262 /* dump initialised data */
1263 pic16_dump_isection(of, rel_idataSymSet, 0);
1264 pic16_dump_isection(of, fix_idataSymSet, 1);
1266 /* dump internal registers */
1267 pic16_dump_int_registers(of, pic16_int_regs);
1269 /* dump generic section variables */
1270 pic16_dump_gsection(of, sectNames);
1272 /* dump other variables */
1273 pic16_dump_usection(of, pic16_rel_udata, 0);
1274 pic16_dump_usection(of, pic16_fix_udata, 1);
1279 /*-----------------------------------------------------------------*/
1280 /* computeSpillable - given a point find the spillable live ranges */
1281 /*-----------------------------------------------------------------*/
1283 computeSpillable (iCode * ic)
1287 debugLog ("%s\n", __FUNCTION__);
1288 /* spillable live ranges are those that are live at this
1289 point . the following categories need to be subtracted
1291 a) - those that are already spilt
1292 b) - if being used by this one
1293 c) - defined by this one */
1295 spillable = bitVectCopy (ic->rlive);
1297 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1299 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1300 bitVectUnSetBit (spillable, ic->defKey);
1301 spillable = bitVectIntersect (spillable, _G.regAssigned);
1306 /*-----------------------------------------------------------------*/
1307 /* noSpilLoc - return true if a variable has no spil location */
1308 /*-----------------------------------------------------------------*/
1310 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1312 debugLog ("%s\n", __FUNCTION__);
1313 return (sym->usl.spillLoc ? 0 : 1);
1316 /*-----------------------------------------------------------------*/
1317 /* hasSpilLoc - will return 1 if the symbol has spil location */
1318 /*-----------------------------------------------------------------*/
1320 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1322 debugLog ("%s\n", __FUNCTION__);
1323 return (sym->usl.spillLoc ? 1 : 0);
1326 /*-----------------------------------------------------------------*/
1327 /* directSpilLoc - will return 1 if the splilocation is in direct */
1328 /*-----------------------------------------------------------------*/
1330 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1332 debugLog ("%s\n", __FUNCTION__);
1333 if (sym->usl.spillLoc &&
1334 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1340 /*-----------------------------------------------------------------*/
1341 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1342 /* but is not used as a pointer */
1343 /*-----------------------------------------------------------------*/
1345 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1347 debugLog ("%s\n", __FUNCTION__);
1348 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1351 /*-----------------------------------------------------------------*/
1352 /* rematable - will return 1 if the remat flag is set */
1353 /*-----------------------------------------------------------------*/
1355 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1357 debugLog ("%s\n", __FUNCTION__);
1361 /*-----------------------------------------------------------------*/
1362 /* notUsedInRemaining - not used or defined in remain of the block */
1363 /*-----------------------------------------------------------------*/
1365 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1367 debugLog ("%s\n", __FUNCTION__);
1368 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1369 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1372 /*-----------------------------------------------------------------*/
1373 /* allLRs - return true for all */
1374 /*-----------------------------------------------------------------*/
1376 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1378 debugLog ("%s\n", __FUNCTION__);
1382 /*-----------------------------------------------------------------*/
1383 /* liveRangesWith - applies function to a given set of live range */
1384 /*-----------------------------------------------------------------*/
1386 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1387 eBBlock * ebp, iCode * ic)
1392 debugLog ("%s\n", __FUNCTION__);
1393 if (!lrs || !lrs->size)
1396 for (i = 1; i < lrs->size; i++)
1399 if (!bitVectBitValue (lrs, i))
1402 /* if we don't find it in the live range
1403 hash table we are in serious trouble */
1404 if (!(sym = hTabItemWithKey (liveRanges, i)))
1406 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1407 "liveRangesWith could not find liveRange");
1411 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1412 addSetHead (&rset, sym);
1419 /*-----------------------------------------------------------------*/
1420 /* leastUsedLR - given a set determines which is the least used */
1421 /*-----------------------------------------------------------------*/
1423 leastUsedLR (set * sset)
1425 symbol *sym = NULL, *lsym = NULL;
1427 debugLog ("%s\n", __FUNCTION__);
1428 sym = lsym = setFirstItem (sset);
1433 for (; lsym; lsym = setNextItem (sset))
1436 /* if usage is the same then prefer
1437 the spill the smaller of the two */
1438 if (lsym->used == sym->used)
1439 if (getSize (lsym->type) < getSize (sym->type))
1443 if (lsym->used < sym->used)
1448 setToNull ((void *) &sset);
1453 /*-----------------------------------------------------------------*/
1454 /* noOverLap - will iterate through the list looking for over lap */
1455 /*-----------------------------------------------------------------*/
1457 noOverLap (set * itmpStack, symbol * fsym)
1460 debugLog ("%s\n", __FUNCTION__);
1463 for (sym = setFirstItem (itmpStack); sym;
1464 sym = setNextItem (itmpStack))
1466 if (sym->liveTo > fsym->liveFrom)
1474 /*-----------------------------------------------------------------*/
1475 /* isFree - will return 1 if the a free spil location is found */
1476 /*-----------------------------------------------------------------*/
1481 V_ARG (symbol **, sloc);
1482 V_ARG (symbol *, fsym);
1484 debugLog ("%s\n", __FUNCTION__);
1485 /* if already found */
1489 /* if it is free && and the itmp assigned to
1490 this does not have any overlapping live ranges
1491 with the one currently being assigned and
1492 the size can be accomodated */
1494 noOverLap (sym->usl.itmpStack, fsym) &&
1495 getSize (sym->type) >= getSize (fsym->type))
1504 /*-----------------------------------------------------------------*/
1505 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1506 /*-----------------------------------------------------------------*/
1508 spillLRWithPtrReg (symbol * forSym)
1514 debugLog ("%s\n", __FUNCTION__);
1515 if (!_G.regAssigned ||
1516 bitVectIsZero (_G.regAssigned))
1519 r0 = pic16_regWithIdx (R0_IDX);
1520 r1 = pic16_regWithIdx (R1_IDX);
1522 /* for all live ranges */
1523 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1524 lrsym = hTabNextItem (liveRanges, &k))
1528 /* if no registers assigned to it or
1530 /* if it does not overlap with this then
1531 not need to spill it */
1533 if (lrsym->isspilt || !lrsym->nRegs ||
1534 (lrsym->liveTo < forSym->liveFrom))
1537 /* go thru the registers : if it is either
1538 r0 or r1 then spil it */
1539 for (j = 0; j < lrsym->nRegs; j++)
1540 if (lrsym->regs[j] == r0 ||
1541 lrsym->regs[j] == r1)
1550 /*-----------------------------------------------------------------*/
1551 /* createStackSpil - create a location on the stack to spil */
1552 /*-----------------------------------------------------------------*/
1554 createStackSpil (symbol * sym)
1556 symbol *sloc = NULL;
1557 int useXstack, model, noOverlay;
1559 char slocBuffer[30];
1560 debugLog ("%s\n", __FUNCTION__);
1562 /* first go try and find a free one that is already
1563 existing on the stack */
1564 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1566 /* found a free one : just update & return */
1567 sym->usl.spillLoc = sloc;
1570 addSetHead (&sloc->usl.itmpStack, sym);
1574 /* could not then have to create one , this is the hard part
1575 we need to allocate this on the stack : this is really a
1576 hack!! but cannot think of anything better at this time */
1578 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1580 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1581 __FILE__, __LINE__);
1585 sloc = newiTemp (slocBuffer);
1587 /* set the type to the spilling symbol */
1588 sloc->type = copyLinkChain (sym->type);
1589 sloc->etype = getSpec (sloc->type);
1590 SPEC_SCLS (sloc->etype) = S_DATA;
1591 SPEC_EXTR (sloc->etype) = 0;
1592 SPEC_STAT (sloc->etype) = 0;
1594 /* we don't allow it to be allocated`
1595 onto the external stack since : so we
1596 temporarily turn it off ; we also
1597 turn off memory model to prevent
1598 the spil from going to the external storage
1599 and turn off overlaying
1602 useXstack = options.useXstack;
1603 model = options.model;
1604 noOverlay = options.noOverlay;
1605 options.noOverlay = 1;
1606 options.model = options.useXstack = 0;
1610 options.useXstack = useXstack;
1611 options.model = model;
1612 options.noOverlay = noOverlay;
1613 sloc->isref = 1; /* to prevent compiler warning */
1615 /* if it is on the stack then update the stack */
1616 if (IN_STACK (sloc->etype))
1618 currFunc->stack += getSize (sloc->type);
1619 _G.stackExtend += getSize (sloc->type);
1622 _G.dataExtend += getSize (sloc->type);
1624 /* add it to the _G.stackSpil set */
1625 addSetHead (&_G.stackSpil, sloc);
1626 sym->usl.spillLoc = sloc;
1629 /* add it to the set of itempStack set
1630 of the spill location */
1631 addSetHead (&sloc->usl.itmpStack, sym);
1635 /*-----------------------------------------------------------------*/
1636 /* isSpiltOnStack - returns true if the spil location is on stack */
1637 /*-----------------------------------------------------------------*/
1639 isSpiltOnStack (symbol * sym)
1643 debugLog ("%s\n", __FUNCTION__);
1650 /* if (sym->_G.stackSpil) */
1653 if (!sym->usl.spillLoc)
1656 etype = getSpec (sym->usl.spillLoc->type);
1657 if (IN_STACK (etype))
1663 /*-----------------------------------------------------------------*/
1664 /* spillThis - spils a specific operand */
1665 /*-----------------------------------------------------------------*/
1667 spillThis (symbol * sym)
1670 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1672 /* if this is rematerializable or has a spillLocation
1673 we are okay, else we need to create a spillLocation
1675 if (!(sym->remat || sym->usl.spillLoc))
1676 createStackSpil (sym);
1679 /* mark it has spilt & put it in the spilt set */
1681 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1683 bitVectUnSetBit (_G.regAssigned, sym->key);
1685 for (i = 0; i < sym->nRegs; i++)
1689 freeReg (sym->regs[i]);
1690 sym->regs[i] = NULL;
1693 /* if spilt on stack then free up r0 & r1
1694 if they could have been assigned to some
1696 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1699 spillLRWithPtrReg (sym);
1702 if (sym->usl.spillLoc && !sym->remat)
1703 sym->usl.spillLoc->allocreq = 1;
1707 /*-----------------------------------------------------------------*/
1708 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1709 /*-----------------------------------------------------------------*/
1711 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1713 bitVect *lrcs = NULL;
1717 debugLog ("%s\n", __FUNCTION__);
1718 /* get the spillable live ranges */
1719 lrcs = computeSpillable (ic);
1721 /* get all live ranges that are rematerizable */
1722 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1725 /* return the least used of these */
1726 return leastUsedLR (selectS);
1729 /* get live ranges with spillLocations in direct space */
1730 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1732 sym = leastUsedLR (selectS);
1733 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1734 sym->usl.spillLoc->rname :
1735 sym->usl.spillLoc->name));
1737 /* mark it as allocation required */
1738 sym->usl.spillLoc->allocreq = 1;
1742 /* if the symbol is local to the block then */
1743 if (forSym->liveTo < ebp->lSeq)
1746 /* check if there are any live ranges allocated
1747 to registers that are not used in this block */
1748 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1750 sym = leastUsedLR (selectS);
1751 /* if this is not rematerializable */
1760 /* check if there are any live ranges that not
1761 used in the remainder of the block */
1762 if (!_G.blockSpil &&
1763 !isiCodeInFunctionCall (ic) &&
1764 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1766 sym = leastUsedLR (selectS);
1769 sym->remainSpil = 1;
1776 /* find live ranges with spillocation && not used as pointers */
1777 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1780 sym = leastUsedLR (selectS);
1781 /* mark this as allocation required */
1782 sym->usl.spillLoc->allocreq = 1;
1786 /* find live ranges with spillocation */
1787 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1790 sym = leastUsedLR (selectS);
1791 sym->usl.spillLoc->allocreq = 1;
1795 /* couldn't find then we need to create a spil
1796 location on the stack , for which one? the least
1798 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1801 /* return a created spil location */
1802 sym = createStackSpil (leastUsedLR (selectS));
1803 sym->usl.spillLoc->allocreq = 1;
1807 /* this is an extreme situation we will spill
1808 this one : happens very rarely but it does happen */
1814 /*-----------------------------------------------------------------*/
1815 /* spilSomething - spil some variable & mark registers as free */
1816 /*-----------------------------------------------------------------*/
1818 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1823 debugLog ("%s\n", __FUNCTION__);
1824 /* get something we can spil */
1825 ssym = selectSpil (ic, ebp, forSym);
1827 /* mark it as spilt */
1829 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1831 /* mark it as not register assigned &
1832 take it away from the set */
1833 bitVectUnSetBit (_G.regAssigned, ssym->key);
1835 /* mark the registers as free */
1836 for (i = 0; i < ssym->nRegs; i++)
1838 freeReg (ssym->regs[i]);
1840 /* if spilt on stack then free up r0 & r1
1841 if they could have been assigned to as gprs */
1842 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1845 spillLRWithPtrReg (ssym);
1848 /* if this was a block level spil then insert push & pop
1849 at the start & end of block respectively */
1850 if (ssym->blockSpil)
1852 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1853 /* add push to the start of the block */
1854 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1855 ebp->sch->next : ebp->sch));
1856 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1857 /* add pop to the end of the block */
1858 addiCodeToeBBlock (ebp, nic, NULL);
1861 /* if spilt because not used in the remainder of the
1862 block then add a push before this instruction and
1863 a pop at the end of the block */
1864 if (ssym->remainSpil)
1867 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1868 /* add push just before this instruction */
1869 addiCodeToeBBlock (ebp, nic, ic);
1871 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1872 /* add pop to the end of the block */
1873 addiCodeToeBBlock (ebp, nic, NULL);
1882 /*-----------------------------------------------------------------*/
1883 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1884 /*-----------------------------------------------------------------*/
1886 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1891 debugLog ("%s\n", __FUNCTION__);
1893 /* try for a ptr type */
1894 if ((reg = allocReg (REG_PTR)))
1897 /* try for gpr type */
1898 if ((reg = allocReg (REG_GPR)))
1901 /* we have to spil */
1902 if (!spilSomething (ic, ebp, sym))
1905 /* make sure partially assigned registers aren't reused */
1906 for (j=0; j<=sym->nRegs; j++)
1908 sym->regs[j]->isFree = 0;
1910 /* this looks like an infinite loop but
1911 in really selectSpil will abort */
1915 /*-----------------------------------------------------------------*/
1916 /* getRegGpr - will try for GPR if not spil */
1917 /*-----------------------------------------------------------------*/
1919 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1924 debugLog ("%s\n", __FUNCTION__);
1926 /* try for gpr type */
1927 if ((reg = allocReg (REG_GPR)))
1930 if (!pic16_ptrRegReq)
1931 if ((reg = allocReg (REG_PTR)))
1934 /* we have to spil */
1935 if (!spilSomething (ic, ebp, sym))
1938 /* make sure partially assigned registers aren't reused */
1939 for (j=0; j<=sym->nRegs; j++)
1941 sym->regs[j]->isFree = 0;
1943 /* this looks like an infinite loop but
1944 in really selectSpil will abort */
1948 /*-----------------------------------------------------------------*/
1949 /* symHasReg - symbol has a given register */
1950 /*-----------------------------------------------------------------*/
1952 symHasReg (symbol * sym, regs * reg)
1956 debugLog ("%s\n", __FUNCTION__);
1957 for (i = 0; i < sym->nRegs; i++)
1958 if (sym->regs[i] == reg)
1964 /*-----------------------------------------------------------------*/
1965 /* deassignLRs - check the live to and if they have registers & are */
1966 /* not spilt then free up the registers */
1967 /*-----------------------------------------------------------------*/
1969 deassignLRs (iCode * ic, eBBlock * ebp)
1975 debugLog ("%s\n", __FUNCTION__);
1976 for (sym = hTabFirstItem (liveRanges, &k); sym;
1977 sym = hTabNextItem (liveRanges, &k))
1980 symbol *psym = NULL;
1981 /* if it does not end here */
1982 if (sym->liveTo > ic->seq)
1985 /* if it was spilt on stack then we can
1986 mark the stack spil location as free */
1991 sym->usl.spillLoc->isFree = 1;
1997 if (!bitVectBitValue (_G.regAssigned, sym->key))
2000 /* special case for shifting: there is a case where shift count
2001 * can be allocated in the same register as the result, so do not
2002 * free right registers if same as result registers, cause genShiftLeft
2003 * will fail -- VR */
2004 if(ic->op == LEFT_OP)
2007 /* special case check if this is an IFX &
2008 the privious one was a pop and the
2009 previous one was not spilt then keep track
2011 if (ic->op == IFX && ic->prev &&
2012 ic->prev->op == IPOP &&
2013 !ic->prev->parmPush &&
2014 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2015 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2021 bitVectUnSetBit (_G.regAssigned, sym->key);
2023 /* if the result of this one needs registers
2024 and does not have it then assign it right
2026 if (IC_RESULT (ic) &&
2027 !(SKIP_IC2 (ic) || /* not a special icode */
2028 ic->op == JUMPTABLE ||
2033 POINTER_SET (ic)) &&
2034 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2035 result->liveTo > ic->seq && /* and will live beyond this */
2036 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2037 result->liveFrom == ic->seq && /* does not start before here */
2038 result->regType == sym->regType && /* same register types */
2039 result->nRegs && /* which needs registers */
2040 !result->isspilt && /* and does not already have them */
2042 !bitVectBitValue (_G.regAssigned, result->key) &&
2043 /* the number of free regs + number of regs in this LR
2044 can accomodate the what result Needs */
2045 ((nfreeRegsType (result->regType) +
2046 sym->nRegs) >= result->nRegs)
2050 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2052 result->regs[i] = sym->regs[i];
2054 result->regs[i] = getRegGpr (ic, ebp, result);
2056 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2060 /* free the remaining */
2061 for (; i < sym->nRegs; i++)
2065 if (!symHasReg (psym, sym->regs[i]))
2066 freeReg (sym->regs[i]);
2069 freeReg (sym->regs[i]);
2076 /*-----------------------------------------------------------------*/
2077 /* reassignLR - reassign this to registers */
2078 /*-----------------------------------------------------------------*/
2080 reassignLR (operand * op)
2082 symbol *sym = OP_SYMBOL (op);
2085 debugLog ("%s\n", __FUNCTION__);
2086 /* not spilt any more */
2087 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2088 bitVectUnSetBit (_G.spiltSet, sym->key);
2090 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2094 for (i = 0; i < sym->nRegs; i++)
2095 sym->regs[i]->isFree = 0;
2098 /*-----------------------------------------------------------------*/
2099 /* willCauseSpill - determines if allocating will cause a spill */
2100 /*-----------------------------------------------------------------*/
2102 willCauseSpill (int nr, int rt)
2104 debugLog ("%s\n", __FUNCTION__);
2105 /* first check if there are any avlb registers
2106 of te type required */
2109 /* special case for pointer type
2110 if pointer type not avlb then
2111 check for type gpr */
2112 if (nFreeRegs (rt) >= nr)
2114 if (nFreeRegs (REG_GPR) >= nr)
2119 if (pic16_ptrRegReq)
2121 if (nFreeRegs (rt) >= nr)
2126 if (nFreeRegs (REG_PTR) +
2127 nFreeRegs (REG_GPR) >= nr)
2132 debugLog (" ... yep it will (cause a spill)\n");
2133 /* it will cause a spil */
2137 /*-----------------------------------------------------------------*/
2138 /* positionRegs - the allocator can allocate same registers to res- */
2139 /* ult and operand, if this happens make sure they are in the same */
2140 /* position as the operand otherwise chaos results */
2141 /*-----------------------------------------------------------------*/
2143 positionRegs (symbol * result, symbol * opsym, int lineno)
2145 int count = min (result->nRegs, opsym->nRegs);
2146 int i, j = 0, shared = 0;
2148 debugLog ("%s\n", __FUNCTION__);
2149 /* if the result has been spilt then cannot share */
2154 /* first make sure that they actually share */
2155 for (i = 0; i < count; i++)
2157 for (j = 0; j < count; j++)
2159 if (result->regs[i] == opsym->regs[j] && i != j)
2169 regs *tmp = result->regs[i];
2170 result->regs[i] = result->regs[j];
2171 result->regs[j] = tmp;
2176 /*------------------------------------------------------------------*/
2177 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2178 /* it should either have registers or have beed spilled. Otherwise, */
2179 /* there was an uninitialized variable, so just spill this to get */
2180 /* the operand in a valid state. */
2181 /*------------------------------------------------------------------*/
2183 verifyRegsAssigned (operand *op, iCode * ic)
2188 if (!IS_ITEMP (op)) return;
2190 sym = OP_SYMBOL (op);
2191 if (sym->isspilt) return;
2192 if (!sym->nRegs) return;
2193 if (sym->regs[0]) return;
2195 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2196 sym->prereqv ? sym->prereqv->name : sym->name);
2201 /*-----------------------------------------------------------------*/
2202 /* serialRegAssign - serially allocate registers to the variables */
2203 /*-----------------------------------------------------------------*/
2205 serialRegAssign (eBBlock ** ebbs, int count)
2209 debugLog ("%s\n", __FUNCTION__);
2210 /* for all blocks */
2211 for (i = 0; i < count; i++)
2216 if (ebbs[i]->noPath &&
2217 (ebbs[i]->entryLabel != entryLabel &&
2218 ebbs[i]->entryLabel != returnLabel))
2221 /* of all instructions do */
2222 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2225 debugLog (" op: %s\n", decodeOp (ic->op));
2227 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2228 pic16_allocDirReg(IC_RESULT(ic));
2230 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2231 pic16_allocDirReg(IC_LEFT(ic));
2233 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2234 pic16_allocDirReg(IC_RIGHT(ic));
2236 /* if this is an ipop that means some live
2237 range will have to be assigned again */
2239 reassignLR (IC_LEFT (ic));
2241 /* if result is present && is a true symbol */
2242 if (IC_RESULT (ic) && ic->op != IFX &&
2243 IS_TRUE_SYMOP (IC_RESULT (ic)))
2244 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2246 /* take away registers from live
2247 ranges that end at this instruction */
2248 deassignLRs (ic, ebbs[i]);
2250 /* some don't need registers */
2251 if (SKIP_IC2 (ic) ||
2252 ic->op == JUMPTABLE ||
2256 (IC_RESULT (ic) && POINTER_SET (ic)))
2259 /* now we need to allocate registers
2260 only for the result */
2263 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2269 /* if it does not need or is spilt
2270 or is already assigned to registers
2271 or will not live beyond this instructions */
2274 bitVectBitValue (_G.regAssigned, sym->key) ||
2275 sym->liveTo <= ic->seq)
2278 /* if some liverange has been spilt at the block level
2279 and this one live beyond this block then spil this
2281 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2286 /* if trying to allocate this will cause
2287 a spill and there is nothing to spill
2288 or this one is rematerializable then
2290 willCS = willCauseSpill (sym->nRegs, sym->regType);
2291 spillable = computeSpillable (ic);
2293 (willCS && bitVectIsZero (spillable)))
2301 /* If the live range preceeds the point of definition
2302 then ideally we must take into account registers that
2303 have been allocated after sym->liveFrom but freed
2304 before ic->seq. This is complicated, so spill this
2305 symbol instead and let fillGaps handle the allocation. */
2306 if (sym->liveFrom < ic->seq)
2312 /* if it has a spillocation & is used less than
2313 all other live ranges then spill this */
2315 if (sym->usl.spillLoc) {
2316 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2317 allLRs, ebbs[i], ic));
2318 if (leastUsed && leastUsed->used > sym->used) {
2323 /* if none of the liveRanges have a spillLocation then better
2324 to spill this one than anything else already assigned to registers */
2325 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2326 /* if this is local to this block then we might find a block spil */
2327 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2335 if (ic->op == RECEIVE)
2336 debugLog ("When I get clever, I'll optimize the receive logic\n");
2338 /* if we need ptr regs for the right side
2340 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2341 <= (unsigned) PTRSIZE)
2346 /* else we assign registers to it */
2347 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2350 bitVectDebugOn(_G.regAssigned, debugF);
2352 for (j = 0; j < sym->nRegs; j++)
2354 if (sym->regType == REG_PTR)
2355 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2357 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2359 /* if the allocation falied which means
2360 this was spilt then break */
2364 debugLog (" %d - \n", __LINE__);
2366 /* if it shares registers with operands make sure
2367 that they are in the same position */
2368 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2369 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2370 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2371 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2372 /* do the same for the right operand */
2373 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2374 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2375 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2376 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2378 debugLog (" %d - \n", __LINE__);
2381 debugLog (" %d - \n", __LINE__);
2390 /* Check for and fix any problems with uninitialized operands */
2391 for (i = 0; i < count; i++)
2395 if (ebbs[i]->noPath &&
2396 (ebbs[i]->entryLabel != entryLabel &&
2397 ebbs[i]->entryLabel != returnLabel))
2400 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2407 verifyRegsAssigned (IC_COND (ic), ic);
2411 if (ic->op == JUMPTABLE)
2413 verifyRegsAssigned (IC_JTCOND (ic), ic);
2417 verifyRegsAssigned (IC_RESULT (ic), ic);
2418 verifyRegsAssigned (IC_LEFT (ic), ic);
2419 verifyRegsAssigned (IC_RIGHT (ic), ic);
2425 /*-----------------------------------------------------------------*/
2426 /* rUmaskForOp :- returns register mask for an operand */
2427 /*-----------------------------------------------------------------*/
2429 rUmaskForOp (operand * op)
2435 debugLog ("%s\n", __FUNCTION__);
2436 /* only temporaries are assigned registers */
2440 sym = OP_SYMBOL (op);
2442 /* if spilt or no registers assigned to it
2444 if (sym->isspilt || !sym->nRegs)
2447 rumask = newBitVect (pic16_nRegs);
2449 for (j = 0; j < sym->nRegs; j++)
2451 rumask = bitVectSetBit (rumask,
2452 sym->regs[j]->rIdx);
2458 /*-----------------------------------------------------------------*/
2459 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2460 /*-----------------------------------------------------------------*/
2462 regsUsedIniCode (iCode * ic)
2464 bitVect *rmask = newBitVect (pic16_nRegs);
2466 debugLog ("%s\n", __FUNCTION__);
2467 /* do the special cases first */
2470 rmask = bitVectUnion (rmask,
2471 rUmaskForOp (IC_COND (ic)));
2475 /* for the jumptable */
2476 if (ic->op == JUMPTABLE)
2478 rmask = bitVectUnion (rmask,
2479 rUmaskForOp (IC_JTCOND (ic)));
2484 /* of all other cases */
2486 rmask = bitVectUnion (rmask,
2487 rUmaskForOp (IC_LEFT (ic)));
2491 rmask = bitVectUnion (rmask,
2492 rUmaskForOp (IC_RIGHT (ic)));
2495 rmask = bitVectUnion (rmask,
2496 rUmaskForOp (IC_RESULT (ic)));
2502 /*-----------------------------------------------------------------*/
2503 /* createRegMask - for each instruction will determine the regsUsed */
2504 /*-----------------------------------------------------------------*/
2506 createRegMask (eBBlock ** ebbs, int count)
2510 debugLog ("%s\n", __FUNCTION__);
2511 /* for all blocks */
2512 for (i = 0; i < count; i++)
2516 if (ebbs[i]->noPath &&
2517 (ebbs[i]->entryLabel != entryLabel &&
2518 ebbs[i]->entryLabel != returnLabel))
2521 /* for all instructions */
2522 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2527 if (SKIP_IC2 (ic) || !ic->rlive)
2530 /* first mark the registers used in this
2532 ic->rUsed = regsUsedIniCode (ic);
2533 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2535 /* now create the register mask for those
2536 registers that are in use : this is a
2537 super set of ic->rUsed */
2538 ic->rMask = newBitVect (pic16_nRegs + 1);
2540 /* for all live Ranges alive at this point */
2541 for (j = 1; j < ic->rlive->size; j++)
2546 /* if not alive then continue */
2547 if (!bitVectBitValue (ic->rlive, j))
2550 /* find the live range we are interested in */
2551 if (!(sym = hTabItemWithKey (liveRanges, j)))
2553 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2554 "createRegMask cannot find live range");
2558 /* if no register assigned to it */
2559 if (!sym->nRegs || sym->isspilt)
2562 /* for all the registers allocated to it */
2563 for (k = 0; k < sym->nRegs; k++)
2566 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2572 /*-----------------------------------------------------------------*/
2573 /* rematStr - returns the rematerialized string for a remat var */
2574 /*-----------------------------------------------------------------*/
2576 rematStr (symbol * sym)
2579 iCode *ic = sym->rematiCode;
2580 symbol *psym = NULL;
2582 debugLog ("%s\n", __FUNCTION__);
2584 //printf ("%s\n", s);
2586 /* if plus or minus print the right hand side */
2588 if (ic->op == '+' || ic->op == '-') {
2590 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2592 sprintf (s, "(%s %c 0x%04x)",
2593 OP_SYMBOL (IC_LEFT (ric))->rname,
2595 (int) operandLitValue (IC_RIGHT (ic)));
2598 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2600 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2601 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2606 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2607 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2609 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2614 /*-----------------------------------------------------------------*/
2615 /* rematStr - returns the rematerialized string for a remat var */
2616 /*-----------------------------------------------------------------*/
2618 rematStr (symbol * sym)
2621 iCode *ic = sym->rematiCode;
2623 debugLog ("%s\n", __FUNCTION__);
2628 /* if plus or minus print the right hand side */
2630 if (ic->op == '+' || ic->op == '-') {
2631 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2634 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2638 if (ic->op == '+' || ic->op == '-')
2640 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2641 sprintf (s, "(%s %c 0x%04x)",
2642 OP_SYMBOL (IC_LEFT (ric))->rname,
2644 (int) operandLitValue (IC_RIGHT (ic)));
2647 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2649 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2653 /* we reached the end */
2654 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2658 printf ("%s\n", buffer);
2663 /*-----------------------------------------------------------------*/
2664 /* regTypeNum - computes the type & number of registers required */
2665 /*-----------------------------------------------------------------*/
2673 debugLog ("%s\n", __FUNCTION__);
2674 /* for each live range do */
2675 for (sym = hTabFirstItem (liveRanges, &k); sym;
2676 sym = hTabNextItem (liveRanges, &k)) {
2678 debugLog (" %d - %s\n", __LINE__, sym->rname);
2679 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2681 /* if used zero times then no registers needed */
2682 if ((sym->liveTo - sym->liveFrom) == 0)
2686 /* if the live range is a temporary */
2689 debugLog (" %d - itemp register\n", __LINE__);
2691 /* if the type is marked as a conditional */
2692 if (sym->regType == REG_CND)
2695 /* if used in return only then we don't
2697 if (sym->ruonly || sym->accuse) {
2698 if (IS_AGGREGATE (sym->type) || sym->isptr)
2699 sym->type = aggrToPtr (sym->type, FALSE);
2700 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2704 /* if the symbol has only one definition &
2705 that definition is a get_pointer and the
2706 pointer we are getting is rematerializable and
2709 if (bitVectnBitsOn (sym->defs) == 1 &&
2710 (ic = hTabItemWithKey (iCodehTab,
2711 bitVectFirstBit (sym->defs))) &&
2713 !IS_BITVAR (sym->etype) &&
2714 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2716 if (ptrPseudoSymSafe (sym, ic)) {
2720 debugLog (" %d - \n", __LINE__);
2722 /* create a psuedo symbol & force a spil */
2723 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2724 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2725 psym->type = sym->type;
2726 psym->etype = sym->etype;
2727 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2728 strcpy (psym->rname, psym->name);
2730 sym->usl.spillLoc = psym;
2734 /* if in data space or idata space then try to
2735 allocate pointer register */
2739 /* if not then we require registers */
2740 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2741 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2742 getSize (sym->type));
2746 if(IS_PTR_CONST (sym->type)) {
2748 if(IS_CODEPTR (sym->type)) {
2750 // what IS this ???? (HJD)
2751 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2752 sym->nRegs = 3; // patch 14
2755 if (sym->nRegs > 4) {
2756 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2757 printTypeChain (sym->type, stderr);
2758 fprintf (stderr, "\n");
2761 /* determine the type of register required */
2762 if (sym->nRegs == 1 &&
2763 IS_PTR (sym->type) &&
2765 sym->regType = REG_PTR;
2767 sym->regType = REG_GPR;
2770 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2774 /* for the first run we don't provide */
2775 /* registers for true symbols we will */
2776 /* see how things go */
2782 static DEFSETFUNC (markRegFree)
2784 ((regs *)item)->isFree = 1;
2789 DEFSETFUNC (pic16_deallocReg)
2791 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2792 ((regs *)item)->isFree = 1;
2793 ((regs *)item)->wasUsed = 0;
2797 /*-----------------------------------------------------------------*/
2798 /* freeAllRegs - mark all registers as free */
2799 /*-----------------------------------------------------------------*/
2801 pic16_freeAllRegs ()
2803 debugLog ("%s\n", __FUNCTION__);
2805 applyToSet(pic16_dynAllocRegs,markRegFree);
2806 applyToSet(pic16_dynStackRegs,markRegFree);
2809 /*-----------------------------------------------------------------*/
2810 /*-----------------------------------------------------------------*/
2812 pic16_deallocateAllRegs ()
2814 debugLog ("%s\n", __FUNCTION__);
2816 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2820 /*-----------------------------------------------------------------*/
2821 /* deallocStackSpil - this will set the stack pointer back */
2822 /*-----------------------------------------------------------------*/
2824 DEFSETFUNC (deallocStackSpil)
2828 debugLog ("%s\n", __FUNCTION__);
2833 /*-----------------------------------------------------------------*/
2834 /* farSpacePackable - returns the packable icode for far variables */
2835 /*-----------------------------------------------------------------*/
2837 farSpacePackable (iCode * ic)
2841 debugLog ("%s\n", __FUNCTION__);
2842 /* go thru till we find a definition for the
2843 symbol on the right */
2844 for (dic = ic->prev; dic; dic = dic->prev)
2847 /* if the definition is a call then no */
2848 if ((dic->op == CALL || dic->op == PCALL) &&
2849 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2854 /* if shift by unknown amount then not */
2855 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2856 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2859 /* if pointer get and size > 1 */
2860 if (POINTER_GET (dic) &&
2861 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2864 if (POINTER_SET (dic) &&
2865 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2868 /* if any three is a true symbol in far space */
2869 if (IC_RESULT (dic) &&
2870 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2871 isOperandInFarSpace (IC_RESULT (dic)))
2874 if (IC_RIGHT (dic) &&
2875 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2876 isOperandInFarSpace (IC_RIGHT (dic)) &&
2877 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2880 if (IC_LEFT (dic) &&
2881 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2882 isOperandInFarSpace (IC_LEFT (dic)) &&
2883 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2886 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2888 if ((dic->op == LEFT_OP ||
2889 dic->op == RIGHT_OP ||
2891 IS_OP_LITERAL (IC_RIGHT (dic)))
2901 /*-----------------------------------------------------------------*/
2902 /* packRegsForAssign - register reduction for assignment */
2903 /*-----------------------------------------------------------------*/
2905 packRegsForAssign (iCode * ic, eBBlock * ebp)
2910 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2911 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2912 debugAopGet (" result:", IC_RESULT (ic));
2913 debugAopGet (" left:", IC_LEFT (ic));
2914 debugAopGet (" right:", IC_RIGHT (ic));
2916 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2918 debugLog(" %d - actuall processing\n", __LINE__ );
2920 if (!IS_ITEMP (IC_RESULT (ic))) {
2921 pic16_allocDirReg(IC_RESULT (ic));
2922 debugLog (" %d - result is not temp\n", __LINE__);
2926 /* See BUGLOG0001 - VR */
2928 if (!IS_ITEMP (IC_RIGHT (ic))) {
2929 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2930 pic16_allocDirReg(IC_RIGHT (ic));
2935 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2936 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2938 debugLog (" %d - not packing - right side fails \n", __LINE__);
2942 /* if the true symbol is defined in far space or on stack
2943 then we should not since this will increase register pressure */
2944 if (isOperandInFarSpace (IC_RESULT (ic)))
2946 if ((dic = farSpacePackable (ic)))
2953 /* find the definition of iTempNN scanning backwards if we find a
2954 a use of the true symbol before we find the definition then
2956 for (dic = ic->prev; dic; dic = dic->prev)
2959 /* if there is a function call and this is
2960 a parameter & not my parameter then don't pack it */
2961 if ((dic->op == CALL || dic->op == PCALL) &&
2962 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2963 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2965 debugLog (" %d - \n", __LINE__);
2974 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2976 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2977 IS_OP_VOLATILE (IC_RESULT (dic)))
2979 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2985 if( IS_SYMOP( IC_RESULT(dic)) &&
2986 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2988 debugLog (" %d - result is bitfield\n", __LINE__);
2994 if (IS_SYMOP (IC_RESULT (dic)) &&
2995 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2997 /* A previous result was assigned to the same register - we'll our definition */
2998 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2999 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3000 if (POINTER_SET (dic))
3006 if (IS_SYMOP (IC_RIGHT (dic)) &&
3007 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3008 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3010 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3015 if (IS_SYMOP (IC_LEFT (dic)) &&
3016 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3017 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3019 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3024 if (POINTER_SET (dic) &&
3025 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3027 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3035 return 0; /* did not find */
3038 /* This code is taken from the hc08 port. Do not know
3039 * if it fits for pic16, but I leave it here just in case */
3041 /* if assignment then check that right is not a bit */
3042 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3043 sym_link *etype = operandType (IC_RIGHT (dic));
3045 if (IS_BITFIELD (etype)) {
3046 /* if result is a bit too then it's ok */
3047 etype = operandType (IC_RESULT (dic));
3048 if (!IS_BITFIELD (etype)) {
3049 debugLog(" %d bitfields\n");
3056 /* if the result is on stack or iaccess then it must be
3057 the same atleast one of the operands */
3058 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3059 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3061 /* the operation has only one symbol
3062 operator then we can pack */
3063 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3064 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3067 if (!((IC_LEFT (dic) &&
3068 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3070 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3074 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3075 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3076 /* found the definition */
3077 /* replace the result with the result of */
3078 /* this assignment and remove this assignment */
3079 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3080 IC_RESULT (dic) = IC_RESULT (ic);
3082 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3084 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3086 /* delete from liverange table also
3087 delete from all the points inbetween and the new
3089 for (sic = dic; sic != ic; sic = sic->next)
3091 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3092 if (IS_ITEMP (IC_RESULT (dic)))
3093 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3096 remiCodeFromeBBlock (ebp, ic);
3097 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3099 debugLog(" %d\n", __LINE__ );
3100 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3101 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3109 #define NO_packRegsForAccUse
3110 #define NO_packRegsForSupport
3111 #define NO_packRegsForOneuse
3112 #define NO_cast_peep
3117 #ifndef NO_packRegsForSupport
3118 /*-----------------------------------------------------------------*/
3119 /* findAssignToSym : scanning backwards looks for first assig found */
3120 /*-----------------------------------------------------------------*/
3122 findAssignToSym (operand * op, iCode * ic)
3126 debugLog ("%s\n", __FUNCTION__);
3127 for (dic = ic->prev; dic; dic = dic->prev)
3130 /* if definition by assignment */
3131 if (dic->op == '=' &&
3132 !POINTER_SET (dic) &&
3133 IC_RESULT (dic)->key == op->key
3134 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3138 /* we are interested only if defined in far space */
3139 /* or in stack space in case of + & - */
3141 /* if assigned to a non-symbol then return
3143 if (!IS_SYMOP (IC_RIGHT (dic)))
3146 /* if the symbol is in far space then
3148 if (isOperandInFarSpace (IC_RIGHT (dic)))
3151 /* for + & - operations make sure that
3152 if it is on the stack it is the same
3153 as one of the three operands */
3154 if ((ic->op == '+' || ic->op == '-') &&
3155 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3157 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3158 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3159 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3167 /* if we find an usage then we cannot delete it */
3168 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3171 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3174 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3178 /* now make sure that the right side of dic
3179 is not defined between ic & dic */
3182 iCode *sic = dic->next;
3184 for (; sic != ic; sic = sic->next)
3185 if (IC_RESULT (sic) &&
3186 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3197 #ifndef NO_packRegsForSupport
3198 /*-----------------------------------------------------------------*/
3199 /* packRegsForSupport :- reduce some registers for support calls */
3200 /*-----------------------------------------------------------------*/
3202 packRegsForSupport (iCode * ic, eBBlock * ebp)
3206 debugLog ("%s\n", __FUNCTION__);
3207 /* for the left & right operand :- look to see if the
3208 left was assigned a true symbol in far space in that
3209 case replace them */
3210 if (IS_ITEMP (IC_LEFT (ic)) &&
3211 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3213 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3219 debugAopGet ("removing left:", IC_LEFT (ic));
3221 /* found it we need to remove it from the
3223 for (sic = dic; sic != ic; sic = sic->next)
3224 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3226 IC_LEFT (ic)->operand.symOperand =
3227 IC_RIGHT (dic)->operand.symOperand;
3228 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3229 remiCodeFromeBBlock (ebp, dic);
3230 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3231 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3235 /* do the same for the right operand */
3238 IS_ITEMP (IC_RIGHT (ic)) &&
3239 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3241 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3247 /* if this is a subtraction & the result
3248 is a true symbol in far space then don't pack */
3249 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3251 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3252 if (IN_FARSPACE (SPEC_OCLS (etype)))
3256 debugAopGet ("removing right:", IC_RIGHT (ic));
3258 /* found it we need to remove it from the
3260 for (sic = dic; sic != ic; sic = sic->next)
3261 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3263 IC_RIGHT (ic)->operand.symOperand =
3264 IC_RIGHT (dic)->operand.symOperand;
3265 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3267 remiCodeFromeBBlock (ebp, dic);
3268 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3269 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3278 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3280 #ifndef NO_packRegsForOneuse
3281 /*-----------------------------------------------------------------*/
3282 /* packRegsForOneuse : - will reduce some registers for single Use */
3283 /*-----------------------------------------------------------------*/
3285 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3290 debugLog ("%s\n", __FUNCTION__);
3291 /* if returning a literal then do nothing */
3295 /* only upto 2 bytes since we cannot predict
3296 the usage of b, & acc */
3297 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3302 /* this routine will mark the a symbol as used in one
3303 instruction use only && if the definition is local
3304 (ie. within the basic block) && has only one definition &&
3305 that definition is either a return value from a
3306 function or does not contain any variables in
3308 uses = bitVectCopy (OP_USES (op));
3309 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3310 if (!bitVectIsZero (uses)) /* has other uses */
3313 /* if it has only one defintion */
3314 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3315 return NULL; /* has more than one definition */
3317 /* get that definition */
3319 hTabItemWithKey (iCodehTab,
3320 bitVectFirstBit (OP_DEFS (op)))))
3323 /* found the definition now check if it is local */
3324 if (dic->seq < ebp->fSeq ||
3325 dic->seq > ebp->lSeq)
3326 return NULL; /* non-local */
3328 /* now check if it is the return from
3330 if (dic->op == CALL || dic->op == PCALL)
3332 if (ic->op != SEND && ic->op != RETURN &&
3333 !POINTER_SET(ic) && !POINTER_GET(ic))
3335 OP_SYMBOL (op)->ruonly = 1;
3342 /* otherwise check that the definition does
3343 not contain any symbols in far space */
3344 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3345 isOperandInFarSpace (IC_RIGHT (dic)) ||
3346 IS_OP_RUONLY (IC_LEFT (ic)) ||
3347 IS_OP_RUONLY (IC_RIGHT (ic)))
3352 /* if pointer set then make sure the pointer
3354 if (POINTER_SET (dic) &&
3355 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3358 if (POINTER_GET (dic) &&
3359 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3364 /* also make sure the intervenening instructions
3365 don't have any thing in far space */
3366 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3369 /* if there is an intervening function call then no */
3370 if (dic->op == CALL || dic->op == PCALL)
3372 /* if pointer set then make sure the pointer
3374 if (POINTER_SET (dic) &&
3375 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3378 if (POINTER_GET (dic) &&
3379 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3382 /* if address of & the result is remat then okay */
3383 if (dic->op == ADDRESS_OF &&
3384 OP_SYMBOL (IC_RESULT (dic))->remat)
3387 /* if operand has size of three or more & this
3388 operation is a '*','/' or '%' then 'b' may
3390 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3391 getSize (operandType (op)) >= 3)
3394 /* if left or right or result is in far space */
3395 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3396 isOperandInFarSpace (IC_RIGHT (dic)) ||
3397 isOperandInFarSpace (IC_RESULT (dic)) ||
3398 IS_OP_RUONLY (IC_LEFT (dic)) ||
3399 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3400 IS_OP_RUONLY (IC_RESULT (dic)))
3406 OP_SYMBOL (op)->ruonly = 1;
3413 /*-----------------------------------------------------------------*/
3414 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3415 /*-----------------------------------------------------------------*/
3417 isBitwiseOptimizable (iCode * ic)
3419 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3420 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3422 debugLog ("%s\n", __FUNCTION__);
3423 /* bitwise operations are considered optimizable
3424 under the following conditions (Jean-Louis VERN)
3436 if (IS_LITERAL (rtype) ||
3437 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3444 #ifndef NO_packRegsForAccUse
3446 /*-----------------------------------------------------------------*/
3447 /* packRegsForAccUse - pack registers for acc use */
3448 /*-----------------------------------------------------------------*/
3450 packRegsForAccUse (iCode * ic)
3454 debugLog ("%s\n", __FUNCTION__);
3456 /* if this is an aggregate, e.g. a one byte char array */
3457 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3460 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3462 /* if + or - then it has to be one byte result */
3463 if ((ic->op == '+' || ic->op == '-')
3464 && getSize (operandType (IC_RESULT (ic))) > 1)
3467 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3468 /* if shift operation make sure right side is not a literal */
3469 if (ic->op == RIGHT_OP &&
3470 (isOperandLiteral (IC_RIGHT (ic)) ||
3471 getSize (operandType (IC_RESULT (ic))) > 1))
3474 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3475 if (ic->op == LEFT_OP &&
3476 (isOperandLiteral (IC_RIGHT (ic)) ||
3477 getSize (operandType (IC_RESULT (ic))) > 1))
3480 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3481 if (IS_BITWISE_OP (ic) &&
3482 getSize (operandType (IC_RESULT (ic))) > 1)
3486 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3487 /* has only one definition */
3488 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3491 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3492 /* has only one use */
3493 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3496 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3497 /* and the usage immediately follows this iCode */
3498 if (!(uic = hTabItemWithKey (iCodehTab,
3499 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3502 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3503 if (ic->next != uic)
3506 /* if it is a conditional branch then we definitely can */
3510 if (uic->op == JUMPTABLE)
3513 /* if the usage is not is an assignment
3514 or an arithmetic / bitwise / shift operation then not */
3515 if (POINTER_SET (uic) &&
3516 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3519 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3520 if (uic->op != '=' &&
3521 !IS_ARITHMETIC_OP (uic) &&
3522 !IS_BITWISE_OP (uic) &&
3523 uic->op != LEFT_OP &&
3524 uic->op != RIGHT_OP)
3527 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3528 /* if used in ^ operation then make sure right is not a
3530 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3533 /* if shift operation make sure right side is not a literal */
3534 if (uic->op == RIGHT_OP &&
3535 (isOperandLiteral (IC_RIGHT (uic)) ||
3536 getSize (operandType (IC_RESULT (uic))) > 1))
3539 if (uic->op == LEFT_OP &&
3540 (isOperandLiteral (IC_RIGHT (uic)) ||
3541 getSize (operandType (IC_RESULT (uic))) > 1))
3544 /* make sure that the result of this icode is not on the
3545 stack, since acc is used to compute stack offset */
3546 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3547 OP_SYMBOL (IC_RESULT (uic))->onStack)
3550 /* if either one of them in far space then we cannot */
3551 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3552 isOperandInFarSpace (IC_LEFT (uic))) ||
3553 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3554 isOperandInFarSpace (IC_RIGHT (uic))))
3557 /* if the usage has only one operand then we can */
3558 if (IC_LEFT (uic) == NULL ||
3559 IC_RIGHT (uic) == NULL)
3562 /* make sure this is on the left side if not
3563 a '+' since '+' is commutative */
3564 if (ic->op != '+' &&
3565 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3569 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3570 /* if one of them is a literal then we can */
3571 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3572 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3573 (getSize (operandType (IC_RESULT (uic))) <= 1))
3575 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3580 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3581 /* if the other one is not on stack then we can */
3582 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3583 (IS_ITEMP (IC_RIGHT (uic)) ||
3584 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3585 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3588 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3589 (IS_ITEMP (IC_LEFT (uic)) ||
3590 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3591 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3597 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3598 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3605 /*-----------------------------------------------------------------*/
3606 /* packForPush - hueristics to reduce iCode for pushing */
3607 /*-----------------------------------------------------------------*/
3609 packForReceive (iCode * ic, eBBlock * ebp)
3613 debugLog ("%s\n", __FUNCTION__);
3614 debugAopGet (" result:", IC_RESULT (ic));
3615 debugAopGet (" left:", IC_LEFT (ic));
3616 debugAopGet (" right:", IC_RIGHT (ic));
3621 for (dic = ic->next; dic; dic = dic->next)
3626 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3627 debugLog (" used on left\n");
3628 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3629 debugLog (" used on right\n");
3630 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3631 debugLog (" used on result\n");
3633 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3634 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3639 debugLog (" hey we can remove this unnecessary assign\n");
3641 /*-----------------------------------------------------------------*/
3642 /* packForPush - hueristics to reduce iCode for pushing */
3643 /*-----------------------------------------------------------------*/
3645 packForPush (iCode * ic, eBBlock * ebp)
3649 debugLog ("%s\n", __FUNCTION__);
3650 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3653 /* must have only definition & one usage */
3654 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3655 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3658 /* find the definition */
3659 if (!(dic = hTabItemWithKey (iCodehTab,
3660 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3663 if (dic->op != '=' || POINTER_SET (dic))
3666 /* we now we know that it has one & only one def & use
3667 and the that the definition is an assignment */
3668 IC_LEFT (ic) = IC_RIGHT (dic);
3670 remiCodeFromeBBlock (ebp, dic);
3671 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3672 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3675 static void printSymType(char * str, sym_link *sl)
3677 if(!pic16_ralloc_debug)return;
3679 debugLog (" %s Symbol type: ",str);
3680 printTypeChain( sl, debugF);
3684 /*-----------------------------------------------------------------*/
3685 /* some debug code to print the symbol S_TYPE. Note that
3686 * the function checkSClass in src/SDCCsymt.c dinks with
3687 * the S_TYPE in ways the PIC port doesn't fully like...*/
3688 /*-----------------------------------------------------------------*/
3689 static void isData(sym_link *sl)
3693 if(!pic16_ralloc_debug)return;
3700 for ( ; sl; sl=sl->next) {
3702 switch (SPEC_SCLS(sl)) {
3703 case S_DATA: fprintf (of, "data "); break;
3704 case S_XDATA: fprintf (of, "xdata "); break;
3705 case S_SFR: fprintf (of, "sfr "); break;
3706 case S_SBIT: fprintf (of, "sbit "); break;
3707 case S_CODE: fprintf (of, "code "); break;
3708 case S_IDATA: fprintf (of, "idata "); break;
3709 case S_PDATA: fprintf (of, "pdata "); break;
3710 case S_LITERAL: fprintf (of, "literal "); break;
3711 case S_STACK: fprintf (of, "stack "); break;
3712 case S_XSTACK: fprintf (of, "xstack "); break;
3713 case S_BIT: fprintf (of, "bit "); break;
3714 case S_EEPROM: fprintf (of, "eeprom "); break;
3723 /*--------------------------------------------------------------------*/
3724 /* pic16_packRegisters - does some transformations to reduce */
3725 /* register pressure */
3727 /*--------------------------------------------------------------------*/
3729 pic16_packRegisters (eBBlock * ebp)
3734 debugLog ("%s\n", __FUNCTION__);
3740 /* look for assignments of the form */
3741 /* iTempNN = TRueSym (someoperation) SomeOperand */
3743 /* TrueSym := iTempNN:1 */
3744 for (ic = ebp->sch; ic; ic = ic->next)
3746 // debugLog("%d\n", __LINE__);
3747 /* find assignment of the form TrueSym := iTempNN:1 */
3748 /* see BUGLOG0001 for workaround with the CAST - VR */
3749 // if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3750 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3751 change += packRegsForAssign (ic, ebp);
3755 if (POINTER_SET (ic))
3756 debugLog ("pointer is set\n");
3757 debugAopGet (" result:", IC_RESULT (ic));
3758 debugAopGet (" left:", IC_LEFT (ic));
3759 debugAopGet (" right:", IC_RIGHT (ic));
3768 for (ic = ebp->sch; ic; ic = ic->next) {
3770 if(IS_SYMOP ( IC_LEFT(ic))) {
3771 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3773 debugAopGet ("x left:", IC_LEFT (ic));
3775 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3777 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3779 debugLog (" is a pointer\n");
3781 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3782 debugLog (" is a ptr\n");
3784 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3785 debugLog (" is volatile\n");
3789 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3790 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3791 pic16_allocDirReg(IC_LEFT (ic));
3794 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3797 if(IS_SYMOP ( IC_RIGHT(ic))) {
3798 debugAopGet (" right:", IC_RIGHT (ic));
3799 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3802 if(IS_SYMOP ( IC_RESULT(ic))) {
3803 debugAopGet (" result:", IC_RESULT (ic));
3804 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3807 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3808 debugAopGet (" right:", IC_RIGHT (ic));
3809 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3810 // pic16_allocDirReg(IC_RIGHT(ic));
3813 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3814 debugAopGet (" result:", IC_RESULT (ic));
3815 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3816 // pic16_allocDirReg(IC_RESULT(ic));
3820 if (POINTER_SET (ic))
3821 debugLog (" %d - Pointer set\n", __LINE__);
3824 /* Look for two subsequent iCodes with */
3826 /* _c = iTemp & op; */
3827 /* and replace them by */
3830 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3832 ic->prev->op == '=' &&
3833 IS_ITEMP (IC_LEFT (ic)) &&
3834 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3835 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3837 iCode* ic_prev = ic->prev;
3838 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3840 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3841 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3843 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3844 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3845 prev_result_sym->liveTo == ic->seq)
3847 prev_result_sym->liveTo = ic_prev->seq;
3850 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3852 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3854 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3856 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3857 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3858 remiCodeFromeBBlock (ebp, ic_prev);
3859 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3863 /* if this is an itemp & result of a address of a true sym
3864 then mark this as rematerialisable */
3865 if (ic->op == ADDRESS_OF &&
3866 IS_ITEMP (IC_RESULT (ic)) &&
3867 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3868 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3869 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3872 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3874 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3875 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3876 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3880 /* if straight assignment then carry remat flag if
3881 this is the only definition */
3882 if (ic->op == '=' &&
3883 !POINTER_SET (ic) &&
3884 IS_SYMOP (IC_RIGHT (ic)) &&
3885 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3886 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3888 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3890 OP_SYMBOL (IC_RESULT (ic))->remat =
3891 OP_SYMBOL (IC_RIGHT (ic))->remat;
3892 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3893 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3896 /* if this is a +/- operation with a rematerizable
3897 then mark this as rematerializable as well */
3898 if ((ic->op == '+' || ic->op == '-') &&
3899 (IS_SYMOP (IC_LEFT (ic)) &&
3900 IS_ITEMP (IC_RESULT (ic)) &&
3901 OP_SYMBOL (IC_LEFT (ic))->remat &&
3902 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3903 IS_OP_LITERAL (IC_RIGHT (ic))))
3905 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3907 operandLitValue (IC_RIGHT (ic));
3908 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3909 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3910 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3913 /* mark the pointer usages */
3914 if (POINTER_SET (ic))
3916 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3917 debugLog (" marking as a pointer (set) =>");
3918 debugAopGet (" result:", IC_RESULT (ic));
3920 if (POINTER_GET (ic))
3922 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3923 debugLog (" marking as a pointer (get) =>");
3924 debugAopGet (" left:", IC_LEFT (ic));
3927 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3931 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3932 /* if we are using a symbol on the stack
3933 then we should say pic16_ptrRegReq */
3934 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3935 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3936 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3937 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3938 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3939 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3943 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3944 if (IS_SYMOP (IC_LEFT (ic)))
3945 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3946 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3947 if (IS_SYMOP (IC_RIGHT (ic)))
3948 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3949 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3950 if (IS_SYMOP (IC_RESULT (ic)))
3951 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3952 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3955 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3959 /* if the condition of an if instruction
3960 is defined in the previous instruction then
3961 mark the itemp as a conditional */
3962 if ((IS_CONDITIONAL (ic) ||
3963 ((ic->op == BITWISEAND ||
3966 isBitwiseOptimizable (ic))) &&
3967 ic->next && ic->next->op == IFX &&
3968 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3969 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3972 debugLog (" %d\n", __LINE__);
3973 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3977 debugLog(" %d\n", __LINE__);
3979 #ifndef NO_packRegsForSupport
3980 /* reduce for support function calls */
3981 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3982 packRegsForSupport (ic, ebp);
3985 /* if a parameter is passed, it's in W, so we may not
3986 need to place a copy in a register */
3987 if (ic->op == RECEIVE)
3988 packForReceive (ic, ebp);
3990 #ifndef NO_packRegsForOneuse
3991 /* some cases the redundant moves can
3992 can be eliminated for return statements */
3993 if ((ic->op == RETURN || ic->op == SEND) &&
3994 !isOperandInFarSpace (IC_LEFT (ic)) &&
3996 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3999 #ifndef NO_packRegsForOneuse
4000 /* if pointer set & left has a size more than
4001 one and right is not in far space */
4002 if (POINTER_SET (ic) &&
4003 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4004 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4005 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4006 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4008 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4011 #ifndef NO_packRegsForOneuse
4012 /* if pointer get */
4013 if (POINTER_GET (ic) &&
4014 !isOperandInFarSpace (IC_RESULT (ic)) &&
4015 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4016 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4017 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4019 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4020 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4023 #ifndef NO_cast_peep
4024 /* if this is cast for intergral promotion then
4025 check if only use of the definition of the
4026 operand being casted/ if yes then replace
4027 the result of that arithmetic operation with
4028 this result and get rid of the cast */
4029 if (ic->op == CAST) {
4031 sym_link *fromType = operandType (IC_RIGHT (ic));
4032 sym_link *toType = operandType (IC_LEFT (ic));
4034 debugLog (" %d - casting\n", __LINE__);
4036 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4037 getSize (fromType) != getSize (toType)) {
4040 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4043 if (IS_ARITHMETIC_OP (dic)) {
4044 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4046 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4047 IC_RESULT (dic) = IC_RESULT (ic);
4048 remiCodeFromeBBlock (ebp, ic);
4049 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4050 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4051 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4055 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4059 /* if the type from and type to are the same
4060 then if this is the only use then packit */
4061 if (compareType (operandType (IC_RIGHT (ic)),
4062 operandType (IC_LEFT (ic))) == 1) {
4064 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4067 debugLog(" %d\n", __LINE__);
4069 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4070 IC_RESULT (dic) = IC_RESULT (ic);
4071 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4072 remiCodeFromeBBlock (ebp, ic);
4073 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4074 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4082 iTempNN := (some variable in farspace) V1
4087 if (ic->op == IPUSH)
4089 packForPush (ic, ebp);
4093 #ifndef NO_packRegsForAccUse
4094 /* pack registers for accumulator use, when the
4095 result of an arithmetic or bit wise operation
4096 has only one use, that use is immediately following
4097 the defintion and the using iCode has only one
4098 operand or has two operands but one is literal &
4099 the result of that operation is not on stack then
4100 we can leave the result of this operation in acc:b
4102 if ((IS_ARITHMETIC_OP (ic)
4104 || IS_BITWISE_OP (ic)
4106 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4109 IS_ITEMP (IC_RESULT (ic)) &&
4110 getSize (operandType (IC_RESULT (ic))) <= 1)
4112 packRegsForAccUse (ic);
4119 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4123 if (!pic16_ralloc_debug || !debugF)
4126 for (i = 0; i < count; i++)
4128 fprintf (debugF, "\n----------------------------------------------------------------\n");
4129 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4130 ebbs[i]->entryLabel->name,
4133 ebbs[i]->isLastInLoop);
4134 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4139 fprintf (debugF, "visited %d : hasFcall = %d\n",
4143 fprintf (debugF, "\ndefines bitVector :");
4144 bitVectDebugOn (ebbs[i]->defSet, debugF);
4145 fprintf (debugF, "\nlocal defines bitVector :");
4146 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4147 fprintf (debugF, "\npointers Set bitvector :");
4148 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4149 fprintf (debugF, "\nin pointers Set bitvector :");
4150 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4151 fprintf (debugF, "\ninDefs Set bitvector :");
4152 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4153 fprintf (debugF, "\noutDefs Set bitvector :");
4154 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4155 fprintf (debugF, "\nusesDefs Set bitvector :");
4156 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4157 fprintf (debugF, "\n----------------------------------------------------------------\n");
4158 printiCChain (ebbs[i]->sch, debugF);
4161 /*-----------------------------------------------------------------*/
4162 /* pic16_assignRegisters - assigns registers to each live range as need */
4163 /*-----------------------------------------------------------------*/
4165 pic16_assignRegisters (eBBlock ** ebbs, int count)
4170 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4171 debugLog ("\nebbs before optimizing:\n");
4172 dumpEbbsToDebug (ebbs, count);
4174 _inRegAllocator = 1;
4176 setToNull ((void *) &_G.funcrUsed);
4177 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4180 /* change assignments this will remove some
4181 live ranges reducing some register pressure */
4182 for (i = 0; i < count; i++)
4183 pic16_packRegisters (ebbs[i]);
4190 debugLog("dir registers allocated so far:\n");
4191 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4194 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4195 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4196 reg = hTabNextItem(dynDirectRegNames, &hkey);
4201 /* liveranges probably changed by register packing
4202 so we compute them again */
4203 recomputeLiveRanges (ebbs, count);
4205 if (options.dump_pack)
4206 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4208 /* first determine for each live range the number of
4209 registers & the type of registers required for each */
4212 /* and serially allocate registers */
4213 serialRegAssign (ebbs, count);
4216 debugLog ("ebbs after serialRegAssign:\n");
4217 dumpEbbsToDebug (ebbs, count);
4220 //pic16_freeAllRegs();
4222 /* if stack was extended then tell the user */
4225 /* werror(W_TOOMANY_SPILS,"stack", */
4226 /* _G.stackExtend,currFunc->name,""); */
4232 /* werror(W_TOOMANY_SPILS,"data space", */
4233 /* _G.dataExtend,currFunc->name,""); */
4237 /* after that create the register mask
4238 for each of the instruction */
4239 createRegMask (ebbs, count);
4241 /* redo that offsets for stacked automatic variables */
4242 redoStackOffsets ();
4244 if (options.dump_rassgn)
4245 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4247 /* now get back the chain */
4248 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4250 debugLog ("ebbs after optimizing:\n");
4251 dumpEbbsToDebug (ebbs, count);
4253 _inRegAllocator = 0;
4257 /* free up any _G.stackSpil locations allocated */
4258 applyToSet (_G.stackSpil, deallocStackSpil);
4260 setToNull ((void *) &_G.stackSpil);
4261 setToNull ((void *) &_G.spiltSet);
4262 /* mark all registers as free */
4263 pic16_freeAllRegs ();
4266 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");