1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
41 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
43 void _debugf(char *f, int l, char *frm, ...);
45 #define NEWREG_DEBUG 0
49 /*-----------------------------------------------------------------*/
50 /* At this point we start getting processor specific although */
51 /* some routines are non-processor specific & can be reused when */
52 /* targetting other processors. The decision for this will have */
53 /* to be made on a routine by routine basis */
54 /* routines used to pack registers are most definitely not reusable */
55 /* since the pack the registers depending strictly on the MCU */
56 /*-----------------------------------------------------------------*/
58 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
59 extern void genpic16Code (iCode *);
69 bitVect *funcrUsed; /* registers used in a function */
75 /* Shared with gen.c */
76 int pic16_ptrRegReq; /* one byte pointer register required */
79 set *pic16_dynAllocRegs=NULL;
80 set *pic16_dynStackRegs=NULL;
81 set *pic16_dynProcessorRegs=NULL;
82 set *pic16_dynDirectRegs=NULL;
83 set *pic16_dynDirectBitRegs=NULL;
84 set *pic16_dynInternalRegs=NULL;
85 set *pic16_dynAccessRegs=NULL;
87 static hTab *dynDirectRegNames=NULL;
88 static hTab *dynAllocRegNames=NULL;
89 static hTab *dynProcRegNames=NULL;
90 static hTab *dynAccessRegNames=NULL;
91 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
93 extern set *sectNames;
95 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
96 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
97 set *pic16_equ_data=NULL; /* registers used by equates */
98 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
99 set *pic16_acs_udata=NULL; /* access bank variables */
101 set *pic16_builtin_functions=NULL;
103 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
104 static int rDirectIdx=0;
106 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
108 int pic16_Gstack_base_addr=0; /* The starting address of registers that
109 * are used to pass and return parameters */
112 int _inRegAllocator=0; /* flag that marks whther allocReg happens while
113 * inside the register allocator function */
116 static void spillThis (symbol *);
117 int pic16_ralloc_debug = 0;
118 static FILE *debugF = NULL;
119 /*-----------------------------------------------------------------*/
120 /* debugLog - open a file for debugging information */
121 /*-----------------------------------------------------------------*/
122 //static void debugLog(char *inst,char *fmt, ...)
124 debugLog (char *fmt,...)
126 static int append = 0; // First time through, open the file without append.
129 //char *bufferP=buffer;
132 if (!pic16_ralloc_debug || !dstFileName)
138 /* create the file name */
139 strcpy (buffer, dstFileName);
140 strcat (buffer, ".d");
142 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
144 werror (E_FILE_OPEN_ERR, buffer);
147 append = 1; // Next time debubLog is called, we'll append the debug info
153 vsprintf (buffer, fmt, ap);
155 fprintf (debugF, "%s", buffer);
157 while (isspace(*bufferP)) bufferP++;
159 if (bufferP && *bufferP)
160 lineCurr = (lineCurr ?
161 connectLine(lineCurr,newLineNode(lb)) :
162 (lineHead = newLineNode(lb)));
163 lineCurr->isInline = _G.inLine;
164 lineCurr->isDebug = _G.debugLine;
173 if(!pic16_ralloc_debug)return;
176 fputc ('\n', debugF);
178 /*-----------------------------------------------------------------*/
179 /* debugLogClose - closes the debug log file (if opened) */
180 /*-----------------------------------------------------------------*/
190 #define AOP(op) op->aop
193 debugAopGet (char *str, operand * op)
195 if(!pic16_ralloc_debug)return NULL;
200 printOperand (op, debugF);
207 pic16_decodeOp (unsigned int op)
209 if (op < 128 && op > ' ') {
210 buffer[0] = (op & 0xff);
216 case IDENTIFIER: return "IDENTIFIER";
217 case TYPE_NAME: return "TYPE_NAME";
218 case CONSTANT: return "CONSTANT";
219 case STRING_LITERAL: return "STRING_LITERAL";
220 case SIZEOF: return "SIZEOF";
221 case PTR_OP: return "PTR_OP";
222 case INC_OP: return "INC_OP";
223 case DEC_OP: return "DEC_OP";
224 case LEFT_OP: return "LEFT_OP";
225 case RIGHT_OP: return "RIGHT_OP";
226 case LE_OP: return "LE_OP";
227 case GE_OP: return "GE_OP";
228 case EQ_OP: return "EQ_OP";
229 case NE_OP: return "NE_OP";
230 case AND_OP: return "AND_OP";
231 case OR_OP: return "OR_OP";
232 case MUL_ASSIGN: return "MUL_ASSIGN";
233 case DIV_ASSIGN: return "DIV_ASSIGN";
234 case MOD_ASSIGN: return "MOD_ASSIGN";
235 case ADD_ASSIGN: return "ADD_ASSIGN";
236 case SUB_ASSIGN: return "SUB_ASSIGN";
237 case LEFT_ASSIGN: return "LEFT_ASSIGN";
238 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
239 case AND_ASSIGN: return "AND_ASSIGN";
240 case XOR_ASSIGN: return "XOR_ASSIGN";
241 case OR_ASSIGN: return "OR_ASSIGN";
242 case TYPEDEF: return "TYPEDEF";
243 case EXTERN: return "EXTERN";
244 case STATIC: return "STATIC";
245 case AUTO: return "AUTO";
246 case REGISTER: return "REGISTER";
247 case CODE: return "CODE";
248 case EEPROM: return "EEPROM";
249 case INTERRUPT: return "INTERRUPT";
250 case SFR: return "SFR";
251 case AT: return "AT";
252 case SBIT: return "SBIT";
253 case REENTRANT: return "REENTRANT";
254 case USING: return "USING";
255 case XDATA: return "XDATA";
256 case DATA: return "DATA";
257 case IDATA: return "IDATA";
258 case PDATA: return "PDATA";
259 case VAR_ARGS: return "VAR_ARGS";
260 case CRITICAL: return "CRITICAL";
261 case NONBANKED: return "NONBANKED";
262 case BANKED: return "BANKED";
263 case CHAR: return "CHAR";
264 case SHORT: return "SHORT";
265 case INT: return "INT";
266 case LONG: return "LONG";
267 case SIGNED: return "SIGNED";
268 case UNSIGNED: return "UNSIGNED";
269 case FLOAT: return "FLOAT";
270 case DOUBLE: return "DOUBLE";
271 case CONST: return "CONST";
272 case VOLATILE: return "VOLATILE";
273 case VOID: return "VOID";
274 case BIT: return "BIT";
275 case STRUCT: return "STRUCT";
276 case UNION: return "UNION";
277 case ENUM: return "ENUM";
278 case ELIPSIS: return "ELIPSIS";
279 case RANGE: return "RANGE";
280 case FAR: return "FAR";
281 case CASE: return "CASE";
282 case DEFAULT: return "DEFAULT";
283 case IF: return "IF";
284 case ELSE: return "ELSE";
285 case SWITCH: return "SWITCH";
286 case WHILE: return "WHILE";
287 case DO: return "DO";
288 case FOR: return "FOR";
289 case GOTO: return "GOTO";
290 case CONTINUE: return "CONTINUE";
291 case BREAK: return "BREAK";
292 case RETURN: return "RETURN";
293 case INLINEASM: return "INLINEASM";
294 case IFX: return "IFX";
295 case ADDRESS_OF: return "ADDRESS_OF";
296 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
297 case SPIL: return "SPIL";
298 case UNSPIL: return "UNSPIL";
299 case GETHBIT: return "GETHBIT";
300 case BITWISEAND: return "BITWISEAND";
301 case UNARYMINUS: return "UNARYMINUS";
302 case IPUSH: return "IPUSH";
303 case IPOP: return "IPOP";
304 case PCALL: return "PCALL";
305 case 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;
394 fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
398 dReg->reg_alias = NULL;
399 dReg->reglives.usedpFlows = newSet();
400 dReg->reglives.assignedpFlows = newSet();
403 if(!(type == REG_SFR && alias == 0x80))
404 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
409 /*-----------------------------------------------------------------*/
410 /* regWithIdx - Search through a set of registers that matches idx */
411 /*-----------------------------------------------------------------*/
413 regWithIdx (set *dRegs, int idx, unsigned fixed)
417 for (dReg = setFirstItem(dRegs) ; dReg ;
418 dReg = setNextItem(dRegs)) {
420 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
428 /*-----------------------------------------------------------------*/
429 /* regFindFree - Search for a free register in a set of registers */
430 /*-----------------------------------------------------------------*/
432 regFindFree (set *dRegs)
436 for (dReg = setFirstItem(dRegs) ; dReg ;
437 dReg = setNextItem(dRegs)) {
439 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
440 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
449 /*-----------------------------------------------------------------*/
450 /* pic16_initStack - allocate registers for a pseudo stack */
451 /*-----------------------------------------------------------------*/
452 void pic16_initStack(int base_address, int size)
457 pic16_Gstack_base_addr = base_address;
458 //fprintf(stderr,"initStack");
460 for(i = 0; i<size; i++)
461 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
464 /*-----------------------------------------------------------------*
465 *-----------------------------------------------------------------*/
467 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
469 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
471 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
473 reg->wasUsed = 0; // we do not know if they are going to be used at all
474 reg->accessBank = 1; // implicit add access Bank
476 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
478 return addSet(&pic16_dynProcessorRegs, reg);
481 /*-----------------------------------------------------------------*
482 *-----------------------------------------------------------------*/
485 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
487 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
489 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
493 return addSet(&pic16_dynInternalRegs,reg);
500 /*-----------------------------------------------------------------*/
501 /* allocReg - allocates register of given type */
502 /*-----------------------------------------------------------------*/
504 allocReg (short type)
508 #define MAX_P16_NREGS 6
512 if(dynrIdx > pic16_nRegs)
516 /* try to reuse some unused registers */
517 reg = regFindFree( pic16_dynAllocRegs );
520 // fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
524 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
525 // fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
528 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
529 // debugf("allocating more registers than available\n", 0);
534 // addSet(&pic16_dynAllocRegs, reg);
537 addSet(&pic16_dynAllocRegs, reg);
538 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
542 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
545 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
546 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
549 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
550 reg->isLocal = 1; /* this is a local frame register */
555 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
556 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
559 return (reg); // addSet(&pic16_dynAllocRegs,reg);
564 /*-----------------------------------------------------------------*/
565 /* pic16_dirregWithName - search for register by name */
566 /*-----------------------------------------------------------------*/
568 pic16_dirregWithName (char *name)
576 /* hash the name to get a key */
578 hkey = regname2key(name);
580 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
582 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
586 if(STRCASECMP(reg->name, name) == 0) {
587 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
591 reg = hTabNextItemWK (dynDirectRegNames);
595 return NULL; // name wasn't found in the hash table
598 /*-----------------------------------------------------------------*/
599 /* pic16_allocregWithName - search for register by name */
600 /*-----------------------------------------------------------------*/
602 pic16_allocregWithName (char *name)
610 /* hash the name to get a key */
612 hkey = regname2key(name);
614 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
616 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
620 if(STRCASECMP(reg->name, name) == 0) {
624 reg = hTabNextItemWK (dynAllocRegNames);
628 return NULL; // name wasn't found in the hash table
633 /*-----------------------------------------------------------------*/
634 /* pic16_procregWithName - search for register by name */
635 /*-----------------------------------------------------------------*/
637 pic16_procregWithName (char *name)
645 /* hash the name to get a key */
647 hkey = regname2key(name);
649 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
651 reg = hTabFirstItemWK(dynProcRegNames, hkey);
655 if(STRCASECMP(reg->name, name) == 0) {
659 reg = hTabNextItemWK (dynProcRegNames);
663 return NULL; // name wasn't found in the hash table
667 /*-----------------------------------------------------------------*/
668 /* pic16_accessregWithName - search for register by name */
669 /*-----------------------------------------------------------------*/
671 pic16_accessregWithName (char *name)
679 /* hash the name to get a key */
681 hkey = regname2key(name);
683 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
685 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
689 if(STRCASECMP(reg->name, name) == 0) {
693 reg = hTabNextItemWK (dynAccessRegNames);
697 return NULL; // name wasn't found in the hash table
701 regs *pic16_regWithName(char *name)
705 reg = pic16_dirregWithName( name );
708 reg = pic16_procregWithName( name );
711 reg = pic16_allocregWithName( name );
714 reg = pic16_accessregWithName( name );
721 /*-----------------------------------------------------------------*/
722 /* pic16_allocDirReg - allocates register of given type */
723 /*-----------------------------------------------------------------*/
725 pic16_allocDirReg (operand *op )
731 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
732 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
736 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
739 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
741 if(pic16_debug_verbose)
743 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
744 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
750 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
751 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
754 if(pic16_debug_verbose) {
755 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
756 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
757 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
758 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
759 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
760 IN_STACK( OP_SYM_ETYPE(op)),
761 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
762 IS_REGPARM(OP_SYM_ETYPE(op)),
765 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
766 OP_SYMBOL(op)->name);
774 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
775 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
779 if(IS_ITEMP(op))return NULL;
781 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
783 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
785 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
786 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
789 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
790 debugLog(" %d const char\n",__LINE__);
791 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
792 // fprintf(stderr, " %d const char\n",__LINE__);
793 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
797 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
798 if (IS_CODE ( OP_SYM_ETYPE(op)) )
799 debugLog(" %d code space\n",__LINE__);
801 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
802 debugLog(" %d integral\n",__LINE__);
804 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
805 debugLog(" %d literal\n",__LINE__);
807 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
808 debugLog(" %d specifier\n",__LINE__);
810 debugAopGet(NULL, op);
814 reg = pic16_dirregWithName(name);
818 int regtype = REG_GPR;
820 /* if this is at an absolute address, then get the address. */
821 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
822 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
823 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
826 /* Register wasn't found in hash, so let's create
827 * a new one and put it in the hash table AND in the
828 * dynDirectRegNames set */
829 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
830 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
836 if(OP_SYMBOL(op)->onStack) {
837 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
838 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
842 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
843 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
846 if(pic16_debug_verbose)
848 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
849 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
850 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
851 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
852 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
853 IN_STACK( OP_SYM_ETYPE(op)),
854 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
856 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
857 OP_SYMBOL(op)->name);
862 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
863 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
865 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
866 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
870 checkAddReg(&pic16_dynAccessRegs, reg);
871 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
877 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
878 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
879 // reg->type = REG_SFR;
882 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
883 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
884 addSet(&pic16_dynDirectBitRegs, reg);
887 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
888 // addSet(&pic16_dynDirectRegs, reg);
891 if(!(IS_STATIC(OP_SYM_ETYPE(op))
892 && OP_SYMBOL(op)->ival
895 checkAddReg(&pic16_dynDirectRegs, reg);
899 // debugLog (" -- %s is declared at address 0x30000x\n",name);
900 return (reg); /* This was NULL before, but since we found it
901 * why not just return it?! */
904 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
906 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
908 /* work around for user defined registers in access bank */
909 if((reg->address>= 0x00 && reg->address < 0x80)
910 || (reg->address >= 0xf80 && reg->address <= 0xfff))
913 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
919 /*-----------------------------------------------------------------*/
920 /* pic16_allocRegByName - allocates register of given type */
921 /*-----------------------------------------------------------------*/
923 pic16_allocRegByName (char *name, int size, operand *op)
929 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
933 /* First, search the hash table to see if there is a register with this name */
934 reg = pic16_dirregWithName(name);
938 /* Register wasn't found in hash, so let's create
939 * a new one and put it in the hash table AND in the
940 * dynDirectRegNames set */
942 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
944 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
946 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
947 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
949 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
950 addSet(&pic16_dynDirectRegs, reg);
956 /*-----------------------------------------------------------------*/
957 /* RegWithIdx - returns pointer to register with index number */
958 /*-----------------------------------------------------------------*/
959 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
964 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
965 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
970 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
972 debugLog ("Found a Dynamic Register!\n");
975 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
976 debugLog ("Found a Direct Register!\n");
982 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
983 debugLog ("Found a Stack Register!\n");
988 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
989 debugLog ("Found a Processor Register!\n");
1003 /*-----------------------------------------------------------------*/
1004 /* pic16_regWithIdx - returns pointer to register with index number*/
1005 /*-----------------------------------------------------------------*/
1007 pic16_regWithIdx (int idx)
1011 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1014 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1018 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1025 /*-----------------------------------------------------------------*/
1026 /* pic16_regWithIdx - returns pointer to register with index number */
1027 /*-----------------------------------------------------------------*/
1029 pic16_allocWithIdx (int idx)
1034 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1035 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1037 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1039 debugLog ("Found a Dynamic Register!\n");
1040 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1041 debugLog ("Found a Stack Register!\n");
1042 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1043 debugLog ("Found a Processor Register!\n");
1044 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1045 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1046 debugLog ("Found an Internal Register!\n");
1049 debugLog ("Dynamic Register not found\n");
1052 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1053 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1054 "regWithIdx not found");
1064 /*-----------------------------------------------------------------*/
1065 /*-----------------------------------------------------------------*/
1067 pic16_findFreeReg(short type)
1074 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1076 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1080 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1092 /*-----------------------------------------------------------------*/
1093 /* freeReg - frees a register */
1094 /*-----------------------------------------------------------------*/
1096 freeReg (regs * reg)
1098 debugLog ("%s\n", __FUNCTION__);
1099 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1104 /*-----------------------------------------------------------------*/
1105 /* nFreeRegs - returns number of free registers */
1106 /*-----------------------------------------------------------------*/
1108 nFreeRegs (int type)
1114 /* although I fixed the register allocation/freeing scheme
1115 * the for loop below doesn't give valid results. I do not
1116 * know why yet. -- VR 10-Jan-2003 */
1121 /* dynamically allocate as many as we need and worry about
1122 * fitting them into a PIC later */
1124 debugLog ("%s\n", __FUNCTION__);
1126 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1127 if((reg->type == type) && reg->isFree)nfr++;
1129 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1133 /*-----------------------------------------------------------------*/
1134 /* nfreeRegsType - free registers with type */
1135 /*-----------------------------------------------------------------*/
1137 nfreeRegsType (int type)
1140 debugLog ("%s\n", __FUNCTION__);
1141 if (type == REG_PTR)
1143 if ((nfr = nFreeRegs (type)) == 0)
1144 return nFreeRegs (REG_GPR);
1147 return nFreeRegs (type);
1150 static void writeSetUsedRegs(FILE *of, set *dRegs)
1155 for (dReg = setFirstItem(dRegs) ; dReg ;
1156 dReg = setNextItem(dRegs)) {
1159 fprintf (of, "\t%s\n",dReg->name);
1165 extern void pic16_groupRegistersInSection(set *regset);
1167 extern void pic16_dump_equates(FILE *of, set *equs);
1168 extern void pic16_dump_access(FILE *of, set *section);
1169 //extern void pic16_dump_map(void);
1170 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1171 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1172 extern void pic16_dump_int_registers(FILE *of, set *section);
1173 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1175 extern void pic16_dump_gsection(FILE *of, set *sections);
1177 static void packBits(set *bregs)
1181 regs *bitfield=NULL;
1182 regs *relocbitfield=NULL;
1188 for (regset = bregs ; regset ;
1189 regset = regset->next) {
1191 breg = regset->item;
1192 breg->isBitField = 1;
1193 //fprintf(stderr,"bit reg: %s\n",breg->name);
1196 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1198 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1199 breg->rIdx = breg->address & 7;
1200 breg->address >>= 3;
1203 sprintf (buffer, "fbitfield%02x", breg->address);
1204 //fprintf(stderr,"new bit field\n");
1205 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1206 bitfield->isBitField = 1;
1207 bitfield->isFixed = 1;
1208 bitfield->address = breg->address;
1209 addSet(&pic16_dynDirectRegs,bitfield);
1210 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1212 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1215 breg->reg_alias = bitfield;
1219 if(!relocbitfield || bit_no >7) {
1222 sprintf (buffer, "bitfield%d", byte_no);
1223 //fprintf(stderr,"new relocatable bit field\n");
1224 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1225 relocbitfield->isBitField = 1;
1226 addSet(&pic16_dynDirectRegs,relocbitfield);
1227 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1231 breg->reg_alias = relocbitfield;
1232 breg->address = rDirectIdx; /* byte_no; */
1233 breg->rIdx = bit_no++;
1239 void pic16_writeUsedRegs(FILE *of)
1241 packBits(pic16_dynDirectBitRegs);
1243 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1244 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1246 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1247 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1249 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1250 pic16_groupRegistersInSection(pic16_dynStackRegs);
1252 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1253 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1255 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1256 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1258 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1259 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1261 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1262 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1265 pic16_dump_equates(of, pic16_equ_data);
1267 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1268 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1270 /* dump access bank symbols */
1271 pic16_dump_access(of, pic16_acs_udata);
1273 /* dump initialised data */
1274 pic16_dump_isection(of, rel_idataSymSet, 0);
1275 pic16_dump_isection(of, fix_idataSymSet, 1);
1277 /* dump internal registers */
1278 pic16_dump_int_registers(of, pic16_int_regs);
1280 /* dump generic section variables */
1281 pic16_dump_gsection(of, sectNames);
1283 /* dump other variables */
1284 pic16_dump_usection(of, pic16_rel_udata, 0);
1285 pic16_dump_usection(of, pic16_fix_udata, 1);
1290 /*-----------------------------------------------------------------*/
1291 /* computeSpillable - given a point find the spillable live ranges */
1292 /*-----------------------------------------------------------------*/
1294 computeSpillable (iCode * ic)
1298 debugLog ("%s\n", __FUNCTION__);
1299 /* spillable live ranges are those that are live at this
1300 point . the following categories need to be subtracted
1302 a) - those that are already spilt
1303 b) - if being used by this one
1304 c) - defined by this one */
1306 spillable = bitVectCopy (ic->rlive);
1308 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1310 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1311 bitVectUnSetBit (spillable, ic->defKey);
1312 spillable = bitVectIntersect (spillable, _G.regAssigned);
1317 /*-----------------------------------------------------------------*/
1318 /* noSpilLoc - return true if a variable has no spil location */
1319 /*-----------------------------------------------------------------*/
1321 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1323 debugLog ("%s\n", __FUNCTION__);
1324 return (sym->usl.spillLoc ? 0 : 1);
1327 /*-----------------------------------------------------------------*/
1328 /* hasSpilLoc - will return 1 if the symbol has spil location */
1329 /*-----------------------------------------------------------------*/
1331 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1333 debugLog ("%s\n", __FUNCTION__);
1334 return (sym->usl.spillLoc ? 1 : 0);
1337 /*-----------------------------------------------------------------*/
1338 /* directSpilLoc - will return 1 if the splilocation is in direct */
1339 /*-----------------------------------------------------------------*/
1341 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1343 debugLog ("%s\n", __FUNCTION__);
1344 if (sym->usl.spillLoc &&
1345 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1351 /*-----------------------------------------------------------------*/
1352 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1353 /* but is not used as a pointer */
1354 /*-----------------------------------------------------------------*/
1356 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1358 debugLog ("%s\n", __FUNCTION__);
1359 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1362 /*-----------------------------------------------------------------*/
1363 /* rematable - will return 1 if the remat flag is set */
1364 /*-----------------------------------------------------------------*/
1366 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1368 debugLog ("%s\n", __FUNCTION__);
1372 /*-----------------------------------------------------------------*/
1373 /* notUsedInRemaining - not used or defined in remain of the block */
1374 /*-----------------------------------------------------------------*/
1376 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1378 debugLog ("%s\n", __FUNCTION__);
1379 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1380 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1383 /*-----------------------------------------------------------------*/
1384 /* allLRs - return true for all */
1385 /*-----------------------------------------------------------------*/
1387 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1389 debugLog ("%s\n", __FUNCTION__);
1393 /*-----------------------------------------------------------------*/
1394 /* liveRangesWith - applies function to a given set of live range */
1395 /*-----------------------------------------------------------------*/
1397 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1398 eBBlock * ebp, iCode * ic)
1403 debugLog ("%s\n", __FUNCTION__);
1404 if (!lrs || !lrs->size)
1407 for (i = 1; i < lrs->size; i++)
1410 if (!bitVectBitValue (lrs, i))
1413 /* if we don't find it in the live range
1414 hash table we are in serious trouble */
1415 if (!(sym = hTabItemWithKey (liveRanges, i)))
1417 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1418 "liveRangesWith could not find liveRange");
1422 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1423 addSetHead (&rset, sym);
1430 /*-----------------------------------------------------------------*/
1431 /* leastUsedLR - given a set determines which is the least used */
1432 /*-----------------------------------------------------------------*/
1434 leastUsedLR (set * sset)
1436 symbol *sym = NULL, *lsym = NULL;
1438 debugLog ("%s\n", __FUNCTION__);
1439 sym = lsym = setFirstItem (sset);
1444 for (; lsym; lsym = setNextItem (sset))
1447 /* if usage is the same then prefer
1448 the spill the smaller of the two */
1449 if (lsym->used == sym->used)
1450 if (getSize (lsym->type) < getSize (sym->type))
1454 if (lsym->used < sym->used)
1459 setToNull ((void *) &sset);
1464 /*-----------------------------------------------------------------*/
1465 /* noOverLap - will iterate through the list looking for over lap */
1466 /*-----------------------------------------------------------------*/
1468 noOverLap (set * itmpStack, symbol * fsym)
1471 debugLog ("%s\n", __FUNCTION__);
1474 for (sym = setFirstItem (itmpStack); sym;
1475 sym = setNextItem (itmpStack))
1477 if (sym->liveTo > fsym->liveFrom)
1485 /*-----------------------------------------------------------------*/
1486 /* isFree - will return 1 if the a free spil location is found */
1487 /*-----------------------------------------------------------------*/
1492 V_ARG (symbol **, sloc);
1493 V_ARG (symbol *, fsym);
1495 debugLog ("%s\n", __FUNCTION__);
1496 /* if already found */
1500 /* if it is free && and the itmp assigned to
1501 this does not have any overlapping live ranges
1502 with the one currently being assigned and
1503 the size can be accomodated */
1505 noOverLap (sym->usl.itmpStack, fsym) &&
1506 getSize (sym->type) >= getSize (fsym->type))
1515 /*-----------------------------------------------------------------*/
1516 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1517 /*-----------------------------------------------------------------*/
1519 spillLRWithPtrReg (symbol * forSym)
1525 debugLog ("%s\n", __FUNCTION__);
1526 if (!_G.regAssigned ||
1527 bitVectIsZero (_G.regAssigned))
1530 r0 = pic16_regWithIdx (R0_IDX);
1531 r1 = pic16_regWithIdx (R1_IDX);
1533 /* for all live ranges */
1534 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1535 lrsym = hTabNextItem (liveRanges, &k))
1539 /* if no registers assigned to it or
1541 /* if it does not overlap with this then
1542 not need to spill it */
1544 if (lrsym->isspilt || !lrsym->nRegs ||
1545 (lrsym->liveTo < forSym->liveFrom))
1548 /* go thru the registers : if it is either
1549 r0 or r1 then spil it */
1550 for (j = 0; j < lrsym->nRegs; j++)
1551 if (lrsym->regs[j] == r0 ||
1552 lrsym->regs[j] == r1)
1561 /*-----------------------------------------------------------------*/
1562 /* createStackSpil - create a location on the stack to spil */
1563 /*-----------------------------------------------------------------*/
1565 createStackSpil (symbol * sym)
1567 symbol *sloc = NULL;
1568 int useXstack, model, noOverlay;
1570 char slocBuffer[30];
1571 debugLog ("%s\n", __FUNCTION__);
1573 /* first go try and find a free one that is already
1574 existing on the stack */
1575 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1577 /* found a free one : just update & return */
1578 sym->usl.spillLoc = sloc;
1581 addSetHead (&sloc->usl.itmpStack, sym);
1585 /* could not then have to create one , this is the hard part
1586 we need to allocate this on the stack : this is really a
1587 hack!! but cannot think of anything better at this time */
1589 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1591 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1592 __FILE__, __LINE__);
1596 sloc = newiTemp (slocBuffer);
1598 /* set the type to the spilling symbol */
1599 sloc->type = copyLinkChain (sym->type);
1600 sloc->etype = getSpec (sloc->type);
1601 SPEC_SCLS (sloc->etype) = S_DATA;
1602 SPEC_EXTR (sloc->etype) = 0;
1603 SPEC_STAT (sloc->etype) = 0;
1605 /* we don't allow it to be allocated`
1606 onto the external stack since : so we
1607 temporarily turn it off ; we also
1608 turn off memory model to prevent
1609 the spil from going to the external storage
1610 and turn off overlaying
1613 useXstack = options.useXstack;
1614 model = options.model;
1615 noOverlay = options.noOverlay;
1616 options.noOverlay = 1;
1617 options.model = options.useXstack = 0;
1621 options.useXstack = useXstack;
1622 options.model = model;
1623 options.noOverlay = noOverlay;
1624 sloc->isref = 1; /* to prevent compiler warning */
1626 /* if it is on the stack then update the stack */
1627 if (IN_STACK (sloc->etype))
1629 currFunc->stack += getSize (sloc->type);
1630 _G.stackExtend += getSize (sloc->type);
1633 _G.dataExtend += getSize (sloc->type);
1635 /* add it to the _G.stackSpil set */
1636 addSetHead (&_G.stackSpil, sloc);
1637 sym->usl.spillLoc = sloc;
1640 /* add it to the set of itempStack set
1641 of the spill location */
1642 addSetHead (&sloc->usl.itmpStack, sym);
1646 /*-----------------------------------------------------------------*/
1647 /* isSpiltOnStack - returns true if the spil location is on stack */
1648 /*-----------------------------------------------------------------*/
1650 isSpiltOnStack (symbol * sym)
1654 debugLog ("%s\n", __FUNCTION__);
1661 /* if (sym->_G.stackSpil) */
1664 if (!sym->usl.spillLoc)
1667 etype = getSpec (sym->usl.spillLoc->type);
1668 if (IN_STACK (etype))
1674 /*-----------------------------------------------------------------*/
1675 /* spillThis - spils a specific operand */
1676 /*-----------------------------------------------------------------*/
1678 spillThis (symbol * sym)
1681 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1683 /* if this is rematerializable or has a spillLocation
1684 we are okay, else we need to create a spillLocation
1686 if (!(sym->remat || sym->usl.spillLoc))
1687 createStackSpil (sym);
1690 /* mark it has spilt & put it in the spilt set */
1692 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1694 bitVectUnSetBit (_G.regAssigned, sym->key);
1696 for (i = 0; i < sym->nRegs; i++)
1700 freeReg (sym->regs[i]);
1701 sym->regs[i] = NULL;
1704 /* if spilt on stack then free up r0 & r1
1705 if they could have been assigned to some
1707 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1710 spillLRWithPtrReg (sym);
1713 if (sym->usl.spillLoc && !sym->remat)
1714 sym->usl.spillLoc->allocreq = 1;
1718 /*-----------------------------------------------------------------*/
1719 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1720 /*-----------------------------------------------------------------*/
1722 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1724 bitVect *lrcs = NULL;
1728 debugLog ("%s\n", __FUNCTION__);
1729 /* get the spillable live ranges */
1730 lrcs = computeSpillable (ic);
1732 /* get all live ranges that are rematerizable */
1733 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1736 /* return the least used of these */
1737 return leastUsedLR (selectS);
1740 /* get live ranges with spillLocations in direct space */
1741 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1743 sym = leastUsedLR (selectS);
1744 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1745 sym->usl.spillLoc->rname :
1746 sym->usl.spillLoc->name));
1748 /* mark it as allocation required */
1749 sym->usl.spillLoc->allocreq = 1;
1753 /* if the symbol is local to the block then */
1754 if (forSym->liveTo < ebp->lSeq)
1757 /* check if there are any live ranges allocated
1758 to registers that are not used in this block */
1759 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1761 sym = leastUsedLR (selectS);
1762 /* if this is not rematerializable */
1771 /* check if there are any live ranges that not
1772 used in the remainder of the block */
1773 if (!_G.blockSpil &&
1774 !isiCodeInFunctionCall (ic) &&
1775 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1777 sym = leastUsedLR (selectS);
1780 sym->remainSpil = 1;
1787 /* find live ranges with spillocation && not used as pointers */
1788 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1791 sym = leastUsedLR (selectS);
1792 /* mark this as allocation required */
1793 sym->usl.spillLoc->allocreq = 1;
1797 /* find live ranges with spillocation */
1798 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1801 sym = leastUsedLR (selectS);
1802 sym->usl.spillLoc->allocreq = 1;
1806 /* couldn't find then we need to create a spil
1807 location on the stack , for which one? the least
1809 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1812 /* return a created spil location */
1813 sym = createStackSpil (leastUsedLR (selectS));
1814 sym->usl.spillLoc->allocreq = 1;
1818 /* this is an extreme situation we will spill
1819 this one : happens very rarely but it does happen */
1825 /*-----------------------------------------------------------------*/
1826 /* spilSomething - spil some variable & mark registers as free */
1827 /*-----------------------------------------------------------------*/
1829 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1834 debugLog ("%s\n", __FUNCTION__);
1835 /* get something we can spil */
1836 ssym = selectSpil (ic, ebp, forSym);
1838 /* mark it as spilt */
1840 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1842 /* mark it as not register assigned &
1843 take it away from the set */
1844 bitVectUnSetBit (_G.regAssigned, ssym->key);
1846 /* mark the registers as free */
1847 for (i = 0; i < ssym->nRegs; i++)
1849 freeReg (ssym->regs[i]);
1851 /* if spilt on stack then free up r0 & r1
1852 if they could have been assigned to as gprs */
1853 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1856 spillLRWithPtrReg (ssym);
1859 /* if this was a block level spil then insert push & pop
1860 at the start & end of block respectively */
1861 if (ssym->blockSpil)
1863 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1864 /* add push to the start of the block */
1865 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1866 ebp->sch->next : ebp->sch));
1867 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1868 /* add pop to the end of the block */
1869 addiCodeToeBBlock (ebp, nic, NULL);
1872 /* if spilt because not used in the remainder of the
1873 block then add a push before this instruction and
1874 a pop at the end of the block */
1875 if (ssym->remainSpil)
1878 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1879 /* add push just before this instruction */
1880 addiCodeToeBBlock (ebp, nic, ic);
1882 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1883 /* add pop to the end of the block */
1884 addiCodeToeBBlock (ebp, nic, NULL);
1893 /*-----------------------------------------------------------------*/
1894 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1895 /*-----------------------------------------------------------------*/
1897 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1902 debugLog ("%s\n", __FUNCTION__);
1904 /* try for a ptr type */
1905 if ((reg = allocReg (REG_PTR)))
1908 /* try for gpr type */
1909 if ((reg = allocReg (REG_GPR)))
1912 /* we have to spil */
1913 if (!spilSomething (ic, ebp, sym))
1916 /* make sure partially assigned registers aren't reused */
1917 for (j=0; j<=sym->nRegs; j++)
1919 sym->regs[j]->isFree = 0;
1921 /* this looks like an infinite loop but
1922 in really selectSpil will abort */
1926 /*-----------------------------------------------------------------*/
1927 /* getRegGpr - will try for GPR if not spil */
1928 /*-----------------------------------------------------------------*/
1930 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1935 debugLog ("%s\n", __FUNCTION__);
1937 /* try for gpr type */
1938 if ((reg = allocReg (REG_GPR)))
1941 if (!pic16_ptrRegReq)
1942 if ((reg = allocReg (REG_PTR)))
1945 /* we have to spil */
1946 if (!spilSomething (ic, ebp, sym))
1949 /* make sure partially assigned registers aren't reused */
1950 for (j=0; j<=sym->nRegs; j++)
1952 sym->regs[j]->isFree = 0;
1954 /* this looks like an infinite loop but
1955 in really selectSpil will abort */
1959 /*-----------------------------------------------------------------*/
1960 /* symHasReg - symbol has a given register */
1961 /*-----------------------------------------------------------------*/
1963 symHasReg (symbol * sym, regs * reg)
1967 debugLog ("%s\n", __FUNCTION__);
1968 for (i = 0; i < sym->nRegs; i++)
1969 if (sym->regs[i] == reg)
1975 /*-----------------------------------------------------------------*/
1976 /* deassignLRs - check the live to and if they have registers & are */
1977 /* not spilt then free up the registers */
1978 /*-----------------------------------------------------------------*/
1980 deassignLRs (iCode * ic, eBBlock * ebp)
1986 debugLog ("%s\n", __FUNCTION__);
1987 for (sym = hTabFirstItem (liveRanges, &k); sym;
1988 sym = hTabNextItem (liveRanges, &k))
1991 symbol *psym = NULL;
1992 /* if it does not end here */
1993 if (sym->liveTo > ic->seq)
1996 /* if it was spilt on stack then we can
1997 mark the stack spil location as free */
2002 sym->usl.spillLoc->isFree = 1;
2008 if (!bitVectBitValue (_G.regAssigned, sym->key))
2011 /* special case for shifting: there is a case where shift count
2012 * can be allocated in the same register as the result, so do not
2013 * free right registers if same as result registers, cause genShiftLeft
2014 * will fail -- VR */
2015 if(ic->op == LEFT_OP)
2018 /* special case check if this is an IFX &
2019 the privious one was a pop and the
2020 previous one was not spilt then keep track
2022 if (ic->op == IFX && ic->prev &&
2023 ic->prev->op == IPOP &&
2024 !ic->prev->parmPush &&
2025 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2026 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2032 bitVectUnSetBit (_G.regAssigned, sym->key);
2034 /* if the result of this one needs registers
2035 and does not have it then assign it right
2037 if (IC_RESULT (ic) &&
2038 !(SKIP_IC2 (ic) || /* not a special icode */
2039 ic->op == JUMPTABLE ||
2044 POINTER_SET (ic)) &&
2045 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2046 result->liveTo > ic->seq && /* and will live beyond this */
2047 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2048 result->liveFrom == ic->seq && /* does not start before here */
2049 result->regType == sym->regType && /* same register types */
2050 result->nRegs && /* which needs registers */
2051 !result->isspilt && /* and does not already have them */
2053 !bitVectBitValue (_G.regAssigned, result->key) &&
2054 /* the number of free regs + number of regs in this LR
2055 can accomodate the what result Needs */
2056 ((nfreeRegsType (result->regType) +
2057 sym->nRegs) >= result->nRegs)
2061 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2063 result->regs[i] = sym->regs[i];
2065 result->regs[i] = getRegGpr (ic, ebp, result);
2067 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2071 /* free the remaining */
2072 for (; i < sym->nRegs; i++)
2076 if (!symHasReg (psym, sym->regs[i]))
2077 freeReg (sym->regs[i]);
2080 freeReg (sym->regs[i]);
2087 /*-----------------------------------------------------------------*/
2088 /* reassignLR - reassign this to registers */
2089 /*-----------------------------------------------------------------*/
2091 reassignLR (operand * op)
2093 symbol *sym = OP_SYMBOL (op);
2096 debugLog ("%s\n", __FUNCTION__);
2097 /* not spilt any more */
2098 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2099 bitVectUnSetBit (_G.spiltSet, sym->key);
2101 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2105 for (i = 0; i < sym->nRegs; i++)
2106 sym->regs[i]->isFree = 0;
2109 /*-----------------------------------------------------------------*/
2110 /* willCauseSpill - determines if allocating will cause a spill */
2111 /*-----------------------------------------------------------------*/
2113 willCauseSpill (int nr, int rt)
2115 debugLog ("%s\n", __FUNCTION__);
2116 /* first check if there are any avlb registers
2117 of te type required */
2120 /* special case for pointer type
2121 if pointer type not avlb then
2122 check for type gpr */
2123 if (nFreeRegs (rt) >= nr)
2125 if (nFreeRegs (REG_GPR) >= nr)
2130 if (pic16_ptrRegReq)
2132 if (nFreeRegs (rt) >= nr)
2137 if (nFreeRegs (REG_PTR) +
2138 nFreeRegs (REG_GPR) >= nr)
2143 debugLog (" ... yep it will (cause a spill)\n");
2144 /* it will cause a spil */
2148 /*-----------------------------------------------------------------*/
2149 /* positionRegs - the allocator can allocate same registers to res- */
2150 /* ult and operand, if this happens make sure they are in the same */
2151 /* position as the operand otherwise chaos results */
2152 /*-----------------------------------------------------------------*/
2154 positionRegs (symbol * result, symbol * opsym, int lineno)
2156 int count = min (result->nRegs, opsym->nRegs);
2157 int i, j = 0, shared = 0;
2159 debugLog ("%s\n", __FUNCTION__);
2160 /* if the result has been spilt then cannot share */
2165 /* first make sure that they actually share */
2166 for (i = 0; i < count; i++)
2168 for (j = 0; j < count; j++)
2170 if (result->regs[i] == opsym->regs[j] && i != j)
2180 regs *tmp = result->regs[i];
2181 result->regs[i] = result->regs[j];
2182 result->regs[j] = tmp;
2187 /*------------------------------------------------------------------*/
2188 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2189 /* it should either have registers or have beed spilled. Otherwise, */
2190 /* there was an uninitialized variable, so just spill this to get */
2191 /* the operand in a valid state. */
2192 /*------------------------------------------------------------------*/
2194 verifyRegsAssigned (operand *op, iCode * ic)
2199 if (!IS_ITEMP (op)) return;
2201 sym = OP_SYMBOL (op);
2202 if (sym->isspilt) return;
2203 if (!sym->nRegs) return;
2204 if (sym->regs[0]) return;
2206 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2207 sym->prereqv ? sym->prereqv->name : sym->name);
2212 /*-----------------------------------------------------------------*/
2213 /* serialRegAssign - serially allocate registers to the variables */
2214 /*-----------------------------------------------------------------*/
2216 serialRegAssign (eBBlock ** ebbs, int count)
2221 debugLog ("%s\n", __FUNCTION__);
2222 /* for all blocks */
2223 for (i = 0; i < count; i++)
2225 if (ebbs[i]->noPath &&
2226 (ebbs[i]->entryLabel != entryLabel &&
2227 ebbs[i]->entryLabel != returnLabel))
2230 /* of all instructions do */
2231 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2234 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2236 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2237 pic16_allocDirReg(IC_RESULT(ic));
2239 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2240 pic16_allocDirReg(IC_LEFT(ic));
2242 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2243 pic16_allocDirReg(IC_RIGHT(ic));
2245 /* if this is an ipop that means some live
2246 range will have to be assigned again */
2248 reassignLR (IC_LEFT (ic));
2250 /* if result is present && is a true symbol */
2251 if (IC_RESULT (ic) && ic->op != IFX &&
2252 IS_TRUE_SYMOP (IC_RESULT (ic)))
2253 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2255 /* take away registers from live
2256 ranges that end at this instruction */
2257 deassignLRs (ic, ebbs[i]);
2259 /* some don't need registers */
2260 if (SKIP_IC2 (ic) ||
2261 ic->op == JUMPTABLE ||
2265 (IC_RESULT (ic) && POINTER_SET (ic)))
2268 /* now we need to allocate registers
2269 only for the result */
2272 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2278 /* Make sure any spill location is definately allocated */
2279 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2280 !sym->usl.spillLoc->allocreq)
2282 sym->usl.spillLoc->allocreq++;
2285 /* if it does not need or is spilt
2286 or is already assigned to registers
2287 or will not live beyond this instructions */
2290 bitVectBitValue (_G.regAssigned, sym->key) ||
2291 sym->liveTo <= ic->seq)
2294 /* if some liverange has been spilt at the block level
2295 and this one live beyond this block then spil this
2297 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2302 /* if trying to allocate this will cause
2303 a spill and there is nothing to spill
2304 or this one is rematerializable then
2306 willCS = willCauseSpill (sym->nRegs, sym->regType);
2308 /* explicit turn off register spilling */
2311 spillable = computeSpillable (ic);
2313 (willCS && bitVectIsZero (spillable)))
2321 /* If the live range preceeds the point of definition
2322 then ideally we must take into account registers that
2323 have been allocated after sym->liveFrom but freed
2324 before ic->seq. This is complicated, so spill this
2325 symbol instead and let fillGaps handle the allocation. */
2327 if (sym->liveFrom < ic->seq)
2333 /* if it has a spillocation & is used less than
2334 all other live ranges then spill this */
2336 if (sym->usl.spillLoc) {
2337 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2338 allLRs, ebbs[i], ic));
2339 if (leastUsed && leastUsed->used > sym->used) {
2344 /* if none of the liveRanges have a spillLocation then better
2345 to spill this one than anything else already assigned to registers */
2346 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2347 /* if this is local to this block then we might find a block spil */
2348 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2356 if (ic->op == RECEIVE)
2357 debugLog ("When I get clever, I'll optimize the receive logic\n");
2359 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2360 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2361 && (ic->next->op == IFX)
2362 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2364 /* skip register allocation since none will be used */
2365 for(j=0;j<sym->nRegs;j++)
2366 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2367 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2372 /* if we need ptr regs for the right side
2374 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2375 <= (unsigned) PTRSIZE)
2380 /* else we assign registers to it */
2381 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2384 bitVectDebugOn(_G.regAssigned, debugF);
2386 for (j = 0; j < sym->nRegs; j++)
2388 if (sym->regType == REG_PTR)
2389 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2391 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2393 /* if the allocation falied which means
2394 this was spilt then break */
2398 debugLog (" %d - \n", __LINE__);
2400 /* if it shares registers with operands make sure
2401 that they are in the same position */
2402 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2403 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2404 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2405 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2406 /* do the same for the right operand */
2407 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2408 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2409 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2410 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2412 debugLog (" %d - \n", __LINE__);
2415 debugLog (" %d - \n", __LINE__);
2424 /* Check for and fix any problems with uninitialized operands */
2425 for (i = 0; i < count; i++)
2429 if (ebbs[i]->noPath &&
2430 (ebbs[i]->entryLabel != entryLabel &&
2431 ebbs[i]->entryLabel != returnLabel))
2434 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2441 verifyRegsAssigned (IC_COND (ic), ic);
2445 if (ic->op == JUMPTABLE)
2447 verifyRegsAssigned (IC_JTCOND (ic), ic);
2451 verifyRegsAssigned (IC_RESULT (ic), ic);
2452 verifyRegsAssigned (IC_LEFT (ic), ic);
2453 verifyRegsAssigned (IC_RIGHT (ic), ic);
2459 /*-----------------------------------------------------------------*/
2460 /* rUmaskForOp :- returns register mask for an operand */
2461 /*-----------------------------------------------------------------*/
2463 rUmaskForOp (operand * op)
2469 debugLog ("%s\n", __FUNCTION__);
2470 /* only temporaries are assigned registers */
2474 sym = OP_SYMBOL (op);
2476 /* if spilt or no registers assigned to it
2478 if (sym->isspilt || !sym->nRegs)
2481 rumask = newBitVect (pic16_nRegs);
2483 for (j = 0; j < sym->nRegs; j++)
2485 rumask = bitVectSetBit (rumask,
2486 sym->regs[j]->rIdx);
2492 /*-----------------------------------------------------------------*/
2493 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2494 /*-----------------------------------------------------------------*/
2496 regsUsedIniCode (iCode * ic)
2498 bitVect *rmask = newBitVect (pic16_nRegs);
2500 debugLog ("%s\n", __FUNCTION__);
2501 /* do the special cases first */
2504 rmask = bitVectUnion (rmask,
2505 rUmaskForOp (IC_COND (ic)));
2509 /* for the jumptable */
2510 if (ic->op == JUMPTABLE)
2512 rmask = bitVectUnion (rmask,
2513 rUmaskForOp (IC_JTCOND (ic)));
2518 /* of all other cases */
2520 rmask = bitVectUnion (rmask,
2521 rUmaskForOp (IC_LEFT (ic)));
2525 rmask = bitVectUnion (rmask,
2526 rUmaskForOp (IC_RIGHT (ic)));
2529 rmask = bitVectUnion (rmask,
2530 rUmaskForOp (IC_RESULT (ic)));
2536 /*-----------------------------------------------------------------*/
2537 /* createRegMask - for each instruction will determine the regsUsed */
2538 /*-----------------------------------------------------------------*/
2540 createRegMask (eBBlock ** ebbs, int count)
2544 debugLog ("%s\n", __FUNCTION__);
2545 /* for all blocks */
2546 for (i = 0; i < count; i++)
2550 if (ebbs[i]->noPath &&
2551 (ebbs[i]->entryLabel != entryLabel &&
2552 ebbs[i]->entryLabel != returnLabel))
2555 /* for all instructions */
2556 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2561 if (SKIP_IC2 (ic) || !ic->rlive)
2564 /* first mark the registers used in this
2566 ic->rUsed = regsUsedIniCode (ic);
2567 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2569 /* now create the register mask for those
2570 registers that are in use : this is a
2571 super set of ic->rUsed */
2572 ic->rMask = newBitVect (pic16_nRegs + 1);
2574 /* for all live Ranges alive at this point */
2575 for (j = 1; j < ic->rlive->size; j++)
2580 /* if not alive then continue */
2581 if (!bitVectBitValue (ic->rlive, j))
2584 /* find the live range we are interested in */
2585 if (!(sym = hTabItemWithKey (liveRanges, j)))
2587 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2588 "createRegMask cannot find live range");
2592 /* if no register assigned to it */
2593 if (!sym->nRegs || sym->isspilt)
2596 /* for all the registers allocated to it */
2597 for (k = 0; k < sym->nRegs; k++)
2600 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2606 /*-----------------------------------------------------------------*/
2607 /* rematStr - returns the rematerialized string for a remat var */
2608 /*-----------------------------------------------------------------*/
2610 rematStr (symbol * sym)
2613 iCode *ic = sym->rematiCode;
2614 symbol *psym = NULL;
2616 debugLog ("%s\n", __FUNCTION__);
2618 //printf ("%s\n", s);
2620 /* if plus or minus print the right hand side */
2622 if (ic->op == '+' || ic->op == '-') {
2624 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2626 sprintf (s, "(%s %c 0x%04x)",
2627 OP_SYMBOL (IC_LEFT (ric))->rname,
2629 (int) operandLitValue (IC_RIGHT (ic)));
2632 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2634 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2635 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2640 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2641 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2643 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2648 /*-----------------------------------------------------------------*/
2649 /* rematStr - returns the rematerialized string for a remat var */
2650 /*-----------------------------------------------------------------*/
2652 rematStr (symbol * sym)
2655 iCode *ic = sym->rematiCode;
2657 debugLog ("%s\n", __FUNCTION__);
2662 /* if plus or minus print the right hand side */
2664 if (ic->op == '+' || ic->op == '-') {
2665 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2668 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2672 if (ic->op == '+' || ic->op == '-')
2674 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2675 sprintf (s, "(%s %c 0x%04x)",
2676 OP_SYMBOL (IC_LEFT (ric))->rname,
2678 (int) operandLitValue (IC_RIGHT (ic)));
2681 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2683 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2687 /* we reached the end */
2688 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2692 printf ("%s\n", buffer);
2697 /*-----------------------------------------------------------------*/
2698 /* regTypeNum - computes the type & number of registers required */
2699 /*-----------------------------------------------------------------*/
2707 debugLog ("%s\n", __FUNCTION__);
2708 /* for each live range do */
2709 for (sym = hTabFirstItem (liveRanges, &k); sym;
2710 sym = hTabNextItem (liveRanges, &k)) {
2712 debugLog (" %d - %s\n", __LINE__, sym->rname);
2713 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2715 /* if used zero times then no registers needed */
2716 if ((sym->liveTo - sym->liveFrom) == 0)
2720 /* if the live range is a temporary */
2723 debugLog (" %d - itemp register\n", __LINE__);
2725 /* if the type is marked as a conditional */
2726 if (sym->regType == REG_CND)
2729 /* if used in return only then we don't
2731 if (sym->ruonly || sym->accuse) {
2732 if (IS_AGGREGATE (sym->type) || sym->isptr)
2733 sym->type = aggrToPtr (sym->type, FALSE);
2734 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2738 /* if the symbol has only one definition &
2739 that definition is a get_pointer and the
2740 pointer we are getting is rematerializable and
2743 if (bitVectnBitsOn (sym->defs) == 1 &&
2744 (ic = hTabItemWithKey (iCodehTab,
2745 bitVectFirstBit (sym->defs))) &&
2747 !IS_BITVAR (sym->etype) &&
2748 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2750 if (ptrPseudoSymSafe (sym, ic)) {
2754 debugLog (" %d - \n", __LINE__);
2756 /* create a psuedo symbol & force a spil */
2757 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2758 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2759 psym->type = sym->type;
2760 psym->etype = sym->etype;
2761 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2762 strcpy (psym->rname, psym->name);
2764 sym->usl.spillLoc = psym;
2768 /* if in data space or idata space then try to
2769 allocate pointer register */
2773 /* if not then we require registers */
2774 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2775 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2776 getSize (sym->type));
2780 if(IS_PTR_CONST (sym->type)) {
2782 if(IS_CODEPTR (sym->type)) {
2784 // what IS this ???? (HJD)
2785 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2786 sym->nRegs = 3; // patch 14
2789 if (sym->nRegs > 4) {
2790 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2791 printTypeChain (sym->type, stderr);
2792 fprintf (stderr, "\n");
2795 /* determine the type of register required */
2796 if (sym->nRegs == 1 &&
2797 IS_PTR (sym->type) &&
2799 sym->regType = REG_PTR;
2801 sym->regType = REG_GPR;
2804 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2808 /* for the first run we don't provide */
2809 /* registers for true symbols we will */
2810 /* see how things go */
2816 static DEFSETFUNC (markRegFree)
2818 ((regs *)item)->isFree = 1;
2823 DEFSETFUNC (pic16_deallocReg)
2825 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2826 ((regs *)item)->isFree = 1;
2827 ((regs *)item)->wasUsed = 0;
2831 /*-----------------------------------------------------------------*/
2832 /* freeAllRegs - mark all registers as free */
2833 /*-----------------------------------------------------------------*/
2835 pic16_freeAllRegs ()
2837 debugLog ("%s\n", __FUNCTION__);
2839 applyToSet(pic16_dynAllocRegs,markRegFree);
2840 applyToSet(pic16_dynStackRegs,markRegFree);
2843 /*-----------------------------------------------------------------*/
2844 /*-----------------------------------------------------------------*/
2846 pic16_deallocateAllRegs ()
2848 debugLog ("%s\n", __FUNCTION__);
2850 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2854 /*-----------------------------------------------------------------*/
2855 /* deallocStackSpil - this will set the stack pointer back */
2856 /*-----------------------------------------------------------------*/
2858 DEFSETFUNC (deallocStackSpil)
2862 debugLog ("%s\n", __FUNCTION__);
2867 /*-----------------------------------------------------------------*/
2868 /* farSpacePackable - returns the packable icode for far variables */
2869 /*-----------------------------------------------------------------*/
2871 farSpacePackable (iCode * ic)
2875 debugLog ("%s\n", __FUNCTION__);
2876 /* go thru till we find a definition for the
2877 symbol on the right */
2878 for (dic = ic->prev; dic; dic = dic->prev)
2881 /* if the definition is a call then no */
2882 if ((dic->op == CALL || dic->op == PCALL) &&
2883 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2888 /* if shift by unknown amount then not */
2889 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2890 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2893 /* if pointer get and size > 1 */
2894 if (POINTER_GET (dic) &&
2895 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2898 if (POINTER_SET (dic) &&
2899 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2902 /* if any three is a true symbol in far space */
2903 if (IC_RESULT (dic) &&
2904 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2905 isOperandInFarSpace (IC_RESULT (dic)))
2908 if (IC_RIGHT (dic) &&
2909 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2910 isOperandInFarSpace (IC_RIGHT (dic)) &&
2911 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2914 if (IC_LEFT (dic) &&
2915 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2916 isOperandInFarSpace (IC_LEFT (dic)) &&
2917 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2920 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2922 if ((dic->op == LEFT_OP ||
2923 dic->op == RIGHT_OP ||
2925 IS_OP_LITERAL (IC_RIGHT (dic)))
2935 /*-----------------------------------------------------------------*/
2936 /* packRegsForAssign - register reduction for assignment */
2937 /*-----------------------------------------------------------------*/
2939 packRegsForAssign (iCode * ic, eBBlock * ebp)
2944 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2945 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
2946 debugAopGet (" result:", IC_RESULT (ic));
2947 debugAopGet (" left:", IC_LEFT (ic));
2948 debugAopGet (" right:", IC_RIGHT (ic));
2950 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2952 debugLog(" %d - actuall processing\n", __LINE__ );
2954 if (!IS_ITEMP (IC_RESULT (ic))) {
2955 pic16_allocDirReg(IC_RESULT (ic));
2956 debugLog (" %d - result is not temp\n", __LINE__);
2959 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
2961 /* See BUGLOG0001 - VR */
2963 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
2964 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2965 pic16_allocDirReg(IC_RIGHT (ic));
2970 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2971 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2973 debugLog (" %d - not packing - right side fails \n", __LINE__);
2977 /* if the true symbol is defined in far space or on stack
2978 then we should not since this will increase register pressure */
2979 if (isOperandInFarSpace (IC_RESULT (ic)))
2981 if ((dic = farSpacePackable (ic)))
2988 /* find the definition of iTempNN scanning backwards if we find a
2989 a use of the true symbol before we find the definition then
2991 for (dic = ic->prev; dic; dic = dic->prev)
2994 /* if there is a function call and this is
2995 a parameter & not my parameter then don't pack it */
2996 if ((dic->op == CALL || dic->op == PCALL) &&
2997 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2998 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3000 debugLog (" %d - \n", __LINE__);
3009 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3011 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3012 IS_OP_VOLATILE (IC_RESULT (dic)))
3014 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3020 if( IS_SYMOP( IC_RESULT(dic)) &&
3021 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3023 debugLog (" %d - result is bitfield\n", __LINE__);
3029 if (IS_SYMOP (IC_RESULT (dic)) &&
3030 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3032 /* A previous result was assigned to the same register - we'll our definition */
3033 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3034 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3035 if (POINTER_SET (dic))
3041 if (IS_SYMOP (IC_RIGHT (dic)) &&
3042 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3043 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3045 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3050 if (IS_SYMOP (IC_LEFT (dic)) &&
3051 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3052 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3054 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3059 if (POINTER_SET (dic) &&
3060 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3062 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3070 return 0; /* did not find */
3073 /* This code is taken from the hc08 port. Do not know
3074 * if it fits for pic16, but I leave it here just in case */
3076 /* if assignment then check that right is not a bit */
3077 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3078 sym_link *etype = operandType (IC_RIGHT (dic));
3080 if (IS_BITFIELD (etype)) {
3081 /* if result is a bit too then it's ok */
3082 etype = operandType (IC_RESULT (dic));
3083 if (!IS_BITFIELD (etype)) {
3084 debugLog(" %d bitfields\n");
3091 /* if the result is on stack or iaccess then it must be
3092 the same atleast one of the operands */
3093 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3094 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3096 /* the operation has only one symbol
3097 operator then we can pack */
3098 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3099 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3102 if (!((IC_LEFT (dic) &&
3103 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3105 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3109 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3110 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3111 /* found the definition */
3112 /* replace the result with the result of */
3113 /* this assignment and remove this assignment */
3114 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3115 IC_RESULT (dic) = IC_RESULT (ic);
3117 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3119 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3121 /* delete from liverange table also
3122 delete from all the points inbetween and the new
3124 for (sic = dic; sic != ic; sic = sic->next)
3126 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3127 if (IS_ITEMP (IC_RESULT (dic)))
3128 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3131 remiCodeFromeBBlock (ebp, ic);
3132 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3134 debugLog(" %d\n", __LINE__ );
3135 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3136 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3144 #define NO_packRegsForAccUse
3145 #define NO_packRegsForSupport
3146 #define NO_packRegsForOneuse
3147 #define NO_cast_peep
3152 #ifndef NO_packRegsForSupport
3153 /*-----------------------------------------------------------------*/
3154 /* findAssignToSym : scanning backwards looks for first assig found */
3155 /*-----------------------------------------------------------------*/
3157 findAssignToSym (operand * op, iCode * ic)
3161 debugLog ("%s\n", __FUNCTION__);
3162 for (dic = ic->prev; dic; dic = dic->prev)
3165 /* if definition by assignment */
3166 if (dic->op == '=' &&
3167 !POINTER_SET (dic) &&
3168 IC_RESULT (dic)->key == op->key
3169 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3173 /* we are interested only if defined in far space */
3174 /* or in stack space in case of + & - */
3176 /* if assigned to a non-symbol then return
3178 if (!IS_SYMOP (IC_RIGHT (dic)))
3181 /* if the symbol is in far space then
3183 if (isOperandInFarSpace (IC_RIGHT (dic)))
3186 /* for + & - operations make sure that
3187 if it is on the stack it is the same
3188 as one of the three operands */
3189 if ((ic->op == '+' || ic->op == '-') &&
3190 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3192 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3193 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3194 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3202 /* if we find an usage then we cannot delete it */
3203 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3206 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3209 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3213 /* now make sure that the right side of dic
3214 is not defined between ic & dic */
3217 iCode *sic = dic->next;
3219 for (; sic != ic; sic = sic->next)
3220 if (IC_RESULT (sic) &&
3221 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3232 #ifndef NO_packRegsForSupport
3233 /*-----------------------------------------------------------------*/
3234 /* packRegsForSupport :- reduce some registers for support calls */
3235 /*-----------------------------------------------------------------*/
3237 packRegsForSupport (iCode * ic, eBBlock * ebp)
3241 debugLog ("%s\n", __FUNCTION__);
3242 /* for the left & right operand :- look to see if the
3243 left was assigned a true symbol in far space in that
3244 case replace them */
3245 if (IS_ITEMP (IC_LEFT (ic)) &&
3246 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3248 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3254 debugAopGet ("removing left:", IC_LEFT (ic));
3256 /* found it we need to remove it from the
3258 for (sic = dic; sic != ic; sic = sic->next)
3259 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3261 IC_LEFT (ic)->operand.symOperand =
3262 IC_RIGHT (dic)->operand.symOperand;
3263 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3264 remiCodeFromeBBlock (ebp, dic);
3265 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3266 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3270 /* do the same for the right operand */
3273 IS_ITEMP (IC_RIGHT (ic)) &&
3274 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3276 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3282 /* if this is a subtraction & the result
3283 is a true symbol in far space then don't pack */
3284 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3286 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3287 if (IN_FARSPACE (SPEC_OCLS (etype)))
3291 debugAopGet ("removing right:", IC_RIGHT (ic));
3293 /* found it we need to remove it from the
3295 for (sic = dic; sic != ic; sic = sic->next)
3296 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3298 IC_RIGHT (ic)->operand.symOperand =
3299 IC_RIGHT (dic)->operand.symOperand;
3300 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3302 remiCodeFromeBBlock (ebp, dic);
3303 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3304 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3313 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3315 #ifndef NO_packRegsForOneuse
3316 /*-----------------------------------------------------------------*/
3317 /* packRegsForOneuse : - will reduce some registers for single Use */
3318 /*-----------------------------------------------------------------*/
3320 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3325 debugLog ("%s\n", __FUNCTION__);
3326 /* if returning a literal then do nothing */
3330 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3333 /* only upto 2 bytes since we cannot predict
3334 the usage of b, & acc */
3335 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3343 /* this routine will mark the a symbol as used in one
3344 instruction use only && if the definition is local
3345 (ie. within the basic block) && has only one definition &&
3346 that definition is either a return value from a
3347 function or does not contain any variables in
3351 uses = bitVectCopy (OP_USES (op));
3352 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3353 if (!bitVectIsZero (uses)) /* has other uses */
3358 if (bitVectnBitsOn (OP_USES (op)) > 1)
3362 /* if it has only one defintion */
3363 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3364 return NULL; /* has more than one definition */
3366 /* get that definition */
3368 hTabItemWithKey (iCodehTab,
3369 bitVectFirstBit (OP_DEFS (op)))))
3372 /* found the definition now check if it is local */
3373 if (dic->seq < ebp->fSeq ||
3374 dic->seq > ebp->lSeq)
3375 return NULL; /* non-local */
3377 /* now check if it is the return from
3379 if (dic->op == CALL || dic->op == PCALL)
3381 if (ic->op != SEND && ic->op != RETURN &&
3382 !POINTER_SET(ic) && !POINTER_GET(ic))
3384 OP_SYMBOL (op)->ruonly = 1;
3393 /* otherwise check that the definition does
3394 not contain any symbols in far space */
3395 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3396 isOperandInFarSpace (IC_RIGHT (dic)) ||
3397 IS_OP_RUONLY (IC_LEFT (ic)) ||
3398 IS_OP_RUONLY (IC_RIGHT (ic)))
3403 /* if pointer set then make sure the pointer
3405 if (POINTER_SET (dic) &&
3406 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3409 if (POINTER_GET (dic) &&
3410 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3416 /* also make sure the intervenening instructions
3417 don't have any thing in far space */
3418 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3421 /* if there is an intervening function call then no */
3422 if (dic->op == CALL || dic->op == PCALL)
3424 /* if pointer set then make sure the pointer
3426 if (POINTER_SET (dic) &&
3427 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3430 if (POINTER_GET (dic) &&
3431 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3434 /* if address of & the result is remat then okay */
3435 if (dic->op == ADDRESS_OF &&
3436 OP_SYMBOL (IC_RESULT (dic))->remat)
3439 /* if operand has size of three or more & this
3440 operation is a '*','/' or '%' then 'b' may
3442 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3443 getSize (operandType (op)) >= 2)
3446 /* if left or right or result is in far space */
3447 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3448 isOperandInFarSpace (IC_RIGHT (dic)) ||
3449 isOperandInFarSpace (IC_RESULT (dic)) ||
3450 IS_OP_RUONLY (IC_LEFT (dic)) ||
3451 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3452 IS_OP_RUONLY (IC_RESULT (dic)))
3458 OP_SYMBOL (op)->ruonly = 1;
3465 /*-----------------------------------------------------------------*/
3466 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3467 /*-----------------------------------------------------------------*/
3469 isBitwiseOptimizable (iCode * ic)
3471 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3472 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3474 debugLog ("%s\n", __FUNCTION__);
3475 /* bitwise operations are considered optimizable
3476 under the following conditions (Jean-Louis VERN)
3488 if (IS_LITERAL (rtype) ||
3489 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3496 #ifndef NO_packRegsForAccUse
3498 /*-----------------------------------------------------------------*/
3499 /* packRegsForAccUse - pack registers for acc use */
3500 /*-----------------------------------------------------------------*/
3502 packRegsForAccUse (iCode * ic)
3506 debugLog ("%s\n", __FUNCTION__);
3508 /* if this is an aggregate, e.g. a one byte char array */
3509 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3512 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3514 /* if + or - then it has to be one byte result */
3515 if ((ic->op == '+' || ic->op == '-')
3516 && getSize (operandType (IC_RESULT (ic))) > 1)
3519 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3520 /* if shift operation make sure right side is not a literal */
3521 if (ic->op == RIGHT_OP &&
3522 (isOperandLiteral (IC_RIGHT (ic)) ||
3523 getSize (operandType (IC_RESULT (ic))) > 1))
3526 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3527 if (ic->op == LEFT_OP &&
3528 (isOperandLiteral (IC_RIGHT (ic)) ||
3529 getSize (operandType (IC_RESULT (ic))) > 1))
3532 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3533 if (IS_BITWISE_OP (ic) &&
3534 getSize (operandType (IC_RESULT (ic))) > 1)
3538 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3539 /* has only one definition */
3540 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3543 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3544 /* has only one use */
3545 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3548 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3549 /* and the usage immediately follows this iCode */
3550 if (!(uic = hTabItemWithKey (iCodehTab,
3551 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3554 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3555 if (ic->next != uic)
3558 /* if it is a conditional branch then we definitely can */
3562 if (uic->op == JUMPTABLE)
3565 /* if the usage is not is an assignment
3566 or an arithmetic / bitwise / shift operation then not */
3567 if (POINTER_SET (uic) &&
3568 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3571 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3572 if (uic->op != '=' &&
3573 !IS_ARITHMETIC_OP (uic) &&
3574 !IS_BITWISE_OP (uic) &&
3575 uic->op != LEFT_OP &&
3576 uic->op != RIGHT_OP)
3579 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3580 /* if used in ^ operation then make sure right is not a
3582 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3585 /* if shift operation make sure right side is not a literal */
3586 if (uic->op == RIGHT_OP &&
3587 (isOperandLiteral (IC_RIGHT (uic)) ||
3588 getSize (operandType (IC_RESULT (uic))) > 1))
3591 if (uic->op == LEFT_OP &&
3592 (isOperandLiteral (IC_RIGHT (uic)) ||
3593 getSize (operandType (IC_RESULT (uic))) > 1))
3596 /* make sure that the result of this icode is not on the
3597 stack, since acc is used to compute stack offset */
3598 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3599 OP_SYMBOL (IC_RESULT (uic))->onStack)
3602 /* if either one of them in far space then we cannot */
3603 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3604 isOperandInFarSpace (IC_LEFT (uic))) ||
3605 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3606 isOperandInFarSpace (IC_RIGHT (uic))))
3609 /* if the usage has only one operand then we can */
3610 if (IC_LEFT (uic) == NULL ||
3611 IC_RIGHT (uic) == NULL)
3614 /* make sure this is on the left side if not
3615 a '+' since '+' is commutative */
3616 if (ic->op != '+' &&
3617 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3621 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3622 /* if one of them is a literal then we can */
3623 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3624 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3625 (getSize (operandType (IC_RESULT (uic))) <= 1))
3627 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3632 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3633 /* if the other one is not on stack then we can */
3634 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3635 (IS_ITEMP (IC_RIGHT (uic)) ||
3636 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3637 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3640 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3641 (IS_ITEMP (IC_LEFT (uic)) ||
3642 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3643 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3649 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3650 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3657 /*-----------------------------------------------------------------*/
3658 /* packForPush - hueristics to reduce iCode for pushing */
3659 /*-----------------------------------------------------------------*/
3661 packForReceive (iCode * ic, eBBlock * ebp)
3665 debugLog ("%s\n", __FUNCTION__);
3666 debugAopGet (" result:", IC_RESULT (ic));
3667 debugAopGet (" left:", IC_LEFT (ic));
3668 debugAopGet (" right:", IC_RIGHT (ic));
3673 for (dic = ic->next; dic; dic = dic->next)
3675 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3676 debugLog (" used on left\n");
3677 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3678 debugLog (" used on right\n");
3679 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3680 debugLog (" used on result\n");
3682 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3683 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3687 debugLog (" hey we can remove this unnecessary assign\n");
3689 /*-----------------------------------------------------------------*/
3690 /* packForPush - hueristics to reduce iCode for pushing */
3691 /*-----------------------------------------------------------------*/
3693 packForPush (iCode * ic, eBBlock * ebp)
3697 debugLog ("%s\n", __FUNCTION__);
3698 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3705 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3706 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3707 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3708 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3712 /* must have only definition & one usage */
3713 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3714 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3717 /* find the definition */
3718 if (!(dic = hTabItemWithKey (iCodehTab,
3719 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3722 /* if definition is not assignment,
3723 * or is not pointer (because pointer might have changed) */
3724 if (dic->op != '=' || POINTER_SET (dic))
3727 /* we must ensure that we can use the delete the assignment,
3728 * because the source might have been modified in between.
3729 * Until I know how to fix this, I'll use the adhoc fix
3730 * to check the liveranges */
3731 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3733 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3737 /* we now we know that it has one & only one def & use
3738 and the that the definition is an assignment */
3739 IC_LEFT (ic) = IC_RIGHT (dic);
3741 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3743 remiCodeFromeBBlock (ebp, dic);
3744 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3745 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3748 static void printSymType(char * str, sym_link *sl)
3750 if(!pic16_ralloc_debug)return;
3752 debugLog (" %s Symbol type: ",str);
3753 printTypeChain( sl, debugF);
3757 /*-----------------------------------------------------------------*/
3758 /* some debug code to print the symbol S_TYPE. Note that
3759 * the function checkSClass in src/SDCCsymt.c dinks with
3760 * the S_TYPE in ways the PIC port doesn't fully like...*/
3761 /*-----------------------------------------------------------------*/
3762 static void isData(sym_link *sl)
3766 if(!pic16_ralloc_debug)return;
3773 for ( ; sl; sl=sl->next) {
3775 switch (SPEC_SCLS(sl)) {
3776 case S_DATA: fprintf (of, "data "); break;
3777 case S_XDATA: fprintf (of, "xdata "); break;
3778 case S_SFR: fprintf (of, "sfr "); break;
3779 case S_SBIT: fprintf (of, "sbit "); break;
3780 case S_CODE: fprintf (of, "code "); break;
3781 case S_IDATA: fprintf (of, "idata "); break;
3782 case S_PDATA: fprintf (of, "pdata "); break;
3783 case S_LITERAL: fprintf (of, "literal "); break;
3784 case S_STACK: fprintf (of, "stack "); break;
3785 case S_XSTACK: fprintf (of, "xstack "); break;
3786 case S_BIT: fprintf (of, "bit "); break;
3787 case S_EEPROM: fprintf (of, "eeprom "); break;
3795 /*--------------------------------------------------------------------*/
3796 /* pic16_packRegisters - does some transformations to reduce */
3797 /* register pressure */
3799 /*--------------------------------------------------------------------*/
3801 pic16_packRegisters (eBBlock * ebp)
3806 debugLog ("%s\n", __FUNCTION__);
3812 /* look for assignments of the form */
3813 /* iTempNN = TRueSym (someoperation) SomeOperand */
3815 /* TrueSym := iTempNN:1 */
3816 for (ic = ebp->sch; ic; ic = ic->next)
3818 // debugLog("%d\n", __LINE__);
3819 /* find assignment of the form TrueSym := iTempNN:1 */
3820 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3821 change += packRegsForAssign (ic, ebp);
3825 if (POINTER_SET (ic))
3826 debugLog ("pointer is set\n");
3827 debugAopGet (" result:", IC_RESULT (ic));
3828 debugAopGet (" left:", IC_LEFT (ic));
3829 debugAopGet (" right:", IC_RIGHT (ic));
3838 for (ic = ebp->sch; ic; ic = ic->next) {
3840 if(IS_SYMOP ( IC_LEFT(ic))) {
3841 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3843 debugAopGet ("x left:", IC_LEFT (ic));
3845 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3847 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3849 debugLog (" is a pointer\n");
3851 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3852 debugLog (" is a ptr\n");
3854 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3855 debugLog (" is volatile\n");
3859 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3860 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3861 pic16_allocDirReg(IC_LEFT (ic));
3864 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3867 if(IS_SYMOP ( IC_RIGHT(ic))) {
3868 debugAopGet (" right:", IC_RIGHT (ic));
3869 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3872 if(IS_SYMOP ( IC_RESULT(ic))) {
3873 debugAopGet (" result:", IC_RESULT (ic));
3874 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3877 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3878 debugAopGet (" right:", IC_RIGHT (ic));
3879 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3880 // pic16_allocDirReg(IC_RIGHT(ic));
3883 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3884 debugAopGet (" result:", IC_RESULT (ic));
3885 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3886 // pic16_allocDirReg(IC_RESULT(ic));
3890 if (POINTER_SET (ic))
3891 debugLog (" %d - Pointer set\n", __LINE__);
3893 /* Look for two subsequent iCodes with */
3895 /* _c = iTemp & op; */
3896 /* and replace them by */
3899 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3901 && ic->prev->op == '='
3902 && IS_ITEMP (IC_LEFT (ic))
3903 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3904 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3906 iCode* ic_prev = ic->prev;
3907 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3909 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3910 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
3911 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3912 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3913 prev_result_sym->liveTo == ic->seq)
3915 prev_result_sym->liveTo = ic_prev->seq;
3918 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3920 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3922 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
3923 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3924 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3925 remiCodeFromeBBlock (ebp, ic_prev);
3926 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3930 /* if this is an itemp & result of a address of a true sym
3931 then mark this as rematerialisable */
3932 if (ic->op == ADDRESS_OF &&
3933 IS_ITEMP (IC_RESULT (ic)) &&
3934 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3935 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3936 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3939 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3941 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3942 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3943 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3947 /* if straight assignment then carry remat flag if
3948 this is the only definition */
3949 if (ic->op == '=' &&
3950 !POINTER_SET (ic) &&
3951 IS_SYMOP (IC_RIGHT (ic)) &&
3952 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3953 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3955 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3957 OP_SYMBOL (IC_RESULT (ic))->remat =
3958 OP_SYMBOL (IC_RIGHT (ic))->remat;
3959 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3960 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3963 /* if this is a +/- operation with a rematerizable
3964 then mark this as rematerializable as well */
3965 if ((ic->op == '+' || ic->op == '-') &&
3966 (IS_SYMOP (IC_LEFT (ic)) &&
3967 IS_ITEMP (IC_RESULT (ic)) &&
3968 OP_SYMBOL (IC_LEFT (ic))->remat &&
3969 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3970 IS_OP_LITERAL (IC_RIGHT (ic))))
3972 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3974 operandLitValue (IC_RIGHT (ic));
3975 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3976 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3977 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3980 /* mark the pointer usages */
3981 if (POINTER_SET (ic))
3983 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3984 debugLog (" marking as a pointer (set) =>");
3985 debugAopGet (" result:", IC_RESULT (ic));
3987 if (POINTER_GET (ic))
3989 if(IS_SYMOP(IC_LEFT(ic))) {
3990 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3991 debugLog (" marking as a pointer (get) =>");
3992 debugAopGet (" left:", IC_LEFT (ic));
3995 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
3996 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
3997 iCode *dic = ic->prev;
3999 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4001 if(dic && dic->op == '='
4002 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4004 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4007 /* replace prev->left with ic->left */
4008 IC_LEFT(ic) = IC_RIGHT(dic);
4009 IC_RIGHT(ic->prev) = NULL;
4011 /* remove ic->prev iCode (assignment) */
4012 remiCodeFromeBBlock (ebp, dic);
4013 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4016 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4022 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4026 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4027 /* if we are using a symbol on the stack
4028 then we should say pic16_ptrRegReq */
4029 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4030 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4031 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4032 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4033 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4034 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4038 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4039 if (IS_SYMOP (IC_LEFT (ic)))
4040 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4041 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4042 if (IS_SYMOP (IC_RIGHT (ic)))
4043 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4044 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4045 if (IS_SYMOP (IC_RESULT (ic)))
4046 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4047 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4050 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4054 /* if the condition of an if instruction
4055 is defined in the previous instruction then
4056 mark the itemp as a conditional */
4057 if ((IS_CONDITIONAL (ic) ||
4058 ((ic->op == BITWISEAND ||
4061 isBitwiseOptimizable (ic))) &&
4062 ic->next && ic->next->op == IFX &&
4063 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4064 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4067 debugLog (" %d\n", __LINE__);
4068 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4072 debugLog(" %d\n", __LINE__);
4074 #ifndef NO_packRegsForSupport
4075 /* reduce for support function calls */
4076 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4077 packRegsForSupport (ic, ebp);
4080 /* if a parameter is passed, it's in W, so we may not
4081 need to place a copy in a register */
4082 if (ic->op == RECEIVE)
4083 packForReceive (ic, ebp);
4085 #ifndef NO_packRegsForOneuse
4086 /* some cases the redundant moves can
4087 can be eliminated for return statements */
4088 if ((ic->op == RETURN || ic->op == SEND) &&
4089 !isOperandInFarSpace (IC_LEFT (ic)) &&
4091 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4094 #ifndef NO_packRegsForOneuse
4095 /* if pointer set & left has a size more than
4096 one and right is not in far space */
4097 if (POINTER_SET (ic) &&
4098 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4099 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4100 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4101 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4103 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4106 #ifndef NO_packRegsForOneuse
4107 /* if pointer get */
4108 if (POINTER_GET (ic) &&
4109 !isOperandInFarSpace (IC_RESULT (ic)) &&
4110 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4111 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4112 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4114 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4115 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4118 #ifndef NO_cast_peep
4119 /* if this is cast for intergral promotion then
4120 check if only use of the definition of the
4121 operand being casted/ if yes then replace
4122 the result of that arithmetic operation with
4123 this result and get rid of the cast */
4124 if (ic->op == CAST) {
4126 sym_link *fromType = operandType (IC_RIGHT (ic));
4127 sym_link *toType = operandType (IC_LEFT (ic));
4129 debugLog (" %d - casting\n", __LINE__);
4131 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4132 getSize (fromType) != getSize (toType)) {
4135 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4138 if (IS_ARITHMETIC_OP (dic)) {
4139 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4141 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4142 IC_RESULT (dic) = IC_RESULT (ic);
4143 remiCodeFromeBBlock (ebp, ic);
4144 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4145 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4146 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4150 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4154 /* if the type from and type to are the same
4155 then if this is the only use then packit */
4156 if (compareType (operandType (IC_RIGHT (ic)),
4157 operandType (IC_LEFT (ic))) == 1) {
4159 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4162 debugLog(" %d\n", __LINE__);
4164 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4165 IC_RESULT (dic) = IC_RESULT (ic);
4166 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4167 remiCodeFromeBBlock (ebp, ic);
4168 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4169 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4178 /* there are some problems with packing variables
4179 * it seems that the live range estimator doesn't
4180 * estimate correctly the liveranges of some symbols */
4183 iTempNN := (some variable in farspace) V1
4188 if (ic->op == IPUSH)
4190 packForPush (ic, ebp);
4194 #ifndef NO_packRegsForAccUse
4195 /* pack registers for accumulator use, when the
4196 result of an arithmetic or bit wise operation
4197 has only one use, that use is immediately following
4198 the defintion and the using iCode has only one
4199 operand or has two operands but one is literal &
4200 the result of that operation is not on stack then
4201 we can leave the result of this operation in acc:b
4203 if ((IS_ARITHMETIC_OP (ic)
4205 || IS_BITWISE_OP (ic)
4207 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4210 IS_ITEMP (IC_RESULT (ic)) &&
4211 getSize (operandType (IC_RESULT (ic))) <= 1)
4213 packRegsForAccUse (ic);
4220 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4224 if (!pic16_ralloc_debug || !debugF)
4227 for (i = 0; i < count; i++)
4229 fprintf (debugF, "\n----------------------------------------------------------------\n");
4230 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4231 ebbs[i]->entryLabel->name,
4234 ebbs[i]->isLastInLoop);
4235 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4240 fprintf (debugF, "visited %d : hasFcall = %d\n",
4244 fprintf (debugF, "\ndefines bitVector :");
4245 bitVectDebugOn (ebbs[i]->defSet, debugF);
4246 fprintf (debugF, "\nlocal defines bitVector :");
4247 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4248 fprintf (debugF, "\npointers Set bitvector :");
4249 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4250 fprintf (debugF, "\nin pointers Set bitvector :");
4251 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4252 fprintf (debugF, "\ninDefs Set bitvector :");
4253 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4254 fprintf (debugF, "\noutDefs Set bitvector :");
4255 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4256 fprintf (debugF, "\nusesDefs Set bitvector :");
4257 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4258 fprintf (debugF, "\n----------------------------------------------------------------\n");
4259 printiCChain (ebbs[i]->sch, debugF);
4262 /*-----------------------------------------------------------------*/
4263 /* pic16_assignRegisters - assigns registers to each live range as need */
4264 /*-----------------------------------------------------------------*/
4266 pic16_assignRegisters (ebbIndex * ebbi)
4268 eBBlock ** ebbs = ebbi->bbOrder;
4269 int count = ebbi->count;
4273 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4274 debugLog ("\nebbs before optimizing:\n");
4275 dumpEbbsToDebug (ebbs, count);
4277 _inRegAllocator = 1;
4279 setToNull ((void *) &_G.funcrUsed);
4280 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4283 /* change assignments this will remove some
4284 live ranges reducing some register pressure */
4285 for (i = 0; i < count; i++)
4286 pic16_packRegisters (ebbs[i]);
4293 debugLog("dir registers allocated so far:\n");
4294 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4297 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4298 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4299 reg = hTabNextItem(dynDirectRegNames, &hkey);
4304 /* liveranges probably changed by register packing
4305 so we compute them again */
4306 recomputeLiveRanges (ebbs, count);
4308 if (options.dump_pack)
4309 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4311 /* first determine for each live range the number of
4312 registers & the type of registers required for each */
4315 /* start counting function temporary registers from zero */
4318 /* and serially allocate registers */
4319 serialRegAssign (ebbs, count);
4322 debugLog ("ebbs after serialRegAssign:\n");
4323 dumpEbbsToDebug (ebbs, count);
4326 //pic16_freeAllRegs();
4328 /* if stack was extended then tell the user */
4331 /* werror(W_TOOMANY_SPILS,"stack", */
4332 /* _G.stackExtend,currFunc->name,""); */
4338 /* werror(W_TOOMANY_SPILS,"data space", */
4339 /* _G.dataExtend,currFunc->name,""); */
4343 /* after that create the register mask
4344 for each of the instruction */
4345 createRegMask (ebbs, count);
4347 /* redo that offsets for stacked automatic variables */
4348 redoStackOffsets ();
4350 if (options.dump_rassgn)
4351 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4353 /* now get back the chain */
4354 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4356 debugLog ("ebbs after optimizing:\n");
4357 dumpEbbsToDebug (ebbs, count);
4359 _inRegAllocator = 0;
4363 /* free up any _G.stackSpil locations allocated */
4364 applyToSet (_G.stackSpil, deallocStackSpil);
4366 setToNull ((void *) &_G.stackSpil);
4367 setToNull ((void *) &_G.spiltSet);
4368 /* mark all registers as free */
4369 pic16_freeAllRegs ();
4372 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");