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 -------------------------------------------------------------------------*/
35 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
37 void _debugf(char *f, int l, char *frm, ...);
39 #define NEWREG_DEBUG 0
43 /*-----------------------------------------------------------------*/
44 /* At this point we start getting processor specific although */
45 /* some routines are non-processor specific & can be reused when */
46 /* targetting other processors. The decision for this will have */
47 /* to be made on a routine by routine basis */
48 /* routines used to pack registers are most definitely not reusable */
49 /* since the pack the registers depending strictly on the MCU */
50 /*-----------------------------------------------------------------*/
52 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
53 extern void genpic16Code (iCode *);
63 bitVect *funcrUsed; /* registers used in a function */
69 /* Shared with gen.c */
70 int pic16_ptrRegReq; /* one byte pointer register required */
73 set *pic16_dynAllocRegs=NULL;
74 set *pic16_dynStackRegs=NULL;
75 set *pic16_dynProcessorRegs=NULL;
76 set *pic16_dynDirectRegs=NULL;
77 set *pic16_dynDirectBitRegs=NULL;
78 set *pic16_dynInternalRegs=NULL;
79 set *pic16_dynAccessRegs=NULL;
81 static hTab *dynDirectRegNames=NULL;
82 static hTab *dynAllocRegNames=NULL;
83 static hTab *dynProcRegNames=NULL;
84 static hTab *dynAccessRegNames=NULL;
85 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
87 extern set *sectNames;
89 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
90 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
91 set *pic16_equ_data=NULL; /* registers used by equates */
92 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
93 set *pic16_acs_udata=NULL; /* access bank variables */
95 set *pic16_builtin_functions=NULL;
97 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
98 static int rDirectIdx=0;
100 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
102 int pic16_Gstack_base_addr=0; /* The starting address of registers that
103 * are used to pass and return parameters */
106 int _inRegAllocator=0; /* flag that marks whther allocReg happens while
107 * inside the register allocator function */
110 static void spillThis (symbol *);
111 int pic16_ralloc_debug = 0;
112 static FILE *debugF = NULL;
113 /*-----------------------------------------------------------------*/
114 /* debugLog - open a file for debugging information */
115 /*-----------------------------------------------------------------*/
116 //static void debugLog(char *inst,char *fmt, ...)
118 debugLog (char *fmt,...)
120 static int append = 0; // First time through, open the file without append.
123 //char *bufferP=buffer;
126 if (!pic16_ralloc_debug || !dstFileName)
132 /* create the file name */
133 strcpy (buffer, dstFileName);
134 strcat (buffer, ".d");
136 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
138 werror (E_FILE_OPEN_ERR, buffer);
141 append = 1; // Next time debubLog is called, we'll append the debug info
147 vsprintf (buffer, fmt, ap);
149 fprintf (debugF, "%s", buffer);
150 //fprintf (stderr, "%s", buffer);
152 while (isspace((unsigned char)*bufferP)) bufferP++;
154 if (bufferP && *bufferP)
155 lineCurr = (lineCurr ?
156 connectLine(lineCurr,newLineNode(lb)) :
157 (lineHead = newLineNode(lb)));
158 lineCurr->isInline = _G.inLine;
159 lineCurr->isDebug = _G.debugLine;
168 if(!pic16_ralloc_debug)return;
171 fputc ('\n', debugF);
173 /*-----------------------------------------------------------------*/
174 /* debugLogClose - closes the debug log file (if opened) */
175 /*-----------------------------------------------------------------*/
185 #define AOP(op) op->aop
188 debugAopGet (char *str, operand * op)
190 if(!pic16_ralloc_debug)return NULL;
195 printOperand (op, debugF);
202 pic16_decodeOp (unsigned int op)
204 if (op < 128 && op > ' ') {
205 buffer[0] = (op & 0xff);
211 case IDENTIFIER: return "IDENTIFIER";
212 case TYPE_NAME: return "TYPE_NAME";
213 case CONSTANT: return "CONSTANT";
214 case STRING_LITERAL: return "STRING_LITERAL";
215 case SIZEOF: return "SIZEOF";
216 case PTR_OP: return "PTR_OP";
217 case INC_OP: return "INC_OP";
218 case DEC_OP: return "DEC_OP";
219 case LEFT_OP: return "LEFT_OP";
220 case RIGHT_OP: return "RIGHT_OP";
221 case LE_OP: return "LE_OP";
222 case GE_OP: return "GE_OP";
223 case EQ_OP: return "EQ_OP";
224 case NE_OP: return "NE_OP";
225 case AND_OP: return "AND_OP";
226 case OR_OP: return "OR_OP";
227 case MUL_ASSIGN: return "MUL_ASSIGN";
228 case DIV_ASSIGN: return "DIV_ASSIGN";
229 case MOD_ASSIGN: return "MOD_ASSIGN";
230 case ADD_ASSIGN: return "ADD_ASSIGN";
231 case SUB_ASSIGN: return "SUB_ASSIGN";
232 case LEFT_ASSIGN: return "LEFT_ASSIGN";
233 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
234 case AND_ASSIGN: return "AND_ASSIGN";
235 case XOR_ASSIGN: return "XOR_ASSIGN";
236 case OR_ASSIGN: return "OR_ASSIGN";
237 case TYPEDEF: return "TYPEDEF";
238 case EXTERN: return "EXTERN";
239 case STATIC: return "STATIC";
240 case AUTO: return "AUTO";
241 case REGISTER: return "REGISTER";
242 case CODE: return "CODE";
243 case EEPROM: return "EEPROM";
244 case INTERRUPT: return "INTERRUPT";
245 case SFR: return "SFR";
246 case AT: return "AT";
247 case SBIT: return "SBIT";
248 case REENTRANT: return "REENTRANT";
249 case USING: return "USING";
250 case XDATA: return "XDATA";
251 case DATA: return "DATA";
252 case IDATA: return "IDATA";
253 case PDATA: return "PDATA";
254 case VAR_ARGS: return "VAR_ARGS";
255 case CRITICAL: return "CRITICAL";
256 case NONBANKED: return "NONBANKED";
257 case BANKED: return "BANKED";
258 case CHAR: return "CHAR";
259 case SHORT: return "SHORT";
260 case INT: return "INT";
261 case LONG: return "LONG";
262 case SIGNED: return "SIGNED";
263 case UNSIGNED: return "UNSIGNED";
264 case FLOAT: return "FLOAT";
265 case DOUBLE: return "DOUBLE";
266 case CONST: return "CONST";
267 case VOLATILE: return "VOLATILE";
268 case VOID: return "VOID";
269 case BIT: return "BIT";
270 case STRUCT: return "STRUCT";
271 case UNION: return "UNION";
272 case ENUM: return "ENUM";
273 case RANGE: return "RANGE";
274 case FAR: return "FAR";
275 case CASE: return "CASE";
276 case DEFAULT: return "DEFAULT";
277 case IF: return "IF";
278 case ELSE: return "ELSE";
279 case SWITCH: return "SWITCH";
280 case WHILE: return "WHILE";
281 case DO: return "DO";
282 case FOR: return "FOR";
283 case GOTO: return "GOTO";
284 case CONTINUE: return "CONTINUE";
285 case BREAK: return "BREAK";
286 case RETURN: return "RETURN";
287 case INLINEASM: return "INLINEASM";
288 case IFX: return "IFX";
289 case ADDRESS_OF: return "ADDRESS_OF";
290 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
291 case SPIL: return "SPIL";
292 case UNSPIL: return "UNSPIL";
293 case GETHBIT: return "GETHBIT";
294 case BITWISEAND: return "BITWISEAND";
295 case UNARYMINUS: return "UNARYMINUS";
296 case IPUSH: return "IPUSH";
297 case IPOP: return "IPOP";
298 case PCALL: return "PCALL";
299 case FUNCTION: return "FUNCTION";
300 case ENDFUNCTION: return "ENDFUNCTION";
301 case JUMPTABLE: return "JUMPTABLE";
302 case RRC: return "RRC";
303 case RLC: return "RLC";
304 case CAST: return "CAST";
305 case CALL: return "CALL";
306 case PARAM: return "PARAM ";
307 case NULLOP: return "NULLOP";
308 case BLOCK: return "BLOCK";
309 case LABEL: return "LABEL";
310 case RECEIVE: return "RECEIVE";
311 case SEND: return "SEND";
312 case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
314 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
320 static char *decodeRegType(short type)
323 case REG_GPR: return "REG_GPR";
324 case REG_PTR: return "REG_PTR";
325 case REG_CND: return "REG_CNT";
333 /*-----------------------------------------------------------------*/
334 /*-----------------------------------------------------------------*/
336 debugLogRegType (short type)
338 if(!pic16_ralloc_debug)return NULL;
340 case REG_GPR: return "REG_GPR";
341 case REG_PTR: return "REG_PTR";
342 case REG_CND: return "REG_CND";
344 sprintf (buffer, "unknown reg type %d", type);
349 /*-----------------------------------------------------------------*/
350 /*-----------------------------------------------------------------*/
351 static int regname2key(char const *name)
360 key += (*name++) + 1;
364 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
368 /*-----------------------------------------------------------------*/
369 /* newReg - allocate and init memory for a new register */
370 /*-----------------------------------------------------------------*/
371 regs* newReg(int type, short pc_type, int rIdx, char *name, unsigned size, int alias, operand *refop)
376 dReg = Safe_calloc(1,sizeof(regs));
378 dReg->pc_type = pc_type;
381 dReg->name = Safe_strdup(name);
383 if(xinst && pc_type == PO_GPR_TEMP) {
384 sprintf(buffer,"0x%02x", dReg->rIdx);
386 sprintf(buffer,"r0x%02x", dReg->rIdx);
389 if(type == REG_STK) {
392 dReg->name = Safe_strdup(buffer);
400 if(type == REG_SFR) {
402 dReg->address = rIdx;
403 dReg->accessBank = 1;
407 dReg->accessBank = 0;
411 fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
415 dReg->reg_alias = NULL;
416 dReg->reglives.usedpFlows = newSet();
417 dReg->reglives.assignedpFlows = newSet();
420 if(!(type == REG_SFR && alias == 0x80))
421 hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
426 /*-----------------------------------------------------------------*/
427 /* regWithIdx - Search through a set of registers that matches idx */
428 /*-----------------------------------------------------------------*/
430 regWithIdx (set *dRegs, int idx, unsigned fixed)
434 //#define D(text) text
437 for (dReg = setFirstItem(dRegs) ; dReg ;
438 dReg = setNextItem(dRegs)) {
440 D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
441 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
442 D(fprintf(stderr, "found!\n"));
445 D(fprintf(stderr, "not found!\n"));
451 /*-----------------------------------------------------------------*/
452 /* regFindFree - Search for a free register in a set of registers */
453 /*-----------------------------------------------------------------*/
455 regFindFree (set *dRegs)
459 for (dReg = setFirstItem(dRegs) ; dReg ;
460 dReg = setNextItem(dRegs)) {
462 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
463 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
466 // fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
476 regFindFreeNext(set *dRegs, regs *creg)
481 /* position at current register */
482 for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
485 for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
494 /*-----------------------------------------------------------------*/
495 /* pic16_initStack - allocate registers for a pseudo stack */
496 /*-----------------------------------------------------------------*/
497 void pic16_initStack(int base_address, int size)
502 pic16_Gstack_base_addr = base_address;
503 //fprintf(stderr,"initStack");
505 for(i = 0; i<size; i++)
506 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
509 /*-----------------------------------------------------------------*
510 *-----------------------------------------------------------------*/
512 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
514 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
516 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
518 reg->wasUsed = 0; // we do not know if they are going to be used at all
519 reg->accessBank = 1; // implicit add access Bank
521 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
523 return addSet(&pic16_dynProcessorRegs, reg);
526 /*-----------------------------------------------------------------*
527 *-----------------------------------------------------------------*/
530 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
532 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
534 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
538 return addSet(&pic16_dynInternalRegs,reg);
545 /*-----------------------------------------------------------------*/
546 /* allocReg - allocates register of given type */
547 /*-----------------------------------------------------------------*/
549 allocReg (short type)
553 #define MAX_P16_NREGS 16
557 if(dynrIdx > pic16_nRegs)
558 werror(W_POSSBUG2, __FILE__, __LINE__);
562 /* try to reuse some unused registers */
563 reg = regFindFree( pic16_dynAllocRegs );
566 // fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
570 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
571 // fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
572 // (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
575 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
576 // debugf("allocating more registers than available\n", 0);
580 addSet(&pic16_dynAllocRegs, reg);
581 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
582 // fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
586 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
589 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
590 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
594 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
595 reg->isLocal = 1; /* this is a local frame register */
600 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
601 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
604 return (reg); // addSet(&pic16_dynAllocRegs,reg);
609 /*-----------------------------------------------------------------*/
610 /* pic16_dirregWithName - search for register by name */
611 /*-----------------------------------------------------------------*/
613 pic16_dirregWithName (char *name)
621 /* hash the name to get a key */
623 hkey = regname2key(name);
625 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
627 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
631 if(STRCASECMP(reg->name, name) == 0) {
632 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
636 reg = hTabNextItemWK (dynDirectRegNames);
640 return NULL; // name wasn't found in the hash table
643 /*-----------------------------------------------------------------*/
644 /* pic16_allocregWithName - search for register by name */
645 /*-----------------------------------------------------------------*/
647 pic16_allocregWithName (char *name)
655 /* hash the name to get a key */
657 hkey = regname2key(name);
659 //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
661 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
665 if(STRCASECMP(reg->name, name) == 0) {
669 reg = hTabNextItemWK (dynAllocRegNames);
673 return NULL; // name wasn't found in the hash table
678 /*-----------------------------------------------------------------*/
679 /* pic16_procregWithName - search for register by name */
680 /*-----------------------------------------------------------------*/
682 pic16_procregWithName (char *name)
690 /* hash the name to get a key */
692 hkey = regname2key(name);
694 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
696 reg = hTabFirstItemWK(dynProcRegNames, hkey);
700 if(STRCASECMP(reg->name, name) == 0) {
704 reg = hTabNextItemWK (dynProcRegNames);
708 return NULL; // name wasn't found in the hash table
712 /*-----------------------------------------------------------------*/
713 /* pic16_accessregWithName - search for register by name */
714 /*-----------------------------------------------------------------*/
716 pic16_accessregWithName (char *name)
724 /* hash the name to get a key */
726 hkey = regname2key(name);
728 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
730 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
734 if(STRCASECMP(reg->name, name) == 0) {
738 reg = hTabNextItemWK (dynAccessRegNames);
742 return NULL; // name wasn't found in the hash table
746 regs *pic16_regWithName(char *name)
750 reg = pic16_dirregWithName( name );
753 reg = pic16_procregWithName( name );
756 reg = pic16_allocregWithName( name );
759 reg = pic16_accessregWithName( name );
766 /*-----------------------------------------------------------------*/
767 /* pic16_allocDirReg - allocates register of given type */
768 /*-----------------------------------------------------------------*/
770 pic16_allocDirReg (operand *op )
776 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
777 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
781 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
784 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
786 if(pic16_debug_verbose)
788 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
789 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
795 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
796 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
799 if(pic16_debug_verbose) {
800 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
801 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
802 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
803 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
804 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
805 IN_STACK( OP_SYM_ETYPE(op)),
806 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
807 IS_REGPARM(OP_SYM_ETYPE(op)),
810 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
811 OP_SYMBOL(op)->name);
819 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
820 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
824 if(IS_ITEMP(op))return NULL;
826 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
828 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
830 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
831 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
834 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
835 debugLog(" %d const char\n",__LINE__);
836 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
837 // fprintf(stderr, " %d const char\n",__LINE__);
838 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
842 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
843 if (IS_CODE ( OP_SYM_ETYPE(op)) )
844 debugLog(" %d code space\n",__LINE__);
846 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
847 debugLog(" %d integral\n",__LINE__);
849 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
850 debugLog(" %d literal\n",__LINE__);
852 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
853 debugLog(" %d specifier\n",__LINE__);
855 debugAopGet(NULL, op);
859 reg = pic16_dirregWithName(name);
863 int regtype = REG_GPR;
865 /* if this is at an absolute address, then get the address. */
866 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
867 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
868 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
871 /* Register wasn't found in hash, so let's create
872 * a new one and put it in the hash table AND in the
873 * dynDirectRegNames set */
874 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
875 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
881 if(OP_SYMBOL(op)->onStack) {
882 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
883 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
887 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
888 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
891 if(pic16_debug_verbose)
893 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
894 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
895 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
896 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
897 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
898 IN_STACK( OP_SYM_ETYPE(op)),
899 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
901 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
902 OP_SYMBOL(op)->name);
907 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
908 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
910 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
911 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
915 checkAddReg(&pic16_dynAccessRegs, reg);
916 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
922 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
923 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
924 // reg->type = REG_SFR;
927 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
928 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
929 addSet(&pic16_dynDirectBitRegs, reg);
932 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
933 // addSet(&pic16_dynDirectRegs, reg);
936 if(!(IS_STATIC(OP_SYM_ETYPE(op))
937 && OP_SYMBOL(op)->ival
940 checkAddReg(&pic16_dynDirectRegs, reg);
944 // debugLog (" -- %s is declared at address 0x30000x\n",name);
945 return (reg); /* This was NULL before, but since we found it
946 * why not just return it?! */
949 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
951 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
953 /* work around for user defined registers in access bank */
954 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
955 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
958 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
964 /*-----------------------------------------------------------------*/
965 /* pic16_allocRegByName - allocates register of given type */
966 /*-----------------------------------------------------------------*/
968 pic16_allocRegByName (char *name, int size, operand *op)
974 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
978 /* First, search the hash table to see if there is a register with this name */
979 reg = pic16_dirregWithName(name);
983 /* Register wasn't found in hash, so let's create
984 * a new one and put it in the hash table AND in the
985 * dynDirectRegNames set */
987 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
989 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
991 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
992 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
994 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
995 addSet(&pic16_dynDirectRegs, reg);
1001 /*-----------------------------------------------------------------*/
1002 /* RegWithIdx - returns pointer to register with index number */
1003 /*-----------------------------------------------------------------*/
1004 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
1009 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
1010 // fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
1015 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
1017 debugLog ("Found a Dynamic Register!\n");
1020 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
1021 debugLog ("Found a Direct Register!\n");
1025 if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
1026 debugLog ("Found an Internal Register!\n");
1032 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1033 debugLog ("Found a Stack Register!\n");
1038 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1039 debugLog ("Found a Processor Register!\n");
1053 /*-----------------------------------------------------------------*/
1054 /* pic16_regWithIdx - returns pointer to register with index number*/
1055 /*-----------------------------------------------------------------*/
1057 pic16_regWithIdx (int idx)
1061 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1064 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1068 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1075 /*-----------------------------------------------------------------*/
1076 /* pic16_regWithIdx - returns pointer to register with index number */
1077 /*-----------------------------------------------------------------*/
1079 pic16_allocWithIdx (int idx)
1084 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1085 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1087 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1089 debugLog ("Found a Dynamic Register!\n");
1090 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1091 debugLog ("Found a Stack Register!\n");
1092 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1093 debugLog ("Found a Processor Register!\n");
1094 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1095 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1096 debugLog ("Found an Internal Register!\n");
1099 debugLog ("Dynamic Register not found\n");
1102 dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
1103 addSet(&pic16_dynAllocRegs, dReg);
1104 hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
1109 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1110 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1111 "allocWithIdx not found");
1121 /*-----------------------------------------------------------------*/
1122 /*-----------------------------------------------------------------*/
1124 pic16_findFreeReg(short type)
1131 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1133 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1134 return allocReg( REG_GPR );
1138 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1152 pic16_findFreeRegNext(short type, regs *creg)
1159 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1161 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1162 return (allocReg( REG_GPR ) );
1166 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1178 /*-----------------------------------------------------------------*/
1179 /* freeReg - frees a register */
1180 /*-----------------------------------------------------------------*/
1182 freeReg (regs * reg)
1184 debugLog ("%s\n", __FUNCTION__);
1185 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1190 /*-----------------------------------------------------------------*/
1191 /* nFreeRegs - returns number of free registers */
1192 /*-----------------------------------------------------------------*/
1194 nFreeRegs (int type)
1200 /* although I fixed the register allocation/freeing scheme
1201 * the for loop below doesn't give valid results. I do not
1202 * know why yet. -- VR 10-Jan-2003 */
1207 /* dynamically allocate as many as we need and worry about
1208 * fitting them into a PIC later */
1210 debugLog ("%s\n", __FUNCTION__);
1212 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1213 if((reg->type == type) && reg->isFree)nfr++;
1215 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1219 /*-----------------------------------------------------------------*/
1220 /* nfreeRegsType - free registers with type */
1221 /*-----------------------------------------------------------------*/
1223 nfreeRegsType (int type)
1226 debugLog ("%s\n", __FUNCTION__);
1227 if (type == REG_PTR)
1229 if ((nfr = nFreeRegs (type)) == 0)
1230 return nFreeRegs (REG_GPR);
1233 return nFreeRegs (type);
1236 static void writeSetUsedRegs(FILE *of, set *dRegs)
1241 for (dReg = setFirstItem(dRegs) ; dReg ;
1242 dReg = setNextItem(dRegs)) {
1245 fprintf (of, "\t%s\n",dReg->name);
1251 extern void pic16_groupRegistersInSection(set *regset);
1253 extern void pic16_dump_equates(FILE *of, set *equs);
1254 extern void pic16_dump_access(FILE *of, set *section);
1255 //extern void pic16_dump_map(void);
1256 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1257 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1258 extern void pic16_dump_int_registers(FILE *of, set *section);
1259 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1261 extern void pic16_dump_gsection(FILE *of, set *sections);
1263 static void packBits(set *bregs)
1267 regs *bitfield=NULL;
1268 regs *relocbitfield=NULL;
1274 for (regset = bregs ; regset ;
1275 regset = regset->next) {
1277 breg = regset->item;
1278 breg->isBitField = 1;
1279 //fprintf(stderr,"bit reg: %s\n",breg->name);
1282 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1284 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1285 breg->rIdx = breg->address & 7;
1286 breg->address >>= 3;
1289 sprintf (buffer, "fbitfield%02x", breg->address);
1290 //fprintf(stderr,"new bit field\n");
1291 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1292 bitfield->isBitField = 1;
1293 bitfield->isFixed = 1;
1294 bitfield->address = breg->address;
1295 addSet(&pic16_dynDirectRegs,bitfield);
1296 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1298 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1301 breg->reg_alias = bitfield;
1305 if(!relocbitfield || bit_no >7) {
1308 sprintf (buffer, "bitfield%d", byte_no);
1309 //fprintf(stderr,"new relocatable bit field\n");
1310 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1311 relocbitfield->isBitField = 1;
1312 addSet(&pic16_dynDirectRegs,relocbitfield);
1313 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1317 breg->reg_alias = relocbitfield;
1318 breg->address = rDirectIdx; /* byte_no; */
1319 breg->rIdx = bit_no++;
1325 void pic16_writeUsedRegs(FILE *of)
1327 packBits(pic16_dynDirectBitRegs);
1329 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1330 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1331 pic16_groupRegistersInSection(pic16_dynStackRegs);
1332 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1333 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1334 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1335 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1338 pic16_dump_equates(of, pic16_equ_data);
1340 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1341 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1343 /* dump access bank symbols */
1344 pic16_dump_access(of, pic16_acs_udata);
1346 /* dump initialised data */
1347 pic16_dump_isection(of, rel_idataSymSet, 0);
1348 pic16_dump_isection(of, fix_idataSymSet, 1);
1351 /* dump internal registers */
1352 pic16_dump_int_registers(of, pic16_int_regs);
1355 /* dump generic section variables */
1356 pic16_dump_gsection(of, sectNames);
1358 /* dump other variables */
1359 pic16_dump_usection(of, pic16_rel_udata, 0);
1360 pic16_dump_usection(of, pic16_fix_udata, 1);
1364 /*-----------------------------------------------------------------*/
1365 /* computeSpillable - given a point find the spillable live ranges */
1366 /*-----------------------------------------------------------------*/
1368 computeSpillable (iCode * ic)
1372 debugLog ("%s\n", __FUNCTION__);
1373 /* spillable live ranges are those that are live at this
1374 point . the following categories need to be subtracted
1376 a) - those that are already spilt
1377 b) - if being used by this one
1378 c) - defined by this one */
1380 spillable = bitVectCopy (ic->rlive);
1382 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1384 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1385 bitVectUnSetBit (spillable, ic->defKey);
1386 spillable = bitVectIntersect (spillable, _G.regAssigned);
1391 /*-----------------------------------------------------------------*/
1392 /* noSpilLoc - return true if a variable has no spil location */
1393 /*-----------------------------------------------------------------*/
1395 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1397 debugLog ("%s\n", __FUNCTION__);
1398 return (sym->usl.spillLoc ? 0 : 1);
1401 /*-----------------------------------------------------------------*/
1402 /* hasSpilLoc - will return 1 if the symbol has spil location */
1403 /*-----------------------------------------------------------------*/
1405 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1407 debugLog ("%s\n", __FUNCTION__);
1408 return (sym->usl.spillLoc ? 1 : 0);
1411 /*-----------------------------------------------------------------*/
1412 /* directSpilLoc - will return 1 if the splilocation is in direct */
1413 /*-----------------------------------------------------------------*/
1415 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1417 debugLog ("%s\n", __FUNCTION__);
1418 if (sym->usl.spillLoc &&
1419 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1425 /*-----------------------------------------------------------------*/
1426 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1427 /* but is not used as a pointer */
1428 /*-----------------------------------------------------------------*/
1430 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1432 debugLog ("%s\n", __FUNCTION__);
1433 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1436 /*-----------------------------------------------------------------*/
1437 /* rematable - will return 1 if the remat flag is set */
1438 /*-----------------------------------------------------------------*/
1440 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1442 debugLog ("%s\n", __FUNCTION__);
1446 /*-----------------------------------------------------------------*/
1447 /* notUsedInRemaining - not used or defined in remain of the block */
1448 /*-----------------------------------------------------------------*/
1450 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1452 debugLog ("%s\n", __FUNCTION__);
1453 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1454 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1457 /*-----------------------------------------------------------------*/
1458 /* allLRs - return true for all */
1459 /*-----------------------------------------------------------------*/
1461 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1463 debugLog ("%s\n", __FUNCTION__);
1467 /*-----------------------------------------------------------------*/
1468 /* liveRangesWith - applies function to a given set of live range */
1469 /*-----------------------------------------------------------------*/
1471 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1472 eBBlock * ebp, iCode * ic)
1477 debugLog ("%s\n", __FUNCTION__);
1478 if (!lrs || !lrs->size)
1481 for (i = 1; i < lrs->size; i++)
1484 if (!bitVectBitValue (lrs, i))
1487 /* if we don't find it in the live range
1488 hash table we are in serious trouble */
1489 if (!(sym = hTabItemWithKey (liveRanges, i)))
1491 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1492 "liveRangesWith could not find liveRange");
1496 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1497 addSetHead (&rset, sym);
1504 /*-----------------------------------------------------------------*/
1505 /* leastUsedLR - given a set determines which is the least used */
1506 /*-----------------------------------------------------------------*/
1508 leastUsedLR (set * sset)
1510 symbol *sym = NULL, *lsym = NULL;
1512 debugLog ("%s\n", __FUNCTION__);
1513 sym = lsym = setFirstItem (sset);
1518 for (; lsym; lsym = setNextItem (sset))
1521 /* if usage is the same then prefer
1522 the spill the smaller of the two */
1523 if (lsym->used == sym->used)
1524 if (getSize (lsym->type) < getSize (sym->type))
1528 if (lsym->used < sym->used)
1533 setToNull ((void *) &sset);
1538 /*-----------------------------------------------------------------*/
1539 /* noOverLap - will iterate through the list looking for over lap */
1540 /*-----------------------------------------------------------------*/
1542 noOverLap (set * itmpStack, symbol * fsym)
1545 debugLog ("%s\n", __FUNCTION__);
1548 for (sym = setFirstItem (itmpStack); sym;
1549 sym = setNextItem (itmpStack))
1551 if (sym->liveTo > fsym->liveFrom)
1559 /*-----------------------------------------------------------------*/
1560 /* isFree - will return 1 if the a free spil location is found */
1561 /*-----------------------------------------------------------------*/
1566 V_ARG (symbol **, sloc);
1567 V_ARG (symbol *, fsym);
1569 debugLog ("%s\n", __FUNCTION__);
1570 /* if already found */
1574 /* if it is free && and the itmp assigned to
1575 this does not have any overlapping live ranges
1576 with the one currently being assigned and
1577 the size can be accomodated */
1579 noOverLap (sym->usl.itmpStack, fsym) &&
1580 getSize (sym->type) >= getSize (fsym->type))
1589 /*-----------------------------------------------------------------*/
1590 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1591 /*-----------------------------------------------------------------*/
1593 spillLRWithPtrReg (symbol * forSym)
1599 debugLog ("%s\n", __FUNCTION__);
1600 if (!_G.regAssigned ||
1601 bitVectIsZero (_G.regAssigned))
1604 r0 = pic16_regWithIdx (R0_IDX);
1605 r1 = pic16_regWithIdx (R1_IDX);
1607 /* for all live ranges */
1608 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1609 lrsym = hTabNextItem (liveRanges, &k))
1613 /* if no registers assigned to it or
1615 /* if it does not overlap with this then
1616 not need to spill it */
1618 if (lrsym->isspilt || !lrsym->nRegs ||
1619 (lrsym->liveTo < forSym->liveFrom))
1622 /* go thru the registers : if it is either
1623 r0 or r1 then spil it */
1624 for (j = 0; j < lrsym->nRegs; j++)
1625 if (lrsym->regs[j] == r0 ||
1626 lrsym->regs[j] == r1)
1635 /*-----------------------------------------------------------------*/
1636 /* createStackSpil - create a location on the stack to spil */
1637 /*-----------------------------------------------------------------*/
1639 createStackSpil (symbol * sym)
1641 symbol *sloc = NULL;
1642 int useXstack, model, noOverlay;
1644 char slocBuffer[30];
1645 debugLog ("%s\n", __FUNCTION__);
1647 /* first go try and find a free one that is already
1648 existing on the stack */
1649 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1651 /* found a free one : just update & return */
1652 sym->usl.spillLoc = sloc;
1655 addSetHead (&sloc->usl.itmpStack, sym);
1659 /* could not then have to create one , this is the hard part
1660 we need to allocate this on the stack : this is really a
1661 hack!! but cannot think of anything better at this time */
1663 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1665 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1666 __FILE__, __LINE__);
1670 sloc = newiTemp (slocBuffer);
1672 /* set the type to the spilling symbol */
1673 sloc->type = copyLinkChain (sym->type);
1674 sloc->etype = getSpec (sloc->type);
1675 SPEC_SCLS (sloc->etype) = S_DATA;
1676 SPEC_EXTR (sloc->etype) = 0;
1677 SPEC_STAT (sloc->etype) = 0;
1679 /* we don't allow it to be allocated`
1680 onto the external stack since : so we
1681 temporarily turn it off ; we also
1682 turn off memory model to prevent
1683 the spil from going to the external storage
1684 and turn off overlaying
1687 useXstack = options.useXstack;
1688 model = options.model;
1689 noOverlay = options.noOverlay;
1690 options.noOverlay = 1;
1691 options.model = options.useXstack = 0;
1695 options.useXstack = useXstack;
1696 options.model = model;
1697 options.noOverlay = noOverlay;
1698 sloc->isref = 1; /* to prevent compiler warning */
1700 /* if it is on the stack then update the stack */
1701 if (IN_STACK (sloc->etype))
1703 currFunc->stack += getSize (sloc->type);
1704 _G.stackExtend += getSize (sloc->type);
1707 _G.dataExtend += getSize (sloc->type);
1709 /* add it to the _G.stackSpil set */
1710 addSetHead (&_G.stackSpil, sloc);
1711 sym->usl.spillLoc = sloc;
1714 /* add it to the set of itempStack set
1715 of the spill location */
1716 addSetHead (&sloc->usl.itmpStack, sym);
1720 /*-----------------------------------------------------------------*/
1721 /* isSpiltOnStack - returns true if the spil location is on stack */
1722 /*-----------------------------------------------------------------*/
1724 isSpiltOnStack (symbol * sym)
1728 debugLog ("%s\n", __FUNCTION__);
1735 /* if (sym->_G.stackSpil) */
1738 if (!sym->usl.spillLoc)
1741 etype = getSpec (sym->usl.spillLoc->type);
1742 if (IN_STACK (etype))
1748 /*-----------------------------------------------------------------*/
1749 /* spillThis - spils a specific operand */
1750 /*-----------------------------------------------------------------*/
1752 spillThis (symbol * sym)
1755 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1757 /* if this is rematerializable or has a spillLocation
1758 we are okay, else we need to create a spillLocation
1760 if (!(sym->remat || sym->usl.spillLoc))
1761 createStackSpil (sym);
1764 /* mark it has spilt & put it in the spilt set */
1766 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1768 bitVectUnSetBit (_G.regAssigned, sym->key);
1770 for (i = 0; i < sym->nRegs; i++)
1774 freeReg (sym->regs[i]);
1775 sym->regs[i] = NULL;
1778 /* if spilt on stack then free up r0 & r1
1779 if they could have been assigned to some
1781 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1784 spillLRWithPtrReg (sym);
1787 if (sym->usl.spillLoc && !sym->remat)
1788 sym->usl.spillLoc->allocreq = 1;
1792 /*-----------------------------------------------------------------*/
1793 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1794 /*-----------------------------------------------------------------*/
1796 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1798 bitVect *lrcs = NULL;
1802 debugLog ("%s\n", __FUNCTION__);
1803 /* get the spillable live ranges */
1804 lrcs = computeSpillable (ic);
1806 /* get all live ranges that are rematerizable */
1807 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1810 /* return the least used of these */
1811 return leastUsedLR (selectS);
1814 /* get live ranges with spillLocations in direct space */
1815 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1817 sym = leastUsedLR (selectS);
1818 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1819 sym->usl.spillLoc->rname :
1820 sym->usl.spillLoc->name));
1822 /* mark it as allocation required */
1823 sym->usl.spillLoc->allocreq = 1;
1827 /* if the symbol is local to the block then */
1828 if (forSym->liveTo < ebp->lSeq)
1831 /* check if there are any live ranges allocated
1832 to registers that are not used in this block */
1833 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1835 sym = leastUsedLR (selectS);
1836 /* if this is not rematerializable */
1845 /* check if there are any live ranges that not
1846 used in the remainder of the block */
1847 if (!_G.blockSpil &&
1848 !isiCodeInFunctionCall (ic) &&
1849 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1851 sym = leastUsedLR (selectS);
1854 sym->remainSpil = 1;
1861 /* find live ranges with spillocation && not used as pointers */
1862 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1865 sym = leastUsedLR (selectS);
1866 /* mark this as allocation required */
1867 sym->usl.spillLoc->allocreq = 1;
1871 /* find live ranges with spillocation */
1872 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1875 sym = leastUsedLR (selectS);
1876 sym->usl.spillLoc->allocreq = 1;
1880 /* couldn't find then we need to create a spil
1881 location on the stack , for which one? the least
1883 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1886 /* return a created spil location */
1887 sym = createStackSpil (leastUsedLR (selectS));
1888 sym->usl.spillLoc->allocreq = 1;
1892 /* this is an extreme situation we will spill
1893 this one : happens very rarely but it does happen */
1899 /*-----------------------------------------------------------------*/
1900 /* spilSomething - spil some variable & mark registers as free */
1901 /*-----------------------------------------------------------------*/
1903 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1908 debugLog ("%s\n", __FUNCTION__);
1909 /* get something we can spil */
1910 ssym = selectSpil (ic, ebp, forSym);
1912 /* mark it as spilt */
1914 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1916 /* mark it as not register assigned &
1917 take it away from the set */
1918 bitVectUnSetBit (_G.regAssigned, ssym->key);
1920 /* mark the registers as free */
1921 for (i = 0; i < ssym->nRegs; i++)
1923 freeReg (ssym->regs[i]);
1925 /* if spilt on stack then free up r0 & r1
1926 if they could have been assigned to as gprs */
1927 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1930 spillLRWithPtrReg (ssym);
1933 /* if this was a block level spil then insert push & pop
1934 at the start & end of block respectively */
1935 if (ssym->blockSpil)
1937 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1938 /* add push to the start of the block */
1939 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1940 ebp->sch->next : ebp->sch));
1941 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1942 /* add pop to the end of the block */
1943 addiCodeToeBBlock (ebp, nic, NULL);
1946 /* if spilt because not used in the remainder of the
1947 block then add a push before this instruction and
1948 a pop at the end of the block */
1949 if (ssym->remainSpil)
1952 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1953 /* add push just before this instruction */
1954 addiCodeToeBBlock (ebp, nic, ic);
1956 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1957 /* add pop to the end of the block */
1958 addiCodeToeBBlock (ebp, nic, NULL);
1967 /*-----------------------------------------------------------------*/
1968 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1969 /*-----------------------------------------------------------------*/
1971 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1976 debugLog ("%s\n", __FUNCTION__);
1978 /* try for a ptr type */
1979 if ((reg = allocReg (REG_PTR)))
1982 /* try for gpr type */
1983 if ((reg = allocReg (REG_GPR)))
1986 /* we have to spil */
1987 if (!spilSomething (ic, ebp, sym))
1990 /* make sure partially assigned registers aren't reused */
1991 for (j=0; j<=sym->nRegs; j++)
1993 sym->regs[j]->isFree = 0;
1995 /* this looks like an infinite loop but
1996 in really selectSpil will abort */
2000 /*-----------------------------------------------------------------*/
2001 /* getRegGpr - will try for GPR if not spil */
2002 /*-----------------------------------------------------------------*/
2004 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
2009 debugLog ("%s\n", __FUNCTION__);
2011 /* try for gpr type */
2012 if ((reg = allocReg (REG_GPR)))
2015 if (!pic16_ptrRegReq)
2016 if ((reg = allocReg (REG_PTR)))
2019 /* we have to spil */
2020 if (!spilSomething (ic, ebp, sym))
2023 /* make sure partially assigned registers aren't reused */
2024 for (j=0; j<=sym->nRegs; j++)
2026 sym->regs[j]->isFree = 0;
2028 /* this looks like an infinite loop but
2029 in really selectSpil will abort */
2033 /*-----------------------------------------------------------------*/
2034 /* symHasReg - symbol has a given register */
2035 /*-----------------------------------------------------------------*/
2037 symHasReg (symbol * sym, regs * reg)
2041 debugLog ("%s\n", __FUNCTION__);
2042 for (i = 0; i < sym->nRegs; i++)
2043 if (sym->regs[i] == reg)
2049 /*-----------------------------------------------------------------*/
2050 /* deassignLRs - check the live to and if they have registers & are */
2051 /* not spilt then free up the registers */
2052 /*-----------------------------------------------------------------*/
2054 deassignLRs (iCode * ic, eBBlock * ebp)
2060 debugLog ("%s\n", __FUNCTION__);
2061 for (sym = hTabFirstItem (liveRanges, &k); sym;
2062 sym = hTabNextItem (liveRanges, &k))
2065 symbol *psym = NULL;
2066 /* if it does not end here */
2067 if (sym->liveTo > ic->seq)
2070 /* if it was spilt on stack then we can
2071 mark the stack spil location as free */
2076 sym->usl.spillLoc->isFree = 1;
2082 if (!bitVectBitValue (_G.regAssigned, sym->key))
2085 /* special case for shifting: there is a case where shift count
2086 * can be allocated in the same register as the result, so do not
2087 * free right registers if same as result registers, cause genShiftLeft
2088 * will fail -- VR */
2089 if(ic->op == LEFT_OP)
2092 /* special case check if this is an IFX &
2093 the privious one was a pop and the
2094 previous one was not spilt then keep track
2096 if (ic->op == IFX && ic->prev &&
2097 ic->prev->op == IPOP &&
2098 !ic->prev->parmPush &&
2099 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2100 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2106 bitVectUnSetBit (_G.regAssigned, sym->key);
2108 /* if the result of this one needs registers
2109 and does not have it then assign it right
2111 if (IC_RESULT (ic) &&
2112 !(SKIP_IC2 (ic) || /* not a special icode */
2113 ic->op == JUMPTABLE ||
2118 POINTER_SET (ic)) &&
2119 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2120 result->liveTo > ic->seq && /* and will live beyond this */
2121 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2122 result->liveFrom == ic->seq && /* does not start before here */
2123 result->regType == sym->regType && /* same register types */
2124 result->nRegs && /* which needs registers */
2125 !result->isspilt && /* and does not already have them */
2127 !bitVectBitValue (_G.regAssigned, result->key) &&
2128 /* the number of free regs + number of regs in this LR
2129 can accomodate the what result Needs */
2130 ((nfreeRegsType (result->regType) +
2131 sym->nRegs) >= result->nRegs)
2136 // for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2137 /* the above does not free the unsued registers in sym,
2138 * leaving them marked as used, and increasing register usage
2139 * until the end of the function - VR 23/11/05 */
2141 for (i = 0; i < result->nRegs; i++)
2143 result->regs[i] = sym->regs[i];
2145 result->regs[i] = getRegGpr (ic, ebp, result);
2147 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2150 /* free the remaining */
2151 for (; i < sym->nRegs; i++)
2155 if (!symHasReg (psym, sym->regs[i]))
2156 freeReg (sym->regs[i]);
2159 freeReg (sym->regs[i]);
2166 /*-----------------------------------------------------------------*/
2167 /* reassignLR - reassign this to registers */
2168 /*-----------------------------------------------------------------*/
2170 reassignLR (operand * op)
2172 symbol *sym = OP_SYMBOL (op);
2175 debugLog ("%s\n", __FUNCTION__);
2176 /* not spilt any more */
2177 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2178 bitVectUnSetBit (_G.spiltSet, sym->key);
2180 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2184 for (i = 0; i < sym->nRegs; i++)
2185 sym->regs[i]->isFree = 0;
2188 /*-----------------------------------------------------------------*/
2189 /* willCauseSpill - determines if allocating will cause a spill */
2190 /*-----------------------------------------------------------------*/
2192 willCauseSpill (int nr, int rt)
2194 debugLog ("%s\n", __FUNCTION__);
2195 /* first check if there are any avlb registers
2196 of te type required */
2199 /* special case for pointer type
2200 if pointer type not avlb then
2201 check for type gpr */
2202 if (nFreeRegs (rt) >= nr)
2204 if (nFreeRegs (REG_GPR) >= nr)
2209 if (pic16_ptrRegReq)
2211 if (nFreeRegs (rt) >= nr)
2216 if (nFreeRegs (REG_PTR) +
2217 nFreeRegs (REG_GPR) >= nr)
2222 debugLog (" ... yep it will (cause a spill)\n");
2223 /* it will cause a spil */
2227 /*-----------------------------------------------------------------*/
2228 /* positionRegs - the allocator can allocate same registers to res- */
2229 /* ult and operand, if this happens make sure they are in the same */
2230 /* position as the operand otherwise chaos results */
2231 /*-----------------------------------------------------------------*/
2233 positionRegs (symbol * result, symbol * opsym, int lineno)
2235 int count = min (result->nRegs, opsym->nRegs);
2236 int i, j = 0, shared = 0;
2238 debugLog ("%s\n", __FUNCTION__);
2239 /* if the result has been spilt then cannot share */
2244 /* first make sure that they actually share */
2245 for (i = 0; i < count; i++)
2247 for (j = 0; j < count; j++)
2249 if (result->regs[i] == opsym->regs[j] && i != j)
2259 regs *tmp = result->regs[i];
2260 result->regs[i] = result->regs[j];
2261 result->regs[j] = tmp;
2266 /*------------------------------------------------------------------*/
2267 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2268 /* it should either have registers or have beed spilled. Otherwise, */
2269 /* there was an uninitialized variable, so just spill this to get */
2270 /* the operand in a valid state. */
2271 /*------------------------------------------------------------------*/
2273 verifyRegsAssigned (operand *op, iCode * ic)
2278 if (!IS_ITEMP (op)) return;
2280 sym = OP_SYMBOL (op);
2281 if (sym->isspilt) return;
2282 if (!sym->nRegs) return;
2283 if (sym->regs[0]) return;
2285 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2286 sym->prereqv ? sym->prereqv->name : sym->name);
2291 /*-----------------------------------------------------------------*/
2292 /* serialRegAssign - serially allocate registers to the variables */
2293 /*-----------------------------------------------------------------*/
2295 serialRegAssign (eBBlock ** ebbs, int count)
2300 debugLog ("%s\n", __FUNCTION__);
2301 /* for all blocks */
2302 for (i = 0; i < count; i++)
2304 if (ebbs[i]->noPath &&
2305 (ebbs[i]->entryLabel != entryLabel &&
2306 ebbs[i]->entryLabel != returnLabel))
2309 /* of all instructions do */
2310 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2313 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2315 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2316 pic16_allocDirReg(IC_RESULT(ic));
2318 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2319 pic16_allocDirReg(IC_LEFT(ic));
2321 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2322 pic16_allocDirReg(IC_RIGHT(ic));
2324 /* if this is an ipop that means some live
2325 range will have to be assigned again */
2327 reassignLR (IC_LEFT (ic));
2329 /* if result is present && is a true symbol */
2330 if (IC_RESULT (ic) && ic->op != IFX &&
2331 IS_TRUE_SYMOP (IC_RESULT (ic)))
2332 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2334 /* take away registers from live
2335 ranges that end at this instruction */
2336 deassignLRs (ic, ebbs[i]);
2338 /* some don't need registers */
2339 if (SKIP_IC2 (ic) ||
2340 ic->op == JUMPTABLE ||
2344 (IC_RESULT (ic) && POINTER_SET (ic)))
2347 /* now we need to allocate registers
2348 only for the result */
2351 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2357 /* Make sure any spill location is definately allocated */
2358 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2359 !sym->usl.spillLoc->allocreq)
2361 sym->usl.spillLoc->allocreq++;
2364 /* if it does not need or is spilt
2365 or is already assigned to registers
2366 or will not live beyond this instructions */
2369 bitVectBitValue (_G.regAssigned, sym->key) ||
2370 sym->liveTo <= ic->seq)
2373 /* if some liverange has been spilt at the block level
2374 and this one live beyond this block then spil this
2376 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2381 /* if trying to allocate this will cause
2382 a spill and there is nothing to spill
2383 or this one is rematerializable then
2385 willCS = willCauseSpill (sym->nRegs, sym->regType);
2387 /* explicit turn off register spilling */
2390 spillable = computeSpillable (ic);
2392 (willCS && bitVectIsZero (spillable)))
2400 /* If the live range preceeds the point of definition
2401 then ideally we must take into account registers that
2402 have been allocated after sym->liveFrom but freed
2403 before ic->seq. This is complicated, so spill this
2404 symbol instead and let fillGaps handle the allocation. */
2406 if (sym->liveFrom < ic->seq)
2412 /* if it has a spillocation & is used less than
2413 all other live ranges then spill this */
2415 if (sym->usl.spillLoc) {
2416 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2417 allLRs, ebbs[i], ic));
2418 if (leastUsed && leastUsed->used > sym->used) {
2423 /* if none of the liveRanges have a spillLocation then better
2424 to spill this one than anything else already assigned to registers */
2425 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2426 /* if this is local to this block then we might find a block spil */
2427 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2435 if (ic->op == RECEIVE)
2436 debugLog ("When I get clever, I'll optimize the receive logic\n");
2438 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2439 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2440 && (ic->next->op == IFX)
2441 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2443 /* skip register allocation since none will be used */
2444 for(j=0;j<sym->nRegs;j++)
2445 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2446 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2451 /* if we need ptr regs for the right side
2453 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2454 <= (unsigned) PTRSIZE)
2459 /* else we assign registers to it */
2460 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2463 bitVectDebugOn(_G.regAssigned, debugF);
2465 for (j = 0; j < sym->nRegs; j++)
2467 if (sym->regType == REG_PTR)
2468 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2470 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2472 /* if the allocation falied which means
2473 this was spilt then break */
2477 debugLog (" %d - \n", __LINE__);
2479 /* if it shares registers with operands make sure
2480 that they are in the same position */
2481 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2482 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2483 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2484 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2485 /* do the same for the right operand */
2486 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2487 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2488 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2489 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2491 debugLog (" %d - \n", __LINE__);
2494 debugLog (" %d - \n", __LINE__);
2503 /* Check for and fix any problems with uninitialized operands */
2504 for (i = 0; i < count; i++)
2508 if (ebbs[i]->noPath &&
2509 (ebbs[i]->entryLabel != entryLabel &&
2510 ebbs[i]->entryLabel != returnLabel))
2513 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2520 verifyRegsAssigned (IC_COND (ic), ic);
2524 if (ic->op == JUMPTABLE)
2526 verifyRegsAssigned (IC_JTCOND (ic), ic);
2530 verifyRegsAssigned (IC_RESULT (ic), ic);
2531 verifyRegsAssigned (IC_LEFT (ic), ic);
2532 verifyRegsAssigned (IC_RIGHT (ic), ic);
2538 /*-----------------------------------------------------------------*/
2539 /* rUmaskForOp :- returns register mask for an operand */
2540 /*-----------------------------------------------------------------*/
2542 rUmaskForOp (operand * op)
2548 debugLog ("%s\n", __FUNCTION__);
2549 /* only temporaries are assigned registers */
2553 sym = OP_SYMBOL (op);
2555 /* if spilt or no registers assigned to it
2557 if (sym->isspilt || !sym->nRegs)
2560 rumask = newBitVect (pic16_nRegs);
2562 for (j = 0; j < sym->nRegs; j++)
2564 rumask = bitVectSetBit (rumask,
2565 sym->regs[j]->rIdx);
2571 /*-----------------------------------------------------------------*/
2572 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2573 /*-----------------------------------------------------------------*/
2575 regsUsedIniCode (iCode * ic)
2577 bitVect *rmask = newBitVect (pic16_nRegs);
2579 debugLog ("%s\n", __FUNCTION__);
2580 /* do the special cases first */
2583 rmask = bitVectUnion (rmask,
2584 rUmaskForOp (IC_COND (ic)));
2588 /* for the jumptable */
2589 if (ic->op == JUMPTABLE)
2591 rmask = bitVectUnion (rmask,
2592 rUmaskForOp (IC_JTCOND (ic)));
2597 /* of all other cases */
2599 rmask = bitVectUnion (rmask,
2600 rUmaskForOp (IC_LEFT (ic)));
2604 rmask = bitVectUnion (rmask,
2605 rUmaskForOp (IC_RIGHT (ic)));
2608 rmask = bitVectUnion (rmask,
2609 rUmaskForOp (IC_RESULT (ic)));
2615 /*-----------------------------------------------------------------*/
2616 /* createRegMask - for each instruction will determine the regsUsed */
2617 /*-----------------------------------------------------------------*/
2619 createRegMask (eBBlock ** ebbs, int count)
2623 debugLog ("%s\n", __FUNCTION__);
2624 /* for all blocks */
2625 for (i = 0; i < count; i++)
2629 if (ebbs[i]->noPath &&
2630 (ebbs[i]->entryLabel != entryLabel &&
2631 ebbs[i]->entryLabel != returnLabel))
2634 /* for all instructions */
2635 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2640 if (SKIP_IC2 (ic) || !ic->rlive)
2643 /* first mark the registers used in this
2645 ic->rUsed = regsUsedIniCode (ic);
2646 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2648 /* now create the register mask for those
2649 registers that are in use : this is a
2650 super set of ic->rUsed */
2651 ic->rMask = newBitVect (pic16_nRegs + 1);
2653 /* for all live Ranges alive at this point */
2654 for (j = 1; j < ic->rlive->size; j++)
2659 /* if not alive then continue */
2660 if (!bitVectBitValue (ic->rlive, j))
2663 /* find the live range we are interested in */
2664 if (!(sym = hTabItemWithKey (liveRanges, j)))
2666 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2667 "createRegMask cannot find live range");
2671 /* if no register assigned to it */
2672 if (!sym->nRegs || sym->isspilt)
2675 /* for all the registers allocated to it */
2676 for (k = 0; k < sym->nRegs; k++)
2679 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2685 /*-----------------------------------------------------------------*/
2686 /* rematStr - returns the rematerialized string for a remat var */
2687 /*-----------------------------------------------------------------*/
2689 rematStr (symbol * sym)
2692 iCode *ic = sym->rematiCode;
2693 symbol *psym = NULL;
2695 debugLog ("%s\n", __FUNCTION__);
2697 //printf ("%s\n", s);
2699 /* if plus or minus print the right hand side */
2701 if (ic->op == '+' || ic->op == '-') {
2703 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2705 sprintf (s, "(%s %c 0x%04x)",
2706 OP_SYMBOL (IC_LEFT (ric))->rname,
2708 (int) operandLitValue (IC_RIGHT (ic)));
2711 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2713 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2714 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2719 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2720 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2722 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2727 /*-----------------------------------------------------------------*/
2728 /* rematStr - returns the rematerialized string for a remat var */
2729 /*-----------------------------------------------------------------*/
2731 rematStr (symbol * sym)
2734 iCode *ic = sym->rematiCode;
2736 debugLog ("%s\n", __FUNCTION__);
2741 /* if plus or minus print the right hand side */
2743 if (ic->op == '+' || ic->op == '-') {
2744 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2747 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2751 if (ic->op == '+' || ic->op == '-')
2753 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2754 sprintf (s, "(%s %c 0x%04x)",
2755 OP_SYMBOL (IC_LEFT (ric))->rname,
2757 (int) operandLitValue (IC_RIGHT (ic)));
2760 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2762 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2766 /* we reached the end */
2767 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2771 printf ("%s\n", buffer);
2776 /*-----------------------------------------------------------------*/
2777 /* regTypeNum - computes the type & number of registers required */
2778 /*-----------------------------------------------------------------*/
2786 debugLog ("%s\n", __FUNCTION__);
2787 /* for each live range do */
2788 for (sym = hTabFirstItem (liveRanges, &k); sym;
2789 sym = hTabNextItem (liveRanges, &k)) {
2791 debugLog (" %d - %s\n", __LINE__, sym->rname);
2792 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2794 /* if used zero times then no registers needed */
2795 if ((sym->liveTo - sym->liveFrom) == 0)
2799 /* if the live range is a temporary */
2802 debugLog (" %d - itemp register\n", __LINE__);
2804 /* if the type is marked as a conditional */
2805 if (sym->regType == REG_CND)
2808 /* if used in return only then we don't
2810 if (sym->ruonly || sym->accuse) {
2811 if (IS_AGGREGATE (sym->type) || sym->isptr)
2812 sym->type = aggrToPtr (sym->type, FALSE);
2813 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2817 /* if the symbol has only one definition &
2818 that definition is a get_pointer and the
2819 pointer we are getting is rematerializable and
2822 if (bitVectnBitsOn (sym->defs) == 1 &&
2823 (ic = hTabItemWithKey (iCodehTab,
2824 bitVectFirstBit (sym->defs))) &&
2826 !IS_BITVAR (sym->etype) &&
2827 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2829 // continue; /* FIXME -- VR */
2830 if (ptrPseudoSymSafe (sym, ic)) {
2834 debugLog (" %d - \n", __LINE__);
2836 /* create a psuedo symbol & force a spil */
2837 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2838 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2839 psym->type = sym->type;
2840 psym->etype = sym->etype;
2841 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2842 strcpy (psym->rname, psym->name);
2844 sym->usl.spillLoc = psym;
2848 /* if in data space or idata space then try to
2849 allocate pointer register */
2853 /* if not then we require registers */
2854 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2855 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2856 getSize (sym->type));
2860 if(IS_PTR_CONST (sym->type)) {
2862 if(IS_CODEPTR (sym->type)) {
2864 // what IS this ???? (HJD)
2865 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2866 sym->nRegs = 3; // patch 14
2869 if (sym->nRegs > 4) {
2870 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2871 printTypeChain (sym->type, stderr);
2872 fprintf (stderr, "\n");
2875 /* determine the type of register required */
2876 if (sym->nRegs == 1 &&
2877 IS_PTR (sym->type) &&
2879 sym->regType = REG_PTR;
2881 sym->regType = REG_GPR;
2884 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2888 /* for the first run we don't provide */
2889 /* registers for true symbols we will */
2890 /* see how things go */
2896 static DEFSETFUNC (markRegFree)
2898 ((regs *)item)->isFree = 1;
2899 // ((regs *)item)->wasUsed = 0;
2904 DEFSETFUNC (pic16_deallocReg)
2906 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2907 ((regs *)item)->isFree = 1;
2908 ((regs *)item)->wasUsed = 0;
2912 /*-----------------------------------------------------------------*/
2913 /* freeAllRegs - mark all registers as free */
2914 /*-----------------------------------------------------------------*/
2916 pic16_freeAllRegs ()
2918 debugLog ("%s\n", __FUNCTION__);
2920 applyToSet(pic16_dynAllocRegs,markRegFree);
2921 applyToSet(pic16_dynStackRegs,markRegFree);
2924 /*-----------------------------------------------------------------*/
2925 /*-----------------------------------------------------------------*/
2927 pic16_deallocateAllRegs ()
2929 debugLog ("%s\n", __FUNCTION__);
2931 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2935 /*-----------------------------------------------------------------*/
2936 /* deallocStackSpil - this will set the stack pointer back */
2937 /*-----------------------------------------------------------------*/
2939 DEFSETFUNC (deallocStackSpil)
2943 debugLog ("%s\n", __FUNCTION__);
2948 /*-----------------------------------------------------------------*/
2949 /* farSpacePackable - returns the packable icode for far variables */
2950 /*-----------------------------------------------------------------*/
2952 farSpacePackable (iCode * ic)
2956 debugLog ("%s\n", __FUNCTION__);
2957 /* go thru till we find a definition for the
2958 symbol on the right */
2959 for (dic = ic->prev; dic; dic = dic->prev)
2962 /* if the definition is a call then no */
2963 if ((dic->op == CALL || dic->op == PCALL) &&
2964 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2969 /* if shift by unknown amount then not */
2970 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2971 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2974 /* if pointer get and size > 1 */
2975 if (POINTER_GET (dic) &&
2976 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2979 if (POINTER_SET (dic) &&
2980 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2983 /* if any three is a true symbol in far space */
2984 if (IC_RESULT (dic) &&
2985 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2986 isOperandInFarSpace (IC_RESULT (dic)))
2989 if (IC_RIGHT (dic) &&
2990 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2991 isOperandInFarSpace (IC_RIGHT (dic)) &&
2992 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2995 if (IC_LEFT (dic) &&
2996 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2997 isOperandInFarSpace (IC_LEFT (dic)) &&
2998 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
3001 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
3003 if ((dic->op == LEFT_OP ||
3004 dic->op == RIGHT_OP ||
3006 IS_OP_LITERAL (IC_RIGHT (dic)))
3017 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
3021 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3022 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3023 debugAopGet (" result:", IC_RESULT (ic));
3024 debugAopGet (" left:", IC_LEFT (ic));
3025 debugAopGet (" right:", IC_RIGHT (ic));
3034 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3036 /*-----------------------------------------------------------------*/
3037 /* packRegsForAssign - register reduction for assignment */
3038 /*-----------------------------------------------------------------*/
3040 packRegsForAssign (iCode * ic, eBBlock * ebp)
3044 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3045 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3046 debugAopGet (" result:", IC_RESULT (ic));
3047 debugAopGet (" left:", IC_LEFT (ic));
3048 debugAopGet (" right:", IC_RIGHT (ic));
3050 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3052 debugLog(" %d - actuall processing\n", __LINE__ );
3054 if (!IS_ITEMP (IC_RESULT (ic))) {
3055 pic16_allocDirReg(IC_RESULT (ic));
3056 debugLog (" %d - result is not temp\n", __LINE__);
3059 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3061 /* See BUGLOG0001 - VR */
3063 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3064 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3065 pic16_allocDirReg(IC_RIGHT (ic));
3070 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3071 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3073 debugLog (" %d - not packing - right side fails \n", __LINE__);
3077 /* if the true symbol is defined in far space or on stack
3078 then we should not since this will increase register pressure */
3079 if (isOperandInFarSpace (IC_RESULT (ic)))
3081 if ((dic = farSpacePackable (ic)))
3088 /* find the definition of iTempNN scanning backwards if we find a
3089 a use of the true symbol before we find the definition then
3091 for (dic = ic->prev; dic; dic = dic->prev)
3094 /* if there is a function call and this is
3095 a parameter & not my parameter then don't pack it */
3096 if ((dic->op == CALL || dic->op == PCALL) &&
3097 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3098 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3100 debugLog (" %d - \n", __LINE__);
3109 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3111 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3112 IS_OP_VOLATILE (IC_RESULT (dic)))
3114 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3120 if( IS_SYMOP( IC_RESULT(dic)) &&
3121 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3123 debugLog (" %d - result is bitfield\n", __LINE__);
3129 if (IS_SYMOP (IC_RESULT (dic)) &&
3130 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3132 /* A previous result was assigned to the same register - we'll our definition */
3133 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3134 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3135 if (POINTER_SET (dic))
3141 if (IS_SYMOP (IC_RIGHT (dic)) &&
3142 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3143 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3145 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3150 if (IS_SYMOP (IC_LEFT (dic)) &&
3151 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3152 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3154 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3159 if (POINTER_SET (dic) &&
3160 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3162 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3170 return 0; /* did not find */
3173 /* This code is taken from the hc08 port. Do not know
3174 * if it fits for pic16, but I leave it here just in case */
3176 /* if assignment then check that right is not a bit */
3177 if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
3178 sym_link *etype = operandType (IC_RESULT (dic));
3180 if (IS_BITFIELD (etype)) {
3181 /* if result is a bit too then it's ok */
3182 etype = operandType (IC_RESULT (ic));
3183 if (!IS_BITFIELD (etype)) {
3184 debugLog(" %d bitfields\n");
3191 /* if the result is on stack or iaccess then it must be
3192 the same atleast one of the operands */
3193 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3194 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3196 /* the operation has only one symbol
3197 operator then we can pack */
3198 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3199 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3202 if (!((IC_LEFT (dic) &&
3203 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3205 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3209 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3210 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3211 /* found the definition */
3212 /* replace the result with the result of */
3213 /* this assignment and remove this assignment */
3216 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3217 IC_RESULT (dic) = IC_RESULT (ic);
3219 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3221 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3223 /* delete from liverange table also
3224 delete from all the points inbetween and the new
3226 for (sic = dic; sic != ic; sic = sic->next)
3228 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3229 if (IS_ITEMP (IC_RESULT (dic)))
3230 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3233 remiCodeFromeBBlock (ebp, ic);
3234 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3236 debugLog(" %d\n", __LINE__ );
3237 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3238 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3245 #define NO_packRegsForAccUse
3246 #define NO_packRegsForSupport
3247 #define NO_packRegsForOneuse
3248 #define NO_cast_peep
3253 #ifndef NO_packRegsForSupport
3254 /*-----------------------------------------------------------------*/
3255 /* findAssignToSym : scanning backwards looks for first assig found */
3256 /*-----------------------------------------------------------------*/
3258 findAssignToSym (operand * op, iCode * ic)
3262 debugLog ("%s\n", __FUNCTION__);
3263 for (dic = ic->prev; dic; dic = dic->prev)
3266 /* if definition by assignment */
3267 if (dic->op == '=' &&
3268 !POINTER_SET (dic) &&
3269 IC_RESULT (dic)->key == op->key
3270 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3274 /* we are interested only if defined in far space */
3275 /* or in stack space in case of + & - */
3277 /* if assigned to a non-symbol then return
3279 if (!IS_SYMOP (IC_RIGHT (dic)))
3282 /* if the symbol is in far space then
3284 if (isOperandInFarSpace (IC_RIGHT (dic)))
3287 /* for + & - operations make sure that
3288 if it is on the stack it is the same
3289 as one of the three operands */
3290 if ((ic->op == '+' || ic->op == '-') &&
3291 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3293 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3294 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3295 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3303 /* if we find an usage then we cannot delete it */
3304 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3307 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3310 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3314 /* now make sure that the right side of dic
3315 is not defined between ic & dic */
3318 iCode *sic = dic->next;
3320 for (; sic != ic; sic = sic->next)
3321 if (IC_RESULT (sic) &&
3322 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3333 #ifndef NO_packRegsForSupport
3334 /*-----------------------------------------------------------------*/
3335 /* packRegsForSupport :- reduce some registers for support calls */
3336 /*-----------------------------------------------------------------*/
3338 packRegsForSupport (iCode * ic, eBBlock * ebp)
3342 debugLog ("%s\n", __FUNCTION__);
3343 /* for the left & right operand :- look to see if the
3344 left was assigned a true symbol in far space in that
3345 case replace them */
3346 if (IS_ITEMP (IC_LEFT (ic)) &&
3347 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3349 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3355 debugAopGet ("removing left:", IC_LEFT (ic));
3357 /* found it we need to remove it from the
3359 for (sic = dic; sic != ic; sic = sic->next)
3360 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3362 IC_LEFT (ic)->operand.symOperand =
3363 IC_RIGHT (dic)->operand.symOperand;
3364 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3365 remiCodeFromeBBlock (ebp, dic);
3366 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3367 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3371 /* do the same for the right operand */
3374 IS_ITEMP (IC_RIGHT (ic)) &&
3375 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3377 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3383 /* if this is a subtraction & the result
3384 is a true symbol in far space then don't pack */
3385 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3387 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3388 if (IN_FARSPACE (SPEC_OCLS (etype)))
3392 debugAopGet ("removing right:", IC_RIGHT (ic));
3394 /* found it we need to remove it from the
3396 for (sic = dic; sic != ic; sic = sic->next)
3397 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3399 IC_RIGHT (ic)->operand.symOperand =
3400 IC_RIGHT (dic)->operand.symOperand;
3401 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3403 remiCodeFromeBBlock (ebp, dic);
3404 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3405 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3414 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3416 #ifndef NO_packRegsForOneuse
3417 /*-----------------------------------------------------------------*/
3418 /* packRegsForOneuse : - will reduce some registers for single Use */
3419 /*-----------------------------------------------------------------*/
3421 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3428 debugLog ("%s\n", __FUNCTION__);
3429 /* if returning a literal then do nothing */
3433 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3436 /* only upto 2 bytes since we cannot predict
3437 the usage of b, & acc */
3438 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3446 /* this routine will mark the a symbol as used in one
3447 instruction use only && if the definition is local
3448 (ie. within the basic block) && has only one definition &&
3449 that definition is either a return value from a
3450 function or does not contain any variables in
3454 uses = bitVectCopy (OP_USES (op));
3455 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3456 if (!bitVectIsZero (uses)) /* has other uses */
3461 if (bitVectnBitsOn (OP_USES (op)) > 1)
3465 /* if it has only one defintion */
3466 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3467 return NULL; /* has more than one definition */
3469 /* get that definition */
3471 hTabItemWithKey (iCodehTab,
3472 bitVectFirstBit (OP_DEFS (op)))))
3475 /* found the definition now check if it is local */
3476 if (dic->seq < ebp->fSeq ||
3477 dic->seq > ebp->lSeq)
3478 return NULL; /* non-local */
3480 /* now check if it is the return from
3482 if (dic->op == CALL || dic->op == PCALL)
3484 if (ic->op != SEND && ic->op != RETURN &&
3485 !POINTER_SET(ic) && !POINTER_GET(ic))
3487 OP_SYMBOL (op)->ruonly = 1;
3496 /* otherwise check that the definition does
3497 not contain any symbols in far space */
3498 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3499 isOperandInFarSpace (IC_RIGHT (dic)) ||
3500 IS_OP_RUONLY (IC_LEFT (ic)) ||
3501 IS_OP_RUONLY (IC_RIGHT (ic)))
3506 /* if pointer set then make sure the pointer
3508 if (POINTER_SET (dic) &&
3509 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3512 if (POINTER_GET (dic) &&
3513 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3519 /* also make sure the intervenening instructions
3520 don't have any thing in far space */
3521 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3524 /* if there is an intervening function call then no */
3525 if (dic->op == CALL || dic->op == PCALL)
3527 /* if pointer set then make sure the pointer
3529 if (POINTER_SET (dic) &&
3530 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3533 if (POINTER_GET (dic) &&
3534 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3537 /* if address of & the result is remat then okay */
3538 if (dic->op == ADDRESS_OF &&
3539 OP_SYMBOL (IC_RESULT (dic))->remat)
3542 /* if operand has size of three or more & this
3543 operation is a '*','/' or '%' then 'b' may
3545 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3546 getSize (operandType (op)) >= 2)
3549 /* if left or right or result is in far space */
3550 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3551 isOperandInFarSpace (IC_RIGHT (dic)) ||
3552 isOperandInFarSpace (IC_RESULT (dic)) ||
3553 IS_OP_RUONLY (IC_LEFT (dic)) ||
3554 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3555 IS_OP_RUONLY (IC_RESULT (dic)))
3561 OP_SYMBOL (op)->ruonly = 1;
3568 /*-----------------------------------------------------------------*/
3569 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3570 /*-----------------------------------------------------------------*/
3572 isBitwiseOptimizable (iCode * ic)
3574 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3575 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3577 debugLog ("%s\n", __FUNCTION__);
3578 /* bitwise operations are considered optimizable
3579 under the following conditions (Jean-Louis VERN)
3591 if (IS_LITERAL (rtype) ||
3592 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3599 #ifndef NO_packRegsForAccUse
3601 /*-----------------------------------------------------------------*/
3602 /* packRegsForAccUse - pack registers for acc use */
3603 /*-----------------------------------------------------------------*/
3605 packRegsForAccUse (iCode * ic)
3609 debugLog ("%s\n", __FUNCTION__);
3611 /* if this is an aggregate, e.g. a one byte char array */
3612 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3615 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3617 /* if + or - then it has to be one byte result */
3618 if ((ic->op == '+' || ic->op == '-')
3619 && getSize (operandType (IC_RESULT (ic))) > 1)
3622 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3623 /* if shift operation make sure right side is not a literal */
3624 if (ic->op == RIGHT_OP &&
3625 (isOperandLiteral (IC_RIGHT (ic)) ||
3626 getSize (operandType (IC_RESULT (ic))) > 1))
3629 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3630 if (ic->op == LEFT_OP &&
3631 (isOperandLiteral (IC_RIGHT (ic)) ||
3632 getSize (operandType (IC_RESULT (ic))) > 1))
3635 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3636 if (IS_BITWISE_OP (ic) &&
3637 getSize (operandType (IC_RESULT (ic))) > 1)
3641 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3642 /* has only one definition */
3643 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3646 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3647 /* has only one use */
3648 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3651 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3652 /* and the usage immediately follows this iCode */
3653 if (!(uic = hTabItemWithKey (iCodehTab,
3654 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3657 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3658 if (ic->next != uic)
3661 /* if it is a conditional branch then we definitely can */
3665 if (uic->op == JUMPTABLE)
3668 /* if the usage is not is an assignment
3669 or an arithmetic / bitwise / shift operation then not */
3670 if (POINTER_SET (uic) &&
3671 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3674 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3675 if (uic->op != '=' &&
3676 !IS_ARITHMETIC_OP (uic) &&
3677 !IS_BITWISE_OP (uic) &&
3678 uic->op != LEFT_OP &&
3679 uic->op != RIGHT_OP)
3682 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3683 /* if used in ^ operation then make sure right is not a
3685 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3688 /* if shift operation make sure right side is not a literal */
3689 if (uic->op == RIGHT_OP &&
3690 (isOperandLiteral (IC_RIGHT (uic)) ||
3691 getSize (operandType (IC_RESULT (uic))) > 1))
3694 if (uic->op == LEFT_OP &&
3695 (isOperandLiteral (IC_RIGHT (uic)) ||
3696 getSize (operandType (IC_RESULT (uic))) > 1))
3699 /* make sure that the result of this icode is not on the
3700 stack, since acc is used to compute stack offset */
3701 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3702 OP_SYMBOL (IC_RESULT (uic))->onStack)
3705 /* if either one of them in far space then we cannot */
3706 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3707 isOperandInFarSpace (IC_LEFT (uic))) ||
3708 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3709 isOperandInFarSpace (IC_RIGHT (uic))))
3712 /* if the usage has only one operand then we can */
3713 if (IC_LEFT (uic) == NULL ||
3714 IC_RIGHT (uic) == NULL)
3717 /* make sure this is on the left side if not
3718 a '+' since '+' is commutative */
3719 if (ic->op != '+' &&
3720 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3724 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3725 /* if one of them is a literal then we can */
3726 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3727 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3728 (getSize (operandType (IC_RESULT (uic))) <= 1))
3730 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3735 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3736 /* if the other one is not on stack then we can */
3737 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3738 (IS_ITEMP (IC_RIGHT (uic)) ||
3739 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3740 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3743 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3744 (IS_ITEMP (IC_LEFT (uic)) ||
3745 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3746 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3752 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3753 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3760 /*-----------------------------------------------------------------*/
3761 /* packForPush - hueristics to reduce iCode for pushing */
3762 /*-----------------------------------------------------------------*/
3764 packForReceive (iCode * ic, eBBlock * ebp)
3768 debugLog ("%s\n", __FUNCTION__);
3769 debugAopGet (" result:", IC_RESULT (ic));
3770 debugAopGet (" left:", IC_LEFT (ic));
3771 debugAopGet (" right:", IC_RIGHT (ic));
3776 for (dic = ic->next; dic; dic = dic->next)
3778 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3779 debugLog (" used on left\n");
3780 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3781 debugLog (" used on right\n");
3782 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3783 debugLog (" used on result\n");
3785 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3786 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3790 debugLog (" hey we can remove this unnecessary assign\n");
3792 /*-----------------------------------------------------------------*/
3793 /* packForPush - hueristics to reduce iCode for pushing */
3794 /*-----------------------------------------------------------------*/
3796 packForPush (iCode * ic, eBBlock * ebp)
3801 debugLog ("%s\n", __FUNCTION__);
3802 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3809 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3810 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3811 iLine = printILine(ic);
3812 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3814 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3818 /* must have only definition & one usage */
3819 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3820 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3823 /* find the definition */
3824 if (!(dic = hTabItemWithKey (iCodehTab,
3825 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3828 /* if definition is not assignment,
3829 * or is not pointer (because pointer might have changed) */
3830 if (dic->op != '=' || POINTER_SET (dic))
3833 /* we must ensure that we can use the delete the assignment,
3834 * because the source might have been modified in between.
3835 * Until I know how to fix this, I'll use the adhoc fix
3836 * to check the liveranges */
3837 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3839 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3843 /* we now we know that it has one & only one def & use
3844 and the that the definition is an assignment */
3845 IC_LEFT (ic) = IC_RIGHT (dic);
3847 iLine = printILine(dic);
3848 debugf("remiCodeFromeBBlock: %s\n", iLine);
3851 remiCodeFromeBBlock (ebp, dic);
3852 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3853 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3856 static void printSymType(char * str, sym_link *sl)
3858 if(!pic16_ralloc_debug)return;
3860 debugLog (" %s Symbol type: ",str);
3861 printTypeChain (sl, debugF);
3865 /*-----------------------------------------------------------------*/
3866 /* some debug code to print the symbol S_TYPE. Note that
3867 * the function checkSClass in src/SDCCsymt.c dinks with
3868 * the S_TYPE in ways the PIC port doesn't fully like...*/
3869 /*-----------------------------------------------------------------*/
3870 static void isData(sym_link *sl)
3874 if(!pic16_ralloc_debug)return;
3881 for ( ; sl; sl=sl->next) {
3883 switch (SPEC_SCLS(sl)) {
3884 case S_DATA: fprintf (of, "data "); break;
3885 case S_XDATA: fprintf (of, "xdata "); break;
3886 case S_SFR: fprintf (of, "sfr "); break;
3887 case S_SBIT: fprintf (of, "sbit "); break;
3888 case S_CODE: fprintf (of, "code "); break;
3889 case S_IDATA: fprintf (of, "idata "); break;
3890 case S_PDATA: fprintf (of, "pdata "); break;
3891 case S_LITERAL: fprintf (of, "literal "); break;
3892 case S_STACK: fprintf (of, "stack "); break;
3893 case S_XSTACK: fprintf (of, "xstack "); break;
3894 case S_BIT: fprintf (of, "bit "); break;
3895 case S_EEPROM: fprintf (of, "eeprom "); break;
3903 /*--------------------------------------------------------------------*/
3904 /* pic16_packRegisters - does some transformations to reduce */
3905 /* register pressure */
3907 /*--------------------------------------------------------------------*/
3909 pic16_packRegisters (eBBlock * ebp)
3914 debugLog ("%s\n", __FUNCTION__);
3920 /* look for assignments of the form */
3921 /* iTempNN = TRueSym (someoperation) SomeOperand */
3923 /* TrueSym := iTempNN:1 */
3924 for (ic = ebp->sch; ic; ic = ic->next)
3926 // debugLog("%d\n", __LINE__);
3927 /* find assignment of the form TrueSym := iTempNN:1 */
3928 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3929 change += packRegsForAssign (ic, ebp);
3933 if (POINTER_SET (ic))
3934 debugLog ("pointer is set\n");
3935 debugAopGet (" result:", IC_RESULT (ic));
3936 debugAopGet (" left:", IC_LEFT (ic));
3937 debugAopGet (" right:", IC_RIGHT (ic));
3946 for (ic = ebp->sch; ic; ic = ic->next) {
3948 if(IS_SYMOP ( IC_LEFT(ic))) {
3949 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3951 debugAopGet ("x left:", IC_LEFT (ic));
3953 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3955 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3957 debugLog (" is a pointer\n");
3959 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3960 debugLog (" is a ptr\n");
3962 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3963 debugLog (" is volatile\n");
3967 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3968 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3969 pic16_allocDirReg(IC_LEFT (ic));
3972 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3975 if(IS_SYMOP ( IC_RIGHT(ic))) {
3976 debugAopGet (" right:", IC_RIGHT (ic));
3977 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3980 if(IS_SYMOP ( IC_RESULT(ic))) {
3981 debugAopGet (" result:", IC_RESULT (ic));
3982 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3985 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3986 debugAopGet (" right:", IC_RIGHT (ic));
3987 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3988 // pic16_allocDirReg(IC_RIGHT(ic));
3991 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3992 debugAopGet (" result:", IC_RESULT (ic));
3993 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3994 // pic16_allocDirReg(IC_RESULT(ic));
3998 if (POINTER_SET (ic))
3999 debugLog (" %d - Pointer set\n", __LINE__);
4001 /* Look for two subsequent iCodes with */
4003 /* _c = iTemp & op; */
4004 /* and replace them by */
4007 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
4009 && ic->prev->op == '='
4010 && IS_ITEMP (IC_LEFT (ic))
4011 && IC_LEFT (ic) == IC_RESULT (ic->prev)
4012 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
4014 iCode* ic_prev = ic->prev;
4015 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
4017 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
4018 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
4019 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
4020 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
4021 prev_result_sym->liveTo == ic->seq)
4023 prev_result_sym->liveTo = ic_prev->seq;
4026 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
4028 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
4030 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
4031 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
4032 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
4033 remiCodeFromeBBlock (ebp, ic_prev);
4034 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
4038 /* if this is an itemp & result of a address of a true sym
4039 then mark this as rematerialisable */
4040 if (ic->op == ADDRESS_OF &&
4041 IS_ITEMP (IC_RESULT (ic)) &&
4042 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4043 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4044 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4047 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4049 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4050 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4051 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4055 /* if straight assignment then carry remat flag if
4056 this is the only definition */
4057 if (ic->op == '=' &&
4058 !POINTER_SET (ic) &&
4059 IS_SYMOP (IC_RIGHT (ic)) &&
4060 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4061 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4063 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4065 OP_SYMBOL (IC_RESULT (ic))->remat =
4066 OP_SYMBOL (IC_RIGHT (ic))->remat;
4067 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4068 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4071 /* if this is a +/- operation with a rematerizable
4072 then mark this as rematerializable as well */
4073 if ((ic->op == '+' || ic->op == '-') &&
4074 (IS_SYMOP (IC_LEFT (ic)) &&
4075 IS_ITEMP (IC_RESULT (ic)) &&
4076 OP_SYMBOL (IC_LEFT (ic))->remat &&
4077 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4078 IS_OP_LITERAL (IC_RIGHT (ic))))
4080 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4082 operandLitValue (IC_RIGHT (ic));
4083 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4084 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4085 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4090 /* try to optimize FSR0 usage when reading data memory pointers */
4092 if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4093 static int fsr0usage=0;
4096 if(POINTER_GET(ic) /* this is a memory read */
4097 && ic->loop /* this is in a loop */
4099 fprintf(stderr, "might optimize FSR0 usage\n");
4104 /* mark the pointer usages */
4105 if (POINTER_SET (ic))
4107 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4108 debugLog (" marking as a pointer (set) =>");
4109 debugAopGet (" result:", IC_RESULT (ic));
4113 if (POINTER_GET (ic))
4115 if(IS_SYMOP(IC_LEFT(ic))) {
4116 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4117 debugLog (" marking as a pointer (get) =>");
4118 debugAopGet (" left:", IC_LEFT (ic));
4121 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4122 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4123 iCode *dic = ic->prev;
4125 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4127 if(dic && dic->op == '='
4128 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4130 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4133 /* replace prev->left with ic->left */
4134 IC_LEFT(ic) = IC_RIGHT(dic);
4135 IC_RIGHT(ic->prev) = NULL;
4137 /* remove ic->prev iCode (assignment) */
4138 remiCodeFromeBBlock (ebp, dic);
4139 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4142 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4148 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4152 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4153 /* if we are using a symbol on the stack
4154 then we should say pic16_ptrRegReq */
4155 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4156 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4157 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4158 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4159 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4160 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4164 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4165 if (IS_SYMOP (IC_LEFT (ic)))
4166 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4167 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4168 if (IS_SYMOP (IC_RIGHT (ic)))
4169 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4170 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4171 if (IS_SYMOP (IC_RESULT (ic)))
4172 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4173 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4176 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4180 /* if the condition of an if instruction
4181 is defined in the previous instruction then
4182 mark the itemp as a conditional */
4183 if ((IS_CONDITIONAL (ic) ||
4184 ((ic->op == BITWISEAND ||
4187 isBitwiseOptimizable (ic))) &&
4188 ic->next && ic->next->op == IFX &&
4189 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4190 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4193 debugLog (" %d\n", __LINE__);
4194 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4198 debugLog(" %d\n", __LINE__);
4200 #ifndef NO_packRegsForSupport
4201 /* reduce for support function calls */
4202 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4203 packRegsForSupport (ic, ebp);
4206 /* if a parameter is passed, it's in W, so we may not
4207 need to place a copy in a register */
4208 if (ic->op == RECEIVE)
4209 packForReceive (ic, ebp);
4211 #ifndef NO_packRegsForOneuse
4212 /* some cases the redundant moves can
4213 can be eliminated for return statements */
4214 if ((ic->op == RETURN || ic->op == SEND) &&
4215 !isOperandInFarSpace (IC_LEFT (ic)) &&
4217 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4220 #ifndef NO_packRegsForOneuse
4221 /* if pointer set & left has a size more than
4222 one and right is not in far space */
4223 if (POINTER_SET (ic) &&
4224 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4225 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4226 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4227 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4229 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4232 #ifndef NO_packRegsForOneuse
4233 /* if pointer get */
4234 if (POINTER_GET (ic) &&
4235 !isOperandInFarSpace (IC_RESULT (ic)) &&
4236 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4237 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4238 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4240 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4241 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4244 #ifndef NO_cast_peep
4245 /* if this is cast for intergral promotion then
4246 check if only use of the definition of the
4247 operand being casted/ if yes then replace
4248 the result of that arithmetic operation with
4249 this result and get rid of the cast */
4250 if (ic->op == CAST) {
4252 sym_link *fromType = operandType (IC_RIGHT (ic));
4253 sym_link *toType = operandType (IC_LEFT (ic));
4255 debugLog (" %d - casting\n", __LINE__);
4257 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4258 getSize (fromType) != getSize (toType)) {
4261 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4264 if (IS_ARITHMETIC_OP (dic)) {
4265 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4267 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4268 IC_RESULT (dic) = IC_RESULT (ic);
4269 remiCodeFromeBBlock (ebp, ic);
4270 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4271 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4272 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4276 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4280 /* if the type from and type to are the same
4281 then if this is the only use then packit */
4282 if (compareType (operandType (IC_RIGHT (ic)),
4283 operandType (IC_LEFT (ic))) == 1) {
4285 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4288 debugLog(" %d\n", __LINE__);
4290 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4291 IC_RESULT (dic) = IC_RESULT (ic);
4292 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4293 remiCodeFromeBBlock (ebp, ic);
4294 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4295 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4304 /* there are some problems with packing variables
4305 * it seems that the live range estimator doesn't
4306 * estimate correctly the liveranges of some symbols */
4309 iTempNN := (some variable in farspace) V1
4314 if (ic->op == IPUSH)
4316 packForPush (ic, ebp);
4320 #ifndef NO_packRegsForAccUse
4321 /* pack registers for accumulator use, when the
4322 result of an arithmetic or bit wise operation
4323 has only one use, that use is immediately following
4324 the defintion and the using iCode has only one
4325 operand or has two operands but one is literal &
4326 the result of that operation is not on stack then
4327 we can leave the result of this operation in acc:b
4329 if ((IS_ARITHMETIC_OP (ic)
4331 || IS_BITWISE_OP (ic)
4333 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4336 IS_ITEMP (IC_RESULT (ic)) &&
4337 getSize (operandType (IC_RESULT (ic))) <= 1)
4339 packRegsForAccUse (ic);
4346 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4350 if (!pic16_ralloc_debug || !debugF)
4353 for (i = 0; i < count; i++)
4355 fprintf (debugF, "\n----------------------------------------------------------------\n");
4356 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4357 ebbs[i]->entryLabel->name,
4360 ebbs[i]->isLastInLoop);
4361 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4366 fprintf (debugF, "visited %d : hasFcall = %d\n",
4370 fprintf (debugF, "\ndefines bitVector :");
4371 bitVectDebugOn (ebbs[i]->defSet, debugF);
4372 fprintf (debugF, "\nlocal defines bitVector :");
4373 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4374 fprintf (debugF, "\npointers Set bitvector :");
4375 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4376 fprintf (debugF, "\nin pointers Set bitvector :");
4377 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4378 fprintf (debugF, "\ninDefs Set bitvector :");
4379 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4380 fprintf (debugF, "\noutDefs Set bitvector :");
4381 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4382 fprintf (debugF, "\nusesDefs Set bitvector :");
4383 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4384 fprintf (debugF, "\n----------------------------------------------------------------\n");
4385 printiCChain (ebbs[i]->sch, debugF);
4389 void dbg_dumpregusage(void);
4391 /*-----------------------------------------------------------------*/
4392 /* pic16_assignRegisters - assigns registers to each live range as need */
4393 /*-----------------------------------------------------------------*/
4395 pic16_assignRegisters (ebbIndex * ebbi)
4397 eBBlock ** ebbs = ebbi->bbOrder;
4398 int count = ebbi->count;
4402 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4403 debugLog ("\nebbs before optimizing:\n");
4404 dumpEbbsToDebug (ebbs, count);
4406 _inRegAllocator = 1;
4408 pic16_freeAllRegs();
4411 /* clear whats left over from peephole parser */
4412 pic16_dynAllocRegs= newSet(); //NULL;
4413 // pic16_dynStackRegs= newSet(); //NULL;
4414 // pic16_dynProcessorRegs=newSet(); //NULL;
4415 // pic16_dynDirectRegs=newSet(); //NULL;
4416 // pic16_dynDirectBitRegs=newSet(); //NULL;
4417 // pic16_dynInternalRegs=newSet(); //NULL;
4418 // pic16_dynAccessRegs=newSet(); //NULL;
4420 // dynDirectRegNames=NULL;
4421 dynAllocRegNames=NULL;
4422 // dynProcRegNames=NULL;
4423 // dynAccessRegNames=NULL;
4426 setToNull ((void *) &_G.funcrUsed);
4427 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4430 /* change assignments this will remove some
4431 live ranges reducing some register pressure */
4432 for (i = 0; i < count; i++)
4433 pic16_packRegisters (ebbs[i]);
4440 debugLog("dir registers allocated so far:\n");
4441 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4445 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4446 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4447 reg = hTabNextItem(dynDirectRegNames, &hkey);
4453 /* liveranges probably changed by register packing
4454 so we compute them again */
4455 recomputeLiveRanges (ebbs, count);
4457 if (options.dump_pack)
4458 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4460 /* first determine for each live range the number of
4461 registers & the type of registers required for each */
4464 /* start counting function temporary registers from zero */
4465 /* XXX: Resetting dynrIdx breaks register allocation,
4466 * see #1489055, #1483693 (?), and #1445850! */
4469 /* and serially allocate registers */
4470 serialRegAssign (ebbs, count);
4473 debugLog ("ebbs after serialRegAssign:\n");
4474 dumpEbbsToDebug (ebbs, count);
4477 //pic16_freeAllRegs();
4479 /* if stack was extended then tell the user */
4482 /* werror(W_TOOMANY_SPILS,"stack", */
4483 /* _G.stackExtend,currFunc->name,""); */
4489 /* werror(W_TOOMANY_SPILS,"data space", */
4490 /* _G.dataExtend,currFunc->name,""); */
4494 /* after that create the register mask
4495 for each of the instruction */
4496 createRegMask (ebbs, count);
4498 /* redo that offsets for stacked automatic variables */
4499 redoStackOffsets ();
4501 if (options.dump_rassgn)
4502 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4504 // dumpLR(ebbs, count);
4506 /* now get back the chain */
4507 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4509 debugLog ("ebbs after optimizing:\n");
4510 dumpEbbsToDebug (ebbs, count);
4513 _inRegAllocator = 0;
4517 /* free up any _G.stackSpil locations allocated */
4518 applyToSet (_G.stackSpil, deallocStackSpil);
4520 setToNull ((void *) &_G.stackSpil);
4521 setToNull ((void *) &_G.spiltSet);
4522 /* mark all registers as free */
4523 pic16_freeAllRegs ();
4526 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");