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(pic16_options.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 *-----------------------------------------------------------------*/
497 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
499 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
501 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
503 reg->wasUsed = 0; // we do not know if they are going to be used at all
504 reg->accessBank = 1; // implicit add access Bank
506 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
508 return addSet(&pic16_dynProcessorRegs, reg);
511 /*-----------------------------------------------------------------*
512 *-----------------------------------------------------------------*/
515 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
517 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
519 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
523 return addSet(&pic16_dynInternalRegs,reg);
530 /*-----------------------------------------------------------------*/
531 /* allocReg - allocates register of given type */
532 /*-----------------------------------------------------------------*/
534 allocReg (short type)
538 #define MAX_P16_NREGS 16
542 if(dynrIdx > pic16_nRegs)
543 werror(W_POSSBUG2, __FILE__, __LINE__);
547 /* try to reuse some unused registers */
548 reg = regFindFree( pic16_dynAllocRegs );
551 // fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
555 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
556 // fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
557 // (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
560 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
561 // debugf("allocating more registers than available\n", 0);
565 addSet(&pic16_dynAllocRegs, reg);
566 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
567 // fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
571 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
574 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
575 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
579 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
580 reg->isLocal = 1; /* this is a local frame register */
585 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
586 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
589 return (reg); // addSet(&pic16_dynAllocRegs,reg);
594 /*-----------------------------------------------------------------*/
595 /* pic16_dirregWithName - search for register by name */
596 /*-----------------------------------------------------------------*/
598 pic16_dirregWithName (char *name)
606 /* hash the name to get a key */
608 hkey = regname2key(name);
610 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
612 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
616 if(STRCASECMP(reg->name, name) == 0) {
617 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
621 reg = hTabNextItemWK (dynDirectRegNames);
625 return NULL; // name wasn't found in the hash table
628 /*-----------------------------------------------------------------*/
629 /* pic16_allocregWithName - search for register by name */
630 /*-----------------------------------------------------------------*/
632 pic16_allocregWithName (char *name)
640 /* hash the name to get a key */
642 hkey = regname2key(name);
644 //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
646 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
650 if(STRCASECMP(reg->name, name) == 0) {
654 reg = hTabNextItemWK (dynAllocRegNames);
658 return NULL; // name wasn't found in the hash table
663 /*-----------------------------------------------------------------*/
664 /* pic16_procregWithName - search for register by name */
665 /*-----------------------------------------------------------------*/
667 pic16_procregWithName (char *name)
675 /* hash the name to get a key */
677 hkey = regname2key(name);
679 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
681 reg = hTabFirstItemWK(dynProcRegNames, hkey);
685 if(STRCASECMP(reg->name, name) == 0) {
689 reg = hTabNextItemWK (dynProcRegNames);
693 return NULL; // name wasn't found in the hash table
697 /*-----------------------------------------------------------------*/
698 /* pic16_accessregWithName - search for register by name */
699 /*-----------------------------------------------------------------*/
701 pic16_accessregWithName (char *name)
709 /* hash the name to get a key */
711 hkey = regname2key(name);
713 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
715 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
719 if(STRCASECMP(reg->name, name) == 0) {
723 reg = hTabNextItemWK (dynAccessRegNames);
727 return NULL; // name wasn't found in the hash table
731 regs *pic16_regWithName(char *name)
735 reg = pic16_dirregWithName( name );
738 reg = pic16_procregWithName( name );
741 reg = pic16_allocregWithName( name );
744 reg = pic16_accessregWithName( name );
751 /*-----------------------------------------------------------------*/
752 /* pic16_allocDirReg - allocates register of given type */
753 /*-----------------------------------------------------------------*/
755 pic16_allocDirReg (operand *op )
761 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
762 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
766 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
769 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
771 if(pic16_debug_verbose)
773 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
774 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
780 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
781 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
784 if(pic16_debug_verbose) {
785 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
786 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
787 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
788 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
789 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
790 IN_STACK( OP_SYM_ETYPE(op)),
791 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
792 IS_REGPARM(OP_SYM_ETYPE(op)),
795 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
796 OP_SYMBOL(op)->name);
804 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
805 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
809 if(IS_ITEMP(op))return NULL;
811 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
813 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
815 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
816 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
819 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
820 debugLog(" %d const char\n",__LINE__);
821 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
822 // fprintf(stderr, " %d const char\n",__LINE__);
823 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
827 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
828 if (IS_CODE ( OP_SYM_ETYPE(op)) )
829 debugLog(" %d code space\n",__LINE__);
831 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
832 debugLog(" %d integral\n",__LINE__);
834 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
835 debugLog(" %d literal\n",__LINE__);
837 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
838 debugLog(" %d specifier\n",__LINE__);
840 debugAopGet(NULL, op);
844 reg = pic16_dirregWithName(name);
848 int regtype = REG_GPR;
850 /* if this is at an absolute address, then get the address. */
851 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
852 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
853 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
856 /* Register wasn't found in hash, so let's create
857 * a new one and put it in the hash table AND in the
858 * dynDirectRegNames set */
859 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
860 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
866 if(OP_SYMBOL(op)->onStack) {
867 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
868 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
872 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
873 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
876 if(pic16_debug_verbose)
878 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
879 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
880 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
881 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
882 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
883 IN_STACK( OP_SYM_ETYPE(op)),
884 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
886 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
887 OP_SYMBOL(op)->name);
892 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
893 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
895 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
896 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
900 checkAddReg(&pic16_dynAccessRegs, reg);
901 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
907 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
908 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
909 // reg->type = REG_SFR;
912 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
913 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
914 addSet(&pic16_dynDirectBitRegs, reg);
917 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
918 // addSet(&pic16_dynDirectRegs, reg);
921 if(!(IS_STATIC(OP_SYM_ETYPE(op))
922 && OP_SYMBOL(op)->ival
925 checkAddReg(&pic16_dynDirectRegs, reg);
929 // debugLog (" -- %s is declared at address 0x30000x\n",name);
930 return (reg); /* This was NULL before, but since we found it
931 * why not just return it?! */
934 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
936 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
938 /* work around for user defined registers in access bank */
939 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
940 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
943 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
949 /*-----------------------------------------------------------------*/
950 /* pic16_allocRegByName - allocates register of given type */
951 /*-----------------------------------------------------------------*/
953 pic16_allocRegByName (char *name, int size, operand *op)
959 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
963 /* First, search the hash table to see if there is a register with this name */
964 reg = pic16_dirregWithName(name);
968 /* Register wasn't found in hash, so let's create
969 * a new one and put it in the hash table AND in the
970 * dynDirectRegNames set */
972 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
974 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
976 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
977 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
979 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
980 addSet(&pic16_dynDirectRegs, reg);
986 /*-----------------------------------------------------------------*/
987 /* RegWithIdx - returns pointer to register with index number */
988 /*-----------------------------------------------------------------*/
989 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
994 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
995 // fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
1000 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
1002 debugLog ("Found a Dynamic Register!\n");
1005 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
1006 debugLog ("Found a Direct Register!\n");
1010 if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
1011 debugLog ("Found an Internal Register!\n");
1017 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1018 debugLog ("Found a Stack Register!\n");
1023 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1024 debugLog ("Found a Processor Register!\n");
1038 /*-----------------------------------------------------------------*/
1039 /* pic16_regWithIdx - returns pointer to register with index number*/
1040 /*-----------------------------------------------------------------*/
1042 pic16_regWithIdx (int idx)
1046 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1049 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1053 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1060 /*-----------------------------------------------------------------*/
1061 /* pic16_regWithIdx - returns pointer to register with index number */
1062 /*-----------------------------------------------------------------*/
1064 pic16_allocWithIdx (int idx)
1069 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1070 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1072 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1074 debugLog ("Found a Dynamic Register!\n");
1075 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1076 debugLog ("Found a Stack Register!\n");
1077 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1078 debugLog ("Found a Processor Register!\n");
1079 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1080 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1081 debugLog ("Found an Internal Register!\n");
1084 debugLog ("Dynamic Register not found\n");
1087 dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
1088 addSet(&pic16_dynAllocRegs, dReg);
1089 hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
1094 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1095 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1096 "allocWithIdx not found");
1106 /*-----------------------------------------------------------------*/
1107 /*-----------------------------------------------------------------*/
1109 pic16_findFreeReg(short type)
1116 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1118 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1119 return allocReg( REG_GPR );
1123 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1137 pic16_findFreeRegNext(short type, regs *creg)
1144 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1146 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1147 return (allocReg( REG_GPR ) );
1151 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1163 /*-----------------------------------------------------------------*/
1164 /* freeReg - frees a register */
1165 /*-----------------------------------------------------------------*/
1167 freeReg (regs * reg)
1169 debugLog ("%s\n", __FUNCTION__);
1170 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1175 /*-----------------------------------------------------------------*/
1176 /* nFreeRegs - returns number of free registers */
1177 /*-----------------------------------------------------------------*/
1179 nFreeRegs (int type)
1185 /* although I fixed the register allocation/freeing scheme
1186 * the for loop below doesn't give valid results. I do not
1187 * know why yet. -- VR 10-Jan-2003 */
1192 /* dynamically allocate as many as we need and worry about
1193 * fitting them into a PIC later */
1195 debugLog ("%s\n", __FUNCTION__);
1197 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1198 if((reg->type == type) && reg->isFree)nfr++;
1200 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1204 /*-----------------------------------------------------------------*/
1205 /* nfreeRegsType - free registers with type */
1206 /*-----------------------------------------------------------------*/
1208 nfreeRegsType (int type)
1211 debugLog ("%s\n", __FUNCTION__);
1212 if (type == REG_PTR)
1214 if ((nfr = nFreeRegs (type)) == 0)
1215 return nFreeRegs (REG_GPR);
1218 return nFreeRegs (type);
1221 static void writeSetUsedRegs(FILE *of, set *dRegs)
1226 for (dReg = setFirstItem(dRegs) ; dReg ;
1227 dReg = setNextItem(dRegs)) {
1230 fprintf (of, "\t%s\n",dReg->name);
1236 extern void pic16_groupRegistersInSection(set *regset);
1238 extern void pic16_dump_equates(FILE *of, set *equs);
1239 extern void pic16_dump_access(FILE *of, set *section);
1240 //extern void pic16_dump_map(void);
1241 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1242 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1243 extern void pic16_dump_int_registers(FILE *of, set *section);
1244 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1246 extern void pic16_dump_gsection(FILE *of, set *sections);
1248 static void packBits(set *bregs)
1252 regs *bitfield=NULL;
1253 regs *relocbitfield=NULL;
1259 for (regset = bregs ; regset ;
1260 regset = regset->next) {
1262 breg = regset->item;
1263 breg->isBitField = 1;
1264 //fprintf(stderr,"bit reg: %s\n",breg->name);
1267 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1269 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1270 breg->rIdx = breg->address & 7;
1271 breg->address >>= 3;
1274 sprintf (buffer, "fbitfield%02x", breg->address);
1275 //fprintf(stderr,"new bit field\n");
1276 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1277 bitfield->isBitField = 1;
1278 bitfield->isFixed = 1;
1279 bitfield->address = breg->address;
1280 addSet(&pic16_dynDirectRegs,bitfield);
1281 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1283 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1286 breg->reg_alias = bitfield;
1290 if(!relocbitfield || bit_no >7) {
1293 sprintf (buffer, "bitfield%d", byte_no);
1294 //fprintf(stderr,"new relocatable bit field\n");
1295 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1296 relocbitfield->isBitField = 1;
1297 addSet(&pic16_dynDirectRegs,relocbitfield);
1298 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1302 breg->reg_alias = relocbitfield;
1303 breg->address = rDirectIdx; /* byte_no; */
1304 breg->rIdx = bit_no++;
1310 void pic16_writeUsedRegs(FILE *of)
1312 packBits(pic16_dynDirectBitRegs);
1314 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1315 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1316 pic16_groupRegistersInSection(pic16_dynStackRegs);
1317 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1318 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1319 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1320 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1323 pic16_dump_equates(of, pic16_equ_data);
1325 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1326 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1328 /* dump access bank symbols */
1329 pic16_dump_access(of, pic16_acs_udata);
1331 /* dump initialised data */
1332 pic16_dump_isection(of, rel_idataSymSet, 0);
1333 pic16_dump_isection(of, fix_idataSymSet, 1);
1335 if(!pic16_options.xinst) {
1336 /* dump internal registers */
1337 pic16_dump_int_registers(of, pic16_int_regs);
1340 /* dump generic section variables */
1341 pic16_dump_gsection(of, sectNames);
1343 /* dump other variables */
1344 pic16_dump_usection(of, pic16_rel_udata, 0);
1345 pic16_dump_usection(of, pic16_fix_udata, 1);
1349 /*-----------------------------------------------------------------*/
1350 /* computeSpillable - given a point find the spillable live ranges */
1351 /*-----------------------------------------------------------------*/
1353 computeSpillable (iCode * ic)
1357 debugLog ("%s\n", __FUNCTION__);
1358 /* spillable live ranges are those that are live at this
1359 point . the following categories need to be subtracted
1361 a) - those that are already spilt
1362 b) - if being used by this one
1363 c) - defined by this one */
1365 spillable = bitVectCopy (ic->rlive);
1367 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1369 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1370 bitVectUnSetBit (spillable, ic->defKey);
1371 spillable = bitVectIntersect (spillable, _G.regAssigned);
1376 /*-----------------------------------------------------------------*/
1377 /* noSpilLoc - return true if a variable has no spil location */
1378 /*-----------------------------------------------------------------*/
1380 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1382 debugLog ("%s\n", __FUNCTION__);
1383 return (sym->usl.spillLoc ? 0 : 1);
1386 /*-----------------------------------------------------------------*/
1387 /* hasSpilLoc - will return 1 if the symbol has spil location */
1388 /*-----------------------------------------------------------------*/
1390 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1392 debugLog ("%s\n", __FUNCTION__);
1393 return (sym->usl.spillLoc ? 1 : 0);
1396 /*-----------------------------------------------------------------*/
1397 /* directSpilLoc - will return 1 if the splilocation is in direct */
1398 /*-----------------------------------------------------------------*/
1400 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1402 debugLog ("%s\n", __FUNCTION__);
1403 if (sym->usl.spillLoc &&
1404 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1410 /*-----------------------------------------------------------------*/
1411 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1412 /* but is not used as a pointer */
1413 /*-----------------------------------------------------------------*/
1415 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1417 debugLog ("%s\n", __FUNCTION__);
1418 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1421 /*-----------------------------------------------------------------*/
1422 /* rematable - will return 1 if the remat flag is set */
1423 /*-----------------------------------------------------------------*/
1425 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1427 debugLog ("%s\n", __FUNCTION__);
1431 /*-----------------------------------------------------------------*/
1432 /* notUsedInRemaining - not used or defined in remain of the block */
1433 /*-----------------------------------------------------------------*/
1435 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1437 debugLog ("%s\n", __FUNCTION__);
1438 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1439 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1442 /*-----------------------------------------------------------------*/
1443 /* allLRs - return true for all */
1444 /*-----------------------------------------------------------------*/
1446 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1448 debugLog ("%s\n", __FUNCTION__);
1452 /*-----------------------------------------------------------------*/
1453 /* liveRangesWith - applies function to a given set of live range */
1454 /*-----------------------------------------------------------------*/
1456 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1457 eBBlock * ebp, iCode * ic)
1462 debugLog ("%s\n", __FUNCTION__);
1463 if (!lrs || !lrs->size)
1466 for (i = 1; i < lrs->size; i++)
1469 if (!bitVectBitValue (lrs, i))
1472 /* if we don't find it in the live range
1473 hash table we are in serious trouble */
1474 if (!(sym = hTabItemWithKey (liveRanges, i)))
1476 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1477 "liveRangesWith could not find liveRange");
1481 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1482 addSetHead (&rset, sym);
1489 /*-----------------------------------------------------------------*/
1490 /* leastUsedLR - given a set determines which is the least used */
1491 /*-----------------------------------------------------------------*/
1493 leastUsedLR (set * sset)
1495 symbol *sym = NULL, *lsym = NULL;
1497 debugLog ("%s\n", __FUNCTION__);
1498 sym = lsym = setFirstItem (sset);
1503 for (; lsym; lsym = setNextItem (sset))
1506 /* if usage is the same then prefer
1507 the spill the smaller of the two */
1508 if (lsym->used == sym->used)
1509 if (getSize (lsym->type) < getSize (sym->type))
1513 if (lsym->used < sym->used)
1518 setToNull ((void *) &sset);
1523 /*-----------------------------------------------------------------*/
1524 /* noOverLap - will iterate through the list looking for over lap */
1525 /*-----------------------------------------------------------------*/
1527 noOverLap (set * itmpStack, symbol * fsym)
1530 debugLog ("%s\n", __FUNCTION__);
1533 for (sym = setFirstItem (itmpStack); sym;
1534 sym = setNextItem (itmpStack))
1536 if (sym->liveTo > fsym->liveFrom)
1544 /*-----------------------------------------------------------------*/
1545 /* isFree - will return 1 if the a free spil location is found */
1546 /*-----------------------------------------------------------------*/
1551 V_ARG (symbol **, sloc);
1552 V_ARG (symbol *, fsym);
1554 debugLog ("%s\n", __FUNCTION__);
1555 /* if already found */
1559 /* if it is free && and the itmp assigned to
1560 this does not have any overlapping live ranges
1561 with the one currently being assigned and
1562 the size can be accomodated */
1564 noOverLap (sym->usl.itmpStack, fsym) &&
1565 getSize (sym->type) >= getSize (fsym->type))
1574 /*-----------------------------------------------------------------*/
1575 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1576 /*-----------------------------------------------------------------*/
1578 spillLRWithPtrReg (symbol * forSym)
1584 debugLog ("%s\n", __FUNCTION__);
1585 if (!_G.regAssigned ||
1586 bitVectIsZero (_G.regAssigned))
1589 r0 = pic16_regWithIdx (R0_IDX);
1590 r1 = pic16_regWithIdx (R1_IDX);
1592 /* for all live ranges */
1593 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1594 lrsym = hTabNextItem (liveRanges, &k))
1598 /* if no registers assigned to it or
1600 /* if it does not overlap with this then
1601 not need to spill it */
1603 if (lrsym->isspilt || !lrsym->nRegs ||
1604 (lrsym->liveTo < forSym->liveFrom))
1607 /* go thru the registers : if it is either
1608 r0 or r1 then spil it */
1609 for (j = 0; j < lrsym->nRegs; j++)
1610 if (lrsym->regs[j] == r0 ||
1611 lrsym->regs[j] == r1)
1620 /*-----------------------------------------------------------------*/
1621 /* createStackSpil - create a location on the stack to spil */
1622 /*-----------------------------------------------------------------*/
1624 createStackSpil (symbol * sym)
1626 symbol *sloc = NULL;
1627 int useXstack, model, noOverlay;
1629 char slocBuffer[30];
1630 debugLog ("%s\n", __FUNCTION__);
1632 /* first go try and find a free one that is already
1633 existing on the stack */
1634 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1636 /* found a free one : just update & return */
1637 sym->usl.spillLoc = sloc;
1640 addSetHead (&sloc->usl.itmpStack, sym);
1644 /* could not then have to create one , this is the hard part
1645 we need to allocate this on the stack : this is really a
1646 hack!! but cannot think of anything better at this time */
1648 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1650 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1651 __FILE__, __LINE__);
1655 sloc = newiTemp (slocBuffer);
1657 /* set the type to the spilling symbol */
1658 sloc->type = copyLinkChain (sym->type);
1659 sloc->etype = getSpec (sloc->type);
1660 SPEC_SCLS (sloc->etype) = S_DATA;
1661 SPEC_EXTR (sloc->etype) = 0;
1662 SPEC_STAT (sloc->etype) = 0;
1664 /* we don't allow it to be allocated`
1665 onto the external stack since : so we
1666 temporarily turn it off ; we also
1667 turn off memory model to prevent
1668 the spil from going to the external storage
1669 and turn off overlaying
1672 useXstack = options.useXstack;
1673 model = options.model;
1674 noOverlay = options.noOverlay;
1675 options.noOverlay = 1;
1676 options.model = options.useXstack = 0;
1680 options.useXstack = useXstack;
1681 options.model = model;
1682 options.noOverlay = noOverlay;
1683 sloc->isref = 1; /* to prevent compiler warning */
1685 /* if it is on the stack then update the stack */
1686 if (IN_STACK (sloc->etype))
1688 currFunc->stack += getSize (sloc->type);
1689 _G.stackExtend += getSize (sloc->type);
1692 _G.dataExtend += getSize (sloc->type);
1694 /* add it to the _G.stackSpil set */
1695 addSetHead (&_G.stackSpil, sloc);
1696 sym->usl.spillLoc = sloc;
1699 /* add it to the set of itempStack set
1700 of the spill location */
1701 addSetHead (&sloc->usl.itmpStack, sym);
1705 /*-----------------------------------------------------------------*/
1706 /* isSpiltOnStack - returns true if the spil location is on stack */
1707 /*-----------------------------------------------------------------*/
1709 isSpiltOnStack (symbol * sym)
1713 debugLog ("%s\n", __FUNCTION__);
1720 /* if (sym->_G.stackSpil) */
1723 if (!sym->usl.spillLoc)
1726 etype = getSpec (sym->usl.spillLoc->type);
1727 if (IN_STACK (etype))
1733 /*-----------------------------------------------------------------*/
1734 /* spillThis - spils a specific operand */
1735 /*-----------------------------------------------------------------*/
1737 spillThis (symbol * sym)
1740 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1742 /* if this is rematerializable or has a spillLocation
1743 we are okay, else we need to create a spillLocation
1745 if (!(sym->remat || sym->usl.spillLoc))
1746 createStackSpil (sym);
1749 /* mark it has spilt & put it in the spilt set */
1751 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1753 bitVectUnSetBit (_G.regAssigned, sym->key);
1755 for (i = 0; i < sym->nRegs; i++)
1759 freeReg (sym->regs[i]);
1760 sym->regs[i] = NULL;
1763 /* if spilt on stack then free up r0 & r1
1764 if they could have been assigned to some
1766 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1769 spillLRWithPtrReg (sym);
1772 if (sym->usl.spillLoc && !sym->remat)
1773 sym->usl.spillLoc->allocreq = 1;
1777 /*-----------------------------------------------------------------*/
1778 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1779 /*-----------------------------------------------------------------*/
1781 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1783 bitVect *lrcs = NULL;
1787 debugLog ("%s\n", __FUNCTION__);
1788 /* get the spillable live ranges */
1789 lrcs = computeSpillable (ic);
1791 /* get all live ranges that are rematerizable */
1792 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1795 /* return the least used of these */
1796 return leastUsedLR (selectS);
1799 /* get live ranges with spillLocations in direct space */
1800 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1802 sym = leastUsedLR (selectS);
1803 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1804 sym->usl.spillLoc->rname :
1805 sym->usl.spillLoc->name));
1807 /* mark it as allocation required */
1808 sym->usl.spillLoc->allocreq = 1;
1812 /* if the symbol is local to the block then */
1813 if (forSym->liveTo < ebp->lSeq)
1816 /* check if there are any live ranges allocated
1817 to registers that are not used in this block */
1818 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1820 sym = leastUsedLR (selectS);
1821 /* if this is not rematerializable */
1830 /* check if there are any live ranges that not
1831 used in the remainder of the block */
1832 if (!_G.blockSpil &&
1833 !isiCodeInFunctionCall (ic) &&
1834 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1836 sym = leastUsedLR (selectS);
1839 sym->remainSpil = 1;
1846 /* find live ranges with spillocation && not used as pointers */
1847 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1850 sym = leastUsedLR (selectS);
1851 /* mark this as allocation required */
1852 sym->usl.spillLoc->allocreq = 1;
1856 /* find live ranges with spillocation */
1857 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1860 sym = leastUsedLR (selectS);
1861 sym->usl.spillLoc->allocreq = 1;
1865 /* couldn't find then we need to create a spil
1866 location on the stack , for which one? the least
1868 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1871 /* return a created spil location */
1872 sym = createStackSpil (leastUsedLR (selectS));
1873 sym->usl.spillLoc->allocreq = 1;
1877 /* this is an extreme situation we will spill
1878 this one : happens very rarely but it does happen */
1884 /*-----------------------------------------------------------------*/
1885 /* spilSomething - spil some variable & mark registers as free */
1886 /*-----------------------------------------------------------------*/
1888 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1893 debugLog ("%s\n", __FUNCTION__);
1894 /* get something we can spil */
1895 ssym = selectSpil (ic, ebp, forSym);
1897 /* mark it as spilt */
1899 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1901 /* mark it as not register assigned &
1902 take it away from the set */
1903 bitVectUnSetBit (_G.regAssigned, ssym->key);
1905 /* mark the registers as free */
1906 for (i = 0; i < ssym->nRegs; i++)
1908 freeReg (ssym->regs[i]);
1910 /* if spilt on stack then free up r0 & r1
1911 if they could have been assigned to as gprs */
1912 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1915 spillLRWithPtrReg (ssym);
1918 /* if this was a block level spil then insert push & pop
1919 at the start & end of block respectively */
1920 if (ssym->blockSpil)
1922 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1923 /* add push to the start of the block */
1924 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1925 ebp->sch->next : ebp->sch));
1926 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1927 /* add pop to the end of the block */
1928 addiCodeToeBBlock (ebp, nic, NULL);
1931 /* if spilt because not used in the remainder of the
1932 block then add a push before this instruction and
1933 a pop at the end of the block */
1934 if (ssym->remainSpil)
1937 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1938 /* add push just before this instruction */
1939 addiCodeToeBBlock (ebp, nic, ic);
1941 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1942 /* add pop to the end of the block */
1943 addiCodeToeBBlock (ebp, nic, NULL);
1952 /*-----------------------------------------------------------------*/
1953 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1954 /*-----------------------------------------------------------------*/
1956 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1961 debugLog ("%s\n", __FUNCTION__);
1963 /* try for a ptr type */
1964 if ((reg = allocReg (REG_PTR)))
1967 /* try for gpr type */
1968 if ((reg = allocReg (REG_GPR)))
1971 /* we have to spil */
1972 if (!spilSomething (ic, ebp, sym))
1975 /* make sure partially assigned registers aren't reused */
1976 for (j=0; j<=sym->nRegs; j++)
1978 sym->regs[j]->isFree = 0;
1980 /* this looks like an infinite loop but
1981 in really selectSpil will abort */
1985 /*-----------------------------------------------------------------*/
1986 /* getRegGpr - will try for GPR if not spil */
1987 /*-----------------------------------------------------------------*/
1989 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1994 debugLog ("%s\n", __FUNCTION__);
1996 /* try for gpr type */
1997 if ((reg = allocReg (REG_GPR)))
2000 if (!pic16_ptrRegReq)
2001 if ((reg = allocReg (REG_PTR)))
2004 /* we have to spil */
2005 if (!spilSomething (ic, ebp, sym))
2008 /* make sure partially assigned registers aren't reused */
2009 for (j=0; j<=sym->nRegs; j++)
2011 sym->regs[j]->isFree = 0;
2013 /* this looks like an infinite loop but
2014 in really selectSpil will abort */
2018 /*-----------------------------------------------------------------*/
2019 /* symHasReg - symbol has a given register */
2020 /*-----------------------------------------------------------------*/
2022 symHasReg (symbol * sym, regs * reg)
2026 debugLog ("%s\n", __FUNCTION__);
2027 for (i = 0; i < sym->nRegs; i++)
2028 if (sym->regs[i] == reg)
2034 /*-----------------------------------------------------------------*/
2035 /* deassignLRs - check the live to and if they have registers & are */
2036 /* not spilt then free up the registers */
2037 /*-----------------------------------------------------------------*/
2039 deassignLRs (iCode * ic, eBBlock * ebp)
2045 debugLog ("%s\n", __FUNCTION__);
2046 for (sym = hTabFirstItem (liveRanges, &k); sym;
2047 sym = hTabNextItem (liveRanges, &k))
2050 symbol *psym = NULL;
2051 /* if it does not end here */
2052 if (sym->liveTo > ic->seq)
2055 /* if it was spilt on stack then we can
2056 mark the stack spil location as free */
2061 sym->usl.spillLoc->isFree = 1;
2067 if (!bitVectBitValue (_G.regAssigned, sym->key))
2070 /* special case for shifting: there is a case where shift count
2071 * can be allocated in the same register as the result, so do not
2072 * free right registers if same as result registers, cause genShiftLeft
2073 * will fail -- VR */
2074 if(ic->op == LEFT_OP)
2077 /* special case check if this is an IFX &
2078 the privious one was a pop and the
2079 previous one was not spilt then keep track
2081 if (ic->op == IFX && ic->prev &&
2082 ic->prev->op == IPOP &&
2083 !ic->prev->parmPush &&
2084 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2085 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2091 bitVectUnSetBit (_G.regAssigned, sym->key);
2093 /* if the result of this one needs registers
2094 and does not have it then assign it right
2096 if (IC_RESULT (ic) &&
2097 !(SKIP_IC2 (ic) || /* not a special icode */
2098 ic->op == JUMPTABLE ||
2103 POINTER_SET (ic)) &&
2104 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2105 result->liveTo > ic->seq && /* and will live beyond this */
2106 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2107 result->liveFrom == ic->seq && /* does not start before here */
2108 result->regType == sym->regType && /* same register types */
2109 result->nRegs && /* which needs registers */
2110 !result->isspilt && /* and does not already have them */
2112 !bitVectBitValue (_G.regAssigned, result->key) &&
2113 /* the number of free regs + number of regs in this LR
2114 can accomodate the what result Needs */
2115 ((nfreeRegsType (result->regType) +
2116 sym->nRegs) >= result->nRegs)
2121 // for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2122 /* the above does not free the unsued registers in sym,
2123 * leaving them marked as used, and increasing register usage
2124 * until the end of the function - VR 23/11/05 */
2126 for (i = 0; i < result->nRegs; i++)
2128 result->regs[i] = sym->regs[i];
2130 result->regs[i] = getRegGpr (ic, ebp, result);
2132 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2135 /* free the remaining */
2136 for (; i < sym->nRegs; i++)
2140 if (!symHasReg (psym, sym->regs[i]))
2141 freeReg (sym->regs[i]);
2144 freeReg (sym->regs[i]);
2151 /*-----------------------------------------------------------------*/
2152 /* reassignLR - reassign this to registers */
2153 /*-----------------------------------------------------------------*/
2155 reassignLR (operand * op)
2157 symbol *sym = OP_SYMBOL (op);
2160 debugLog ("%s\n", __FUNCTION__);
2161 /* not spilt any more */
2162 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2163 bitVectUnSetBit (_G.spiltSet, sym->key);
2165 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2169 for (i = 0; i < sym->nRegs; i++)
2170 sym->regs[i]->isFree = 0;
2173 /*-----------------------------------------------------------------*/
2174 /* willCauseSpill - determines if allocating will cause a spill */
2175 /*-----------------------------------------------------------------*/
2177 willCauseSpill (int nr, int rt)
2179 debugLog ("%s\n", __FUNCTION__);
2180 /* first check if there are any avlb registers
2181 of te type required */
2184 /* special case for pointer type
2185 if pointer type not avlb then
2186 check for type gpr */
2187 if (nFreeRegs (rt) >= nr)
2189 if (nFreeRegs (REG_GPR) >= nr)
2194 if (pic16_ptrRegReq)
2196 if (nFreeRegs (rt) >= nr)
2201 if (nFreeRegs (REG_PTR) +
2202 nFreeRegs (REG_GPR) >= nr)
2207 debugLog (" ... yep it will (cause a spill)\n");
2208 /* it will cause a spil */
2212 /*-----------------------------------------------------------------*/
2213 /* positionRegs - the allocator can allocate same registers to res- */
2214 /* ult and operand, if this happens make sure they are in the same */
2215 /* position as the operand otherwise chaos results */
2216 /*-----------------------------------------------------------------*/
2218 positionRegs (symbol * result, symbol * opsym, int lineno)
2220 int count = min (result->nRegs, opsym->nRegs);
2221 int i, j = 0, shared = 0;
2223 debugLog ("%s\n", __FUNCTION__);
2224 /* if the result has been spilt then cannot share */
2229 /* first make sure that they actually share */
2230 for (i = 0; i < count; i++)
2232 for (j = 0; j < count; j++)
2234 if (result->regs[i] == opsym->regs[j] && i != j)
2244 regs *tmp = result->regs[i];
2245 result->regs[i] = result->regs[j];
2246 result->regs[j] = tmp;
2251 /*------------------------------------------------------------------*/
2252 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2253 /* it should either have registers or have beed spilled. Otherwise, */
2254 /* there was an uninitialized variable, so just spill this to get */
2255 /* the operand in a valid state. */
2256 /*------------------------------------------------------------------*/
2258 verifyRegsAssigned (operand *op, iCode * ic)
2263 if (!IS_ITEMP (op)) return;
2265 sym = OP_SYMBOL (op);
2266 if (sym->isspilt) return;
2267 if (!sym->nRegs) return;
2268 if (sym->regs[0]) return;
2270 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2271 sym->prereqv ? sym->prereqv->name : sym->name);
2276 /*-----------------------------------------------------------------*/
2277 /* serialRegAssign - serially allocate registers to the variables */
2278 /*-----------------------------------------------------------------*/
2280 serialRegAssign (eBBlock ** ebbs, int count)
2285 debugLog ("%s\n", __FUNCTION__);
2286 /* for all blocks */
2287 for (i = 0; i < count; i++)
2289 if (ebbs[i]->noPath &&
2290 (ebbs[i]->entryLabel != entryLabel &&
2291 ebbs[i]->entryLabel != returnLabel))
2294 /* of all instructions do */
2295 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2298 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2300 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2301 pic16_allocDirReg(IC_RESULT(ic));
2303 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2304 pic16_allocDirReg(IC_LEFT(ic));
2306 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2307 pic16_allocDirReg(IC_RIGHT(ic));
2309 /* if this is an ipop that means some live
2310 range will have to be assigned again */
2312 reassignLR (IC_LEFT (ic));
2314 /* if result is present && is a true symbol */
2315 if (IC_RESULT (ic) && ic->op != IFX &&
2316 IS_TRUE_SYMOP (IC_RESULT (ic)))
2317 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2319 /* take away registers from live
2320 ranges that end at this instruction */
2321 deassignLRs (ic, ebbs[i]);
2323 /* some don't need registers */
2324 if (SKIP_IC2 (ic) ||
2325 ic->op == JUMPTABLE ||
2329 (IC_RESULT (ic) && POINTER_SET (ic)))
2332 /* now we need to allocate registers
2333 only for the result */
2336 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2342 /* Make sure any spill location is definately allocated */
2343 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2344 !sym->usl.spillLoc->allocreq)
2346 sym->usl.spillLoc->allocreq++;
2349 /* if it does not need or is spilt
2350 or is already assigned to registers
2351 or will not live beyond this instructions */
2354 bitVectBitValue (_G.regAssigned, sym->key) ||
2355 sym->liveTo <= ic->seq)
2358 /* if some liverange has been spilt at the block level
2359 and this one live beyond this block then spil this
2361 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2366 /* if trying to allocate this will cause
2367 a spill and there is nothing to spill
2368 or this one is rematerializable then
2370 willCS = willCauseSpill (sym->nRegs, sym->regType);
2372 /* explicit turn off register spilling */
2375 spillable = computeSpillable (ic);
2377 (willCS && bitVectIsZero (spillable)))
2385 /* If the live range preceeds the point of definition
2386 then ideally we must take into account registers that
2387 have been allocated after sym->liveFrom but freed
2388 before ic->seq. This is complicated, so spill this
2389 symbol instead and let fillGaps handle the allocation. */
2391 if (sym->liveFrom < ic->seq)
2397 /* if it has a spillocation & is used less than
2398 all other live ranges then spill this */
2400 if (sym->usl.spillLoc) {
2401 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2402 allLRs, ebbs[i], ic));
2403 if (leastUsed && leastUsed->used > sym->used) {
2408 /* if none of the liveRanges have a spillLocation then better
2409 to spill this one than anything else already assigned to registers */
2410 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2411 /* if this is local to this block then we might find a block spil */
2412 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2420 if (ic->op == RECEIVE)
2421 debugLog ("When I get clever, I'll optimize the receive logic\n");
2423 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2424 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2425 && (ic->next->op == IFX)
2426 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2428 /* skip register allocation since none will be used */
2429 for(j=0;j<sym->nRegs;j++)
2430 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2431 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2436 /* if we need ptr regs for the right side
2438 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2439 <= (unsigned) PTRSIZE)
2444 /* else we assign registers to it */
2445 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2448 bitVectDebugOn(_G.regAssigned, debugF);
2450 for (j = 0; j < sym->nRegs; j++)
2452 if (sym->regType == REG_PTR)
2453 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2455 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2457 /* if the allocation falied which means
2458 this was spilt then break */
2462 debugLog (" %d - \n", __LINE__);
2464 /* if it shares registers with operands make sure
2465 that they are in the same position */
2466 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2467 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2468 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2469 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2470 /* do the same for the right operand */
2471 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2472 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2473 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2474 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2476 debugLog (" %d - \n", __LINE__);
2479 debugLog (" %d - \n", __LINE__);
2488 /* Check for and fix any problems with uninitialized operands */
2489 for (i = 0; i < count; i++)
2493 if (ebbs[i]->noPath &&
2494 (ebbs[i]->entryLabel != entryLabel &&
2495 ebbs[i]->entryLabel != returnLabel))
2498 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2505 verifyRegsAssigned (IC_COND (ic), ic);
2509 if (ic->op == JUMPTABLE)
2511 verifyRegsAssigned (IC_JTCOND (ic), ic);
2515 verifyRegsAssigned (IC_RESULT (ic), ic);
2516 verifyRegsAssigned (IC_LEFT (ic), ic);
2517 verifyRegsAssigned (IC_RIGHT (ic), ic);
2523 /*-----------------------------------------------------------------*/
2524 /* rUmaskForOp :- returns register mask for an operand */
2525 /*-----------------------------------------------------------------*/
2527 rUmaskForOp (operand * op)
2533 debugLog ("%s\n", __FUNCTION__);
2534 /* only temporaries are assigned registers */
2538 sym = OP_SYMBOL (op);
2540 /* if spilt or no registers assigned to it
2542 if (sym->isspilt || !sym->nRegs)
2545 rumask = newBitVect (pic16_nRegs);
2547 for (j = 0; j < sym->nRegs; j++)
2549 rumask = bitVectSetBit (rumask,
2550 sym->regs[j]->rIdx);
2556 /*-----------------------------------------------------------------*/
2557 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2558 /*-----------------------------------------------------------------*/
2560 regsUsedIniCode (iCode * ic)
2562 bitVect *rmask = newBitVect (pic16_nRegs);
2564 debugLog ("%s\n", __FUNCTION__);
2565 /* do the special cases first */
2568 rmask = bitVectUnion (rmask,
2569 rUmaskForOp (IC_COND (ic)));
2573 /* for the jumptable */
2574 if (ic->op == JUMPTABLE)
2576 rmask = bitVectUnion (rmask,
2577 rUmaskForOp (IC_JTCOND (ic)));
2582 /* of all other cases */
2584 rmask = bitVectUnion (rmask,
2585 rUmaskForOp (IC_LEFT (ic)));
2589 rmask = bitVectUnion (rmask,
2590 rUmaskForOp (IC_RIGHT (ic)));
2593 rmask = bitVectUnion (rmask,
2594 rUmaskForOp (IC_RESULT (ic)));
2600 /*-----------------------------------------------------------------*/
2601 /* createRegMask - for each instruction will determine the regsUsed */
2602 /*-----------------------------------------------------------------*/
2604 createRegMask (eBBlock ** ebbs, int count)
2608 debugLog ("%s\n", __FUNCTION__);
2609 /* for all blocks */
2610 for (i = 0; i < count; i++)
2614 if (ebbs[i]->noPath &&
2615 (ebbs[i]->entryLabel != entryLabel &&
2616 ebbs[i]->entryLabel != returnLabel))
2619 /* for all instructions */
2620 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2625 if (SKIP_IC2 (ic) || !ic->rlive)
2628 /* first mark the registers used in this
2630 ic->rUsed = regsUsedIniCode (ic);
2631 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2633 /* now create the register mask for those
2634 registers that are in use : this is a
2635 super set of ic->rUsed */
2636 ic->rMask = newBitVect (pic16_nRegs + 1);
2638 /* for all live Ranges alive at this point */
2639 for (j = 1; j < ic->rlive->size; j++)
2644 /* if not alive then continue */
2645 if (!bitVectBitValue (ic->rlive, j))
2648 /* find the live range we are interested in */
2649 if (!(sym = hTabItemWithKey (liveRanges, j)))
2651 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2652 "createRegMask cannot find live range");
2656 /* if no register assigned to it */
2657 if (!sym->nRegs || sym->isspilt)
2660 /* for all the registers allocated to it */
2661 for (k = 0; k < sym->nRegs; k++)
2664 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2670 /*-----------------------------------------------------------------*/
2671 /* rematStr - returns the rematerialized string for a remat var */
2672 /*-----------------------------------------------------------------*/
2674 rematStr (symbol * sym)
2677 iCode *ic = sym->rematiCode;
2678 symbol *psym = NULL;
2680 debugLog ("%s\n", __FUNCTION__);
2682 //printf ("%s\n", s);
2684 /* if plus or minus print the right hand side */
2686 if (ic->op == '+' || ic->op == '-') {
2688 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2690 sprintf (s, "(%s %c 0x%04x)",
2691 OP_SYMBOL (IC_LEFT (ric))->rname,
2693 (int) operandLitValue (IC_RIGHT (ic)));
2696 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2698 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2699 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2704 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2705 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2707 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2712 /*-----------------------------------------------------------------*/
2713 /* rematStr - returns the rematerialized string for a remat var */
2714 /*-----------------------------------------------------------------*/
2716 rematStr (symbol * sym)
2719 iCode *ic = sym->rematiCode;
2721 debugLog ("%s\n", __FUNCTION__);
2726 /* if plus or minus print the right hand side */
2728 if (ic->op == '+' || ic->op == '-') {
2729 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2732 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2736 if (ic->op == '+' || ic->op == '-')
2738 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2739 sprintf (s, "(%s %c 0x%04x)",
2740 OP_SYMBOL (IC_LEFT (ric))->rname,
2742 (int) operandLitValue (IC_RIGHT (ic)));
2745 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2747 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2751 /* we reached the end */
2752 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2756 printf ("%s\n", buffer);
2761 /*-----------------------------------------------------------------*/
2762 /* regTypeNum - computes the type & number of registers required */
2763 /*-----------------------------------------------------------------*/
2771 debugLog ("%s\n", __FUNCTION__);
2772 /* for each live range do */
2773 for (sym = hTabFirstItem (liveRanges, &k); sym;
2774 sym = hTabNextItem (liveRanges, &k)) {
2776 debugLog (" %d - %s\n", __LINE__, sym->rname);
2777 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2779 /* if used zero times then no registers needed */
2780 if ((sym->liveTo - sym->liveFrom) == 0)
2784 /* if the live range is a temporary */
2787 debugLog (" %d - itemp register\n", __LINE__);
2789 /* if the type is marked as a conditional */
2790 if (sym->regType == REG_CND)
2793 /* if used in return only then we don't
2795 if (sym->ruonly || sym->accuse) {
2796 if (IS_AGGREGATE (sym->type) || sym->isptr)
2797 sym->type = aggrToPtr (sym->type, FALSE);
2798 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2802 /* if the symbol has only one definition &
2803 that definition is a get_pointer and the
2804 pointer we are getting is rematerializable and
2807 if (bitVectnBitsOn (sym->defs) == 1 &&
2808 (ic = hTabItemWithKey (iCodehTab,
2809 bitVectFirstBit (sym->defs))) &&
2811 !IS_BITVAR (sym->etype) &&
2812 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2814 // continue; /* FIXME -- VR */
2815 if (ptrPseudoSymSafe (sym, ic)) {
2819 debugLog (" %d - \n", __LINE__);
2821 /* create a psuedo symbol & force a spil */
2822 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2823 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2824 psym->type = sym->type;
2825 psym->etype = sym->etype;
2826 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2827 strcpy (psym->rname, psym->name);
2829 sym->usl.spillLoc = psym;
2833 /* if in data space or idata space then try to
2834 allocate pointer register */
2838 /* if not then we require registers */
2839 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2840 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2841 getSize (sym->type));
2845 if(IS_PTR_CONST (sym->type)) {
2847 if(IS_CODEPTR (sym->type)) {
2849 // what IS this ???? (HJD)
2850 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2851 sym->nRegs = 3; // patch 14
2854 if (sym->nRegs > 4) {
2855 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2856 printTypeChain (sym->type, stderr);
2857 fprintf (stderr, "\n");
2860 /* determine the type of register required */
2861 if (sym->nRegs == 1 &&
2862 IS_PTR (sym->type) &&
2864 sym->regType = REG_PTR;
2866 sym->regType = REG_GPR;
2869 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2873 /* for the first run we don't provide */
2874 /* registers for true symbols we will */
2875 /* see how things go */
2881 static DEFSETFUNC (markRegFree)
2883 ((regs *)item)->isFree = 1;
2884 // ((regs *)item)->wasUsed = 0;
2889 DEFSETFUNC (pic16_deallocReg)
2891 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2892 ((regs *)item)->isFree = 1;
2893 ((regs *)item)->wasUsed = 0;
2897 /*-----------------------------------------------------------------*/
2898 /* freeAllRegs - mark all registers as free */
2899 /*-----------------------------------------------------------------*/
2901 pic16_freeAllRegs ()
2903 debugLog ("%s\n", __FUNCTION__);
2905 applyToSet(pic16_dynAllocRegs,markRegFree);
2906 applyToSet(pic16_dynStackRegs,markRegFree);
2909 /*-----------------------------------------------------------------*/
2910 /*-----------------------------------------------------------------*/
2912 pic16_deallocateAllRegs ()
2914 debugLog ("%s\n", __FUNCTION__);
2916 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2920 /*-----------------------------------------------------------------*/
2921 /* deallocStackSpil - this will set the stack pointer back */
2922 /*-----------------------------------------------------------------*/
2924 DEFSETFUNC (deallocStackSpil)
2928 debugLog ("%s\n", __FUNCTION__);
2933 /*-----------------------------------------------------------------*/
2934 /* farSpacePackable - returns the packable icode for far variables */
2935 /*-----------------------------------------------------------------*/
2937 farSpacePackable (iCode * ic)
2941 debugLog ("%s\n", __FUNCTION__);
2942 /* go thru till we find a definition for the
2943 symbol on the right */
2944 for (dic = ic->prev; dic; dic = dic->prev)
2947 /* if the definition is a call then no */
2948 if ((dic->op == CALL || dic->op == PCALL) &&
2949 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2954 /* if shift by unknown amount then not */
2955 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2956 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2959 /* if pointer get and size > 1 */
2960 if (POINTER_GET (dic) &&
2961 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2964 if (POINTER_SET (dic) &&
2965 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2968 /* if any three is a true symbol in far space */
2969 if (IC_RESULT (dic) &&
2970 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2971 isOperandInFarSpace (IC_RESULT (dic)))
2974 if (IC_RIGHT (dic) &&
2975 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2976 isOperandInFarSpace (IC_RIGHT (dic)) &&
2977 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2980 if (IC_LEFT (dic) &&
2981 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2982 isOperandInFarSpace (IC_LEFT (dic)) &&
2983 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2986 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2988 if ((dic->op == LEFT_OP ||
2989 dic->op == RIGHT_OP ||
2991 IS_OP_LITERAL (IC_RIGHT (dic)))
3002 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
3006 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3007 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3008 debugAopGet (" result:", IC_RESULT (ic));
3009 debugAopGet (" left:", IC_LEFT (ic));
3010 debugAopGet (" right:", IC_RIGHT (ic));
3019 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3021 /*-----------------------------------------------------------------*/
3022 /* packRegsForAssign - register reduction for assignment */
3023 /*-----------------------------------------------------------------*/
3025 packRegsForAssign (iCode * ic, eBBlock * ebp)
3029 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3030 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3031 debugAopGet (" result:", IC_RESULT (ic));
3032 debugAopGet (" left:", IC_LEFT (ic));
3033 debugAopGet (" right:", IC_RIGHT (ic));
3035 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3037 debugLog(" %d - actuall processing\n", __LINE__ );
3039 if (!IS_ITEMP (IC_RESULT (ic))) {
3040 pic16_allocDirReg(IC_RESULT (ic));
3041 debugLog (" %d - result is not temp\n", __LINE__);
3044 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3046 /* See BUGLOG0001 - VR */
3048 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3049 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3050 pic16_allocDirReg(IC_RIGHT (ic));
3055 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3056 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3058 debugLog (" %d - not packing - right side fails \n", __LINE__);
3062 /* if the true symbol is defined in far space or on stack
3063 then we should not since this will increase register pressure */
3064 if (isOperandInFarSpace (IC_RESULT (ic)))
3066 if ((dic = farSpacePackable (ic)))
3073 /* find the definition of iTempNN scanning backwards if we find a
3074 a use of the true symbol before we find the definition then
3076 for (dic = ic->prev; dic; dic = dic->prev)
3079 /* if there is a function call and this is
3080 a parameter & not my parameter then don't pack it */
3081 if ((dic->op == CALL || dic->op == PCALL) &&
3082 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3083 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3085 debugLog (" %d - \n", __LINE__);
3094 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3096 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3097 IS_OP_VOLATILE (IC_RESULT (dic)))
3099 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3105 if( IS_SYMOP( IC_RESULT(dic)) &&
3106 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3108 debugLog (" %d - result is bitfield\n", __LINE__);
3114 if (IS_SYMOP (IC_RESULT (dic)) &&
3115 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3117 /* A previous result was assigned to the same register - we'll our definition */
3118 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3119 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3120 if (POINTER_SET (dic))
3126 if (IS_SYMOP (IC_RIGHT (dic)) &&
3127 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3128 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3130 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3135 if (IS_SYMOP (IC_LEFT (dic)) &&
3136 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3137 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3139 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3144 if (POINTER_SET (dic) &&
3145 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3147 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3155 return 0; /* did not find */
3158 /* This code is taken from the hc08 port. Do not know
3159 * if it fits for pic16, but I leave it here just in case */
3161 /* if assignment then check that right is not a bit */
3162 if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
3163 sym_link *etype = operandType (IC_RESULT (dic));
3165 if (IS_BITFIELD (etype)) {
3166 /* if result is a bit too then it's ok */
3167 etype = operandType (IC_RESULT (ic));
3168 if (!IS_BITFIELD (etype)) {
3169 debugLog(" %d bitfields\n");
3176 /* if the result is on stack or iaccess then it must be
3177 the same atleast one of the operands */
3178 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3179 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3181 /* the operation has only one symbol
3182 operator then we can pack */
3183 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3184 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3187 if (!((IC_LEFT (dic) &&
3188 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3190 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3194 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3195 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3196 /* found the definition */
3197 /* replace the result with the result of */
3198 /* this assignment and remove this assignment */
3201 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3202 IC_RESULT (dic) = IC_RESULT (ic);
3204 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3206 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3208 /* delete from liverange table also
3209 delete from all the points inbetween and the new
3211 for (sic = dic; sic != ic; sic = sic->next)
3213 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3214 if (IS_ITEMP (IC_RESULT (dic)))
3215 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3218 remiCodeFromeBBlock (ebp, ic);
3219 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3221 debugLog(" %d\n", __LINE__ );
3222 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3223 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3230 #define NO_packRegsForAccUse
3231 #define NO_packRegsForSupport
3232 #define NO_packRegsForOneuse
3233 #define NO_cast_peep
3238 #ifndef NO_packRegsForSupport
3239 /*-----------------------------------------------------------------*/
3240 /* findAssignToSym : scanning backwards looks for first assig found */
3241 /*-----------------------------------------------------------------*/
3243 findAssignToSym (operand * op, iCode * ic)
3247 debugLog ("%s\n", __FUNCTION__);
3248 for (dic = ic->prev; dic; dic = dic->prev)
3251 /* if definition by assignment */
3252 if (dic->op == '=' &&
3253 !POINTER_SET (dic) &&
3254 IC_RESULT (dic)->key == op->key
3255 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3259 /* we are interested only if defined in far space */
3260 /* or in stack space in case of + & - */
3262 /* if assigned to a non-symbol then return
3264 if (!IS_SYMOP (IC_RIGHT (dic)))
3267 /* if the symbol is in far space then
3269 if (isOperandInFarSpace (IC_RIGHT (dic)))
3272 /* for + & - operations make sure that
3273 if it is on the stack it is the same
3274 as one of the three operands */
3275 if ((ic->op == '+' || ic->op == '-') &&
3276 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3278 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3279 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3280 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3288 /* if we find an usage then we cannot delete it */
3289 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3292 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3295 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3299 /* now make sure that the right side of dic
3300 is not defined between ic & dic */
3303 iCode *sic = dic->next;
3305 for (; sic != ic; sic = sic->next)
3306 if (IC_RESULT (sic) &&
3307 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3318 #ifndef NO_packRegsForSupport
3319 /*-----------------------------------------------------------------*/
3320 /* packRegsForSupport :- reduce some registers for support calls */
3321 /*-----------------------------------------------------------------*/
3323 packRegsForSupport (iCode * ic, eBBlock * ebp)
3327 debugLog ("%s\n", __FUNCTION__);
3328 /* for the left & right operand :- look to see if the
3329 left was assigned a true symbol in far space in that
3330 case replace them */
3331 if (IS_ITEMP (IC_LEFT (ic)) &&
3332 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3334 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3340 debugAopGet ("removing left:", IC_LEFT (ic));
3342 /* found it we need to remove it from the
3344 for (sic = dic; sic != ic; sic = sic->next)
3345 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3347 IC_LEFT (ic)->operand.symOperand =
3348 IC_RIGHT (dic)->operand.symOperand;
3349 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3350 remiCodeFromeBBlock (ebp, dic);
3351 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3352 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3356 /* do the same for the right operand */
3359 IS_ITEMP (IC_RIGHT (ic)) &&
3360 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3362 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3368 /* if this is a subtraction & the result
3369 is a true symbol in far space then don't pack */
3370 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3372 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3373 if (IN_FARSPACE (SPEC_OCLS (etype)))
3377 debugAopGet ("removing right:", IC_RIGHT (ic));
3379 /* found it we need to remove it from the
3381 for (sic = dic; sic != ic; sic = sic->next)
3382 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3384 IC_RIGHT (ic)->operand.symOperand =
3385 IC_RIGHT (dic)->operand.symOperand;
3386 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3388 remiCodeFromeBBlock (ebp, dic);
3389 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3390 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3399 #ifndef NO_packRegsForOneuse
3400 /*-----------------------------------------------------------------*/
3401 /* packRegsForOneuse : - will reduce some registers for single Use */
3402 /*-----------------------------------------------------------------*/
3404 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3411 debugLog ("%s\n", __FUNCTION__);
3412 /* if returning a literal then do nothing */
3416 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3419 /* only upto 2 bytes since we cannot predict
3420 the usage of b, & acc */
3421 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3429 /* this routine will mark the a symbol as used in one
3430 instruction use only && if the definition is local
3431 (ie. within the basic block) && has only one definition &&
3432 that definition is either a return value from a
3433 function or does not contain any variables in
3437 uses = bitVectCopy (OP_USES (op));
3438 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3439 if (!bitVectIsZero (uses)) /* has other uses */
3444 if (bitVectnBitsOn (OP_USES (op)) > 1)
3448 /* if it has only one defintion */
3449 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3450 return NULL; /* has more than one definition */
3452 /* get that definition */
3454 hTabItemWithKey (iCodehTab,
3455 bitVectFirstBit (OP_DEFS (op)))))
3458 /* found the definition now check if it is local */
3459 if (dic->seq < ebp->fSeq ||
3460 dic->seq > ebp->lSeq)
3461 return NULL; /* non-local */
3463 /* now check if it is the return from
3465 if (dic->op == CALL || dic->op == PCALL)
3467 if (ic->op != SEND && ic->op != RETURN &&
3468 !POINTER_SET(ic) && !POINTER_GET(ic))
3470 OP_SYMBOL (op)->ruonly = 1;
3479 /* otherwise check that the definition does
3480 not contain any symbols in far space */
3481 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3482 isOperandInFarSpace (IC_RIGHT (dic)) ||
3483 IS_OP_RUONLY (IC_LEFT (ic)) ||
3484 IS_OP_RUONLY (IC_RIGHT (ic)))
3489 /* if pointer set then make sure the pointer
3491 if (POINTER_SET (dic) &&
3492 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3495 if (POINTER_GET (dic) &&
3496 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3502 /* also make sure the intervenening instructions
3503 don't have any thing in far space */
3504 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3507 /* if there is an intervening function call then no */
3508 if (dic->op == CALL || dic->op == PCALL)
3510 /* if pointer set then make sure the pointer
3512 if (POINTER_SET (dic) &&
3513 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3516 if (POINTER_GET (dic) &&
3517 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3520 /* if address of & the result is remat then okay */
3521 if (dic->op == ADDRESS_OF &&
3522 OP_SYMBOL (IC_RESULT (dic))->remat)
3525 /* if operand has size of three or more & this
3526 operation is a '*','/' or '%' then 'b' may
3528 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3529 getSize (operandType (op)) >= 2)
3532 /* if left or right or result is in far space */
3533 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3534 isOperandInFarSpace (IC_RIGHT (dic)) ||
3535 isOperandInFarSpace (IC_RESULT (dic)) ||
3536 IS_OP_RUONLY (IC_LEFT (dic)) ||
3537 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3538 IS_OP_RUONLY (IC_RESULT (dic)))
3544 OP_SYMBOL (op)->ruonly = 1;
3551 /*-----------------------------------------------------------------*/
3552 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3553 /*-----------------------------------------------------------------*/
3555 isBitwiseOptimizable (iCode * ic)
3557 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3558 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3560 debugLog ("%s\n", __FUNCTION__);
3561 /* bitwise operations are considered optimizable
3562 under the following conditions (Jean-Louis VERN)
3574 if (IS_LITERAL (rtype) ||
3575 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3582 #ifndef NO_packRegsForAccUse
3584 /*-----------------------------------------------------------------*/
3585 /* packRegsForAccUse - pack registers for acc use */
3586 /*-----------------------------------------------------------------*/
3588 packRegsForAccUse (iCode * ic)
3592 debugLog ("%s\n", __FUNCTION__);
3594 /* if this is an aggregate, e.g. a one byte char array */
3595 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3598 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3600 /* if + or - then it has to be one byte result */
3601 if ((ic->op == '+' || ic->op == '-')
3602 && getSize (operandType (IC_RESULT (ic))) > 1)
3605 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3606 /* if shift operation make sure right side is not a literal */
3607 if (ic->op == RIGHT_OP &&
3608 (isOperandLiteral (IC_RIGHT (ic)) ||
3609 getSize (operandType (IC_RESULT (ic))) > 1))
3612 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3613 if (ic->op == LEFT_OP &&
3614 (isOperandLiteral (IC_RIGHT (ic)) ||
3615 getSize (operandType (IC_RESULT (ic))) > 1))
3618 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3619 if (IS_BITWISE_OP (ic) &&
3620 getSize (operandType (IC_RESULT (ic))) > 1)
3624 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3625 /* has only one definition */
3626 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3629 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3630 /* has only one use */
3631 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3634 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3635 /* and the usage immediately follows this iCode */
3636 if (!(uic = hTabItemWithKey (iCodehTab,
3637 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3640 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3641 if (ic->next != uic)
3644 /* if it is a conditional branch then we definitely can */
3648 if (uic->op == JUMPTABLE)
3651 /* if the usage is not is an assignment
3652 or an arithmetic / bitwise / shift operation then not */
3653 if (POINTER_SET (uic) &&
3654 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3657 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3658 if (uic->op != '=' &&
3659 !IS_ARITHMETIC_OP (uic) &&
3660 !IS_BITWISE_OP (uic) &&
3661 uic->op != LEFT_OP &&
3662 uic->op != RIGHT_OP)
3665 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3666 /* if used in ^ operation then make sure right is not a
3668 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3671 /* if shift operation make sure right side is not a literal */
3672 if (uic->op == RIGHT_OP &&
3673 (isOperandLiteral (IC_RIGHT (uic)) ||
3674 getSize (operandType (IC_RESULT (uic))) > 1))
3677 if (uic->op == LEFT_OP &&
3678 (isOperandLiteral (IC_RIGHT (uic)) ||
3679 getSize (operandType (IC_RESULT (uic))) > 1))
3682 /* make sure that the result of this icode is not on the
3683 stack, since acc is used to compute stack offset */
3684 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3685 OP_SYMBOL (IC_RESULT (uic))->onStack)
3688 /* if either one of them in far space then we cannot */
3689 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3690 isOperandInFarSpace (IC_LEFT (uic))) ||
3691 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3692 isOperandInFarSpace (IC_RIGHT (uic))))
3695 /* if the usage has only one operand then we can */
3696 if (IC_LEFT (uic) == NULL ||
3697 IC_RIGHT (uic) == NULL)
3700 /* make sure this is on the left side if not
3701 a '+' since '+' is commutative */
3702 if (ic->op != '+' &&
3703 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3707 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3708 /* if one of them is a literal then we can */
3709 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3710 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3711 (getSize (operandType (IC_RESULT (uic))) <= 1))
3713 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3718 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3719 /* if the other one is not on stack then we can */
3720 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3721 (IS_ITEMP (IC_RIGHT (uic)) ||
3722 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3723 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3726 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3727 (IS_ITEMP (IC_LEFT (uic)) ||
3728 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3729 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3735 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3736 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3743 /*-----------------------------------------------------------------*/
3744 /* packForPush - hueristics to reduce iCode for pushing */
3745 /*-----------------------------------------------------------------*/
3747 packForReceive (iCode * ic, eBBlock * ebp)
3751 debugLog ("%s\n", __FUNCTION__);
3752 debugAopGet (" result:", IC_RESULT (ic));
3753 debugAopGet (" left:", IC_LEFT (ic));
3754 debugAopGet (" right:", IC_RIGHT (ic));
3759 for (dic = ic->next; dic; dic = dic->next)
3761 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3762 debugLog (" used on left\n");
3763 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3764 debugLog (" used on right\n");
3765 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3766 debugLog (" used on result\n");
3768 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3769 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3773 debugLog (" hey we can remove this unnecessary assign\n");
3775 /*-----------------------------------------------------------------*/
3776 /* packForPush - hueristics to reduce iCode for pushing */
3777 /*-----------------------------------------------------------------*/
3779 packForPush (iCode * ic, eBBlock * ebp)
3784 debugLog ("%s\n", __FUNCTION__);
3785 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3792 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3793 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3794 iLine = printILine(ic);
3795 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3797 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3801 /* must have only definition & one usage */
3802 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3803 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3806 /* find the definition */
3807 if (!(dic = hTabItemWithKey (iCodehTab,
3808 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3811 /* if definition is not assignment,
3812 * or is not pointer (because pointer might have changed) */
3813 if (dic->op != '=' || POINTER_SET (dic))
3816 /* we must ensure that we can use the delete the assignment,
3817 * because the source might have been modified in between.
3818 * Until I know how to fix this, I'll use the adhoc fix
3819 * to check the liveranges */
3820 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3822 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3826 /* we now we know that it has one & only one def & use
3827 and the that the definition is an assignment */
3828 IC_LEFT (ic) = IC_RIGHT (dic);
3830 iLine = printILine(dic);
3831 debugf("remiCodeFromeBBlock: %s\n", iLine);
3834 remiCodeFromeBBlock (ebp, dic);
3835 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3836 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3839 static void printSymType(char * str, sym_link *sl)
3841 if(!pic16_ralloc_debug)return;
3843 debugLog (" %s Symbol type: ",str);
3844 printTypeChain (sl, debugF);
3848 /*-----------------------------------------------------------------*/
3849 /* some debug code to print the symbol S_TYPE. Note that
3850 * the function checkSClass in src/SDCCsymt.c dinks with
3851 * the S_TYPE in ways the PIC port doesn't fully like...*/
3852 /*-----------------------------------------------------------------*/
3853 static void isData(sym_link *sl)
3857 if(!pic16_ralloc_debug)return;
3864 for ( ; sl; sl=sl->next) {
3866 switch (SPEC_SCLS(sl)) {
3867 case S_DATA: fprintf (of, "data "); break;
3868 case S_XDATA: fprintf (of, "xdata "); break;
3869 case S_SFR: fprintf (of, "sfr "); break;
3870 case S_SBIT: fprintf (of, "sbit "); break;
3871 case S_CODE: fprintf (of, "code "); break;
3872 case S_IDATA: fprintf (of, "idata "); break;
3873 case S_PDATA: fprintf (of, "pdata "); break;
3874 case S_LITERAL: fprintf (of, "literal "); break;
3875 case S_STACK: fprintf (of, "stack "); break;
3876 case S_XSTACK: fprintf (of, "xstack "); break;
3877 case S_BIT: fprintf (of, "bit "); break;
3878 case S_EEPROM: fprintf (of, "eeprom "); break;
3886 /*--------------------------------------------------------------------*/
3887 /* pic16_packRegisters - does some transformations to reduce */
3888 /* register pressure */
3890 /*--------------------------------------------------------------------*/
3892 pic16_packRegisters (eBBlock * ebp)
3897 debugLog ("%s\n", __FUNCTION__);
3903 /* look for assignments of the form */
3904 /* iTempNN = TRueSym (someoperation) SomeOperand */
3906 /* TrueSym := iTempNN:1 */
3907 for (ic = ebp->sch; ic; ic = ic->next)
3909 // debugLog("%d\n", __LINE__);
3910 /* find assignment of the form TrueSym := iTempNN:1 */
3911 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3912 change += packRegsForAssign (ic, ebp);
3916 if (POINTER_SET (ic))
3917 debugLog ("pointer is set\n");
3918 debugAopGet (" result:", IC_RESULT (ic));
3919 debugAopGet (" left:", IC_LEFT (ic));
3920 debugAopGet (" right:", IC_RIGHT (ic));
3929 for (ic = ebp->sch; ic; ic = ic->next) {
3931 if(IS_SYMOP ( IC_LEFT(ic))) {
3932 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3934 debugAopGet ("x left:", IC_LEFT (ic));
3936 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3938 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3940 debugLog (" is a pointer\n");
3942 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3943 debugLog (" is a ptr\n");
3945 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3946 debugLog (" is volatile\n");
3950 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3951 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3952 pic16_allocDirReg(IC_LEFT (ic));
3955 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3958 if(IS_SYMOP ( IC_RIGHT(ic))) {
3959 debugAopGet (" right:", IC_RIGHT (ic));
3960 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3963 if(IS_SYMOP ( IC_RESULT(ic))) {
3964 debugAopGet (" result:", IC_RESULT (ic));
3965 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3968 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3969 debugAopGet (" right:", IC_RIGHT (ic));
3970 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3971 // pic16_allocDirReg(IC_RIGHT(ic));
3974 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3975 debugAopGet (" result:", IC_RESULT (ic));
3976 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3977 // pic16_allocDirReg(IC_RESULT(ic));
3981 if (POINTER_SET (ic))
3982 debugLog (" %d - Pointer set\n", __LINE__);
3984 /* Look for two subsequent iCodes with */
3986 /* _c = iTemp & op; */
3987 /* and replace them by */
3990 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3992 && ic->prev->op == '='
3993 && IS_ITEMP (IC_LEFT (ic))
3994 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3995 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3997 iCode* ic_prev = ic->prev;
3998 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
4000 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
4001 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
4002 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
4003 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
4004 prev_result_sym->liveTo == ic->seq)
4006 prev_result_sym->liveTo = ic_prev->seq;
4009 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
4011 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
4013 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
4014 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
4015 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
4016 remiCodeFromeBBlock (ebp, ic_prev);
4017 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
4021 /* if this is an itemp & result of a address of a true sym
4022 then mark this as rematerialisable */
4023 if (ic->op == ADDRESS_OF &&
4024 IS_ITEMP (IC_RESULT (ic)) &&
4025 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4026 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4027 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4030 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4032 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4033 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4034 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4038 /* if straight assignment then carry remat flag if
4039 this is the only definition */
4040 if (ic->op == '=' &&
4041 !POINTER_SET (ic) &&
4042 IS_SYMOP (IC_RIGHT (ic)) &&
4043 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4044 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4046 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4048 OP_SYMBOL (IC_RESULT (ic))->remat =
4049 OP_SYMBOL (IC_RIGHT (ic))->remat;
4050 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4051 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4054 /* if this is a +/- operation with a rematerizable
4055 then mark this as rematerializable as well */
4056 if ((ic->op == '+' || ic->op == '-') &&
4057 (IS_SYMOP (IC_LEFT (ic)) &&
4058 IS_ITEMP (IC_RESULT (ic)) &&
4059 OP_SYMBOL (IC_LEFT (ic))->remat &&
4060 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4061 IS_OP_LITERAL (IC_RIGHT (ic))))
4063 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4065 operandLitValue (IC_RIGHT (ic));
4066 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4067 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4068 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4073 /* try to optimize FSR0 usage when reading data memory pointers */
4075 if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4076 static int fsr0usage=0;
4079 if(POINTER_GET(ic) /* this is a memory read */
4080 && ic->loop /* this is in a loop */
4082 fprintf(stderr, "might optimize FSR0 usage\n");
4087 /* mark the pointer usages */
4088 if (POINTER_SET (ic))
4090 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4091 debugLog (" marking as a pointer (set) =>");
4092 debugAopGet (" result:", IC_RESULT (ic));
4096 if (POINTER_GET (ic))
4098 if(IS_SYMOP(IC_LEFT(ic))) {
4099 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4100 debugLog (" marking as a pointer (get) =>");
4101 debugAopGet (" left:", IC_LEFT (ic));
4104 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4105 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4106 iCode *dic = ic->prev;
4108 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4110 if(dic && dic->op == '='
4111 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4113 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4116 /* replace prev->left with ic->left */
4117 IC_LEFT(ic) = IC_RIGHT(dic);
4118 IC_RIGHT(ic->prev) = NULL;
4120 /* remove ic->prev iCode (assignment) */
4121 remiCodeFromeBBlock (ebp, dic);
4122 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4125 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4131 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4135 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4136 /* if we are using a symbol on the stack
4137 then we should say pic16_ptrRegReq */
4138 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4139 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4140 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4141 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4142 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4143 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4147 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4148 if (IS_SYMOP (IC_LEFT (ic)))
4149 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4150 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4151 if (IS_SYMOP (IC_RIGHT (ic)))
4152 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4153 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4154 if (IS_SYMOP (IC_RESULT (ic)))
4155 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4156 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4159 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4163 /* if the condition of an if instruction
4164 is defined in the previous instruction then
4165 mark the itemp as a conditional */
4166 if ((IS_CONDITIONAL (ic) ||
4167 ((ic->op == BITWISEAND ||
4170 isBitwiseOptimizable (ic))) &&
4171 ic->next && ic->next->op == IFX &&
4172 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4173 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4176 debugLog (" %d\n", __LINE__);
4177 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4181 debugLog(" %d\n", __LINE__);
4183 #ifndef NO_packRegsForSupport
4184 /* reduce for support function calls */
4185 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4186 packRegsForSupport (ic, ebp);
4189 /* if a parameter is passed, it's in W, so we may not
4190 need to place a copy in a register */
4191 if (ic->op == RECEIVE)
4192 packForReceive (ic, ebp);
4194 #ifndef NO_packRegsForOneuse
4195 /* some cases the redundant moves can
4196 can be eliminated for return statements */
4197 if ((ic->op == RETURN || ic->op == SEND) &&
4198 !isOperandInFarSpace (IC_LEFT (ic)) &&
4200 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4203 #ifndef NO_packRegsForOneuse
4204 /* if pointer set & left has a size more than
4205 one and right is not in far space */
4206 if (POINTER_SET (ic) &&
4207 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4208 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4209 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4210 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4212 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4215 #ifndef NO_packRegsForOneuse
4216 /* if pointer get */
4217 if (POINTER_GET (ic) &&
4218 !isOperandInFarSpace (IC_RESULT (ic)) &&
4219 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4220 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4221 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4223 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4224 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4227 #ifndef NO_cast_peep
4228 /* if this is cast for intergral promotion then
4229 check if only use of the definition of the
4230 operand being casted/ if yes then replace
4231 the result of that arithmetic operation with
4232 this result and get rid of the cast */
4233 if (ic->op == CAST) {
4235 sym_link *fromType = operandType (IC_RIGHT (ic));
4236 sym_link *toType = operandType (IC_LEFT (ic));
4238 debugLog (" %d - casting\n", __LINE__);
4240 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4241 getSize (fromType) != getSize (toType)) {
4244 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4247 if (IS_ARITHMETIC_OP (dic)) {
4248 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4250 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4251 IC_RESULT (dic) = IC_RESULT (ic);
4252 remiCodeFromeBBlock (ebp, ic);
4253 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4254 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4255 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4259 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4263 /* if the type from and type to are the same
4264 then if this is the only use then packit */
4265 if (compareType (operandType (IC_RIGHT (ic)),
4266 operandType (IC_LEFT (ic))) == 1) {
4268 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4271 debugLog(" %d\n", __LINE__);
4273 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4274 IC_RESULT (dic) = IC_RESULT (ic);
4275 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4276 remiCodeFromeBBlock (ebp, ic);
4277 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4278 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4287 /* there are some problems with packing variables
4288 * it seems that the live range estimator doesn't
4289 * estimate correctly the liveranges of some symbols */
4292 iTempNN := (some variable in farspace) V1
4297 if (ic->op == IPUSH)
4299 packForPush (ic, ebp);
4303 #ifndef NO_packRegsForAccUse
4304 /* pack registers for accumulator use, when the
4305 result of an arithmetic or bit wise operation
4306 has only one use, that use is immediately following
4307 the defintion and the using iCode has only one
4308 operand or has two operands but one is literal &
4309 the result of that operation is not on stack then
4310 we can leave the result of this operation in acc:b
4312 if ((IS_ARITHMETIC_OP (ic)
4314 || IS_BITWISE_OP (ic)
4316 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4319 IS_ITEMP (IC_RESULT (ic)) &&
4320 getSize (operandType (IC_RESULT (ic))) <= 1)
4322 packRegsForAccUse (ic);
4329 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4333 if (!pic16_ralloc_debug || !debugF)
4336 for (i = 0; i < count; i++)
4338 fprintf (debugF, "\n----------------------------------------------------------------\n");
4339 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4340 ebbs[i]->entryLabel->name,
4343 ebbs[i]->isLastInLoop);
4344 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4349 fprintf (debugF, "visited %d : hasFcall = %d\n",
4353 fprintf (debugF, "\ndefines bitVector :");
4354 bitVectDebugOn (ebbs[i]->defSet, debugF);
4355 fprintf (debugF, "\nlocal defines bitVector :");
4356 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4357 fprintf (debugF, "\npointers Set bitvector :");
4358 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4359 fprintf (debugF, "\nin pointers Set bitvector :");
4360 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4361 fprintf (debugF, "\ninDefs Set bitvector :");
4362 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4363 fprintf (debugF, "\noutDefs Set bitvector :");
4364 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4365 fprintf (debugF, "\nusesDefs Set bitvector :");
4366 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4367 fprintf (debugF, "\n----------------------------------------------------------------\n");
4368 printiCChain (ebbs[i]->sch, debugF);
4372 void dbg_dumpregusage(void);
4374 /*-----------------------------------------------------------------*/
4375 /* pic16_assignRegisters - assigns registers to each live range as need */
4376 /*-----------------------------------------------------------------*/
4378 pic16_assignRegisters (ebbIndex * ebbi)
4380 eBBlock ** ebbs = ebbi->bbOrder;
4381 int count = ebbi->count;
4385 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4386 debugLog ("\nebbs before optimizing:\n");
4387 dumpEbbsToDebug (ebbs, count);
4389 _inRegAllocator = 1;
4391 pic16_freeAllRegs();
4394 /* clear whats left over from peephole parser */
4395 pic16_dynAllocRegs= newSet(); //NULL;
4396 // pic16_dynStackRegs= newSet(); //NULL;
4397 // pic16_dynProcessorRegs=newSet(); //NULL;
4398 // pic16_dynDirectRegs=newSet(); //NULL;
4399 // pic16_dynDirectBitRegs=newSet(); //NULL;
4400 // pic16_dynInternalRegs=newSet(); //NULL;
4401 // pic16_dynAccessRegs=newSet(); //NULL;
4403 // dynDirectRegNames=NULL;
4404 dynAllocRegNames=NULL;
4405 // dynProcRegNames=NULL;
4406 // dynAccessRegNames=NULL;
4409 setToNull ((void *) &_G.funcrUsed);
4410 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4413 /* change assignments this will remove some
4414 live ranges reducing some register pressure */
4415 for (i = 0; i < count; i++)
4416 pic16_packRegisters (ebbs[i]);
4423 debugLog("dir registers allocated so far:\n");
4424 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4428 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4429 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4430 reg = hTabNextItem(dynDirectRegNames, &hkey);
4436 /* liveranges probably changed by register packing
4437 so we compute them again */
4438 recomputeLiveRanges (ebbs, count);
4440 if (options.dump_pack)
4441 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4443 /* first determine for each live range the number of
4444 registers & the type of registers required for each */
4447 /* start counting function temporary registers from zero */
4448 /* XXX: Resetting dynrIdx breaks register allocation,
4449 * see #1489055, #1483693 (?), and #1445850! */
4452 /* and serially allocate registers */
4453 serialRegAssign (ebbs, count);
4456 debugLog ("ebbs after serialRegAssign:\n");
4457 dumpEbbsToDebug (ebbs, count);
4460 //pic16_freeAllRegs();
4462 /* if stack was extended then tell the user */
4465 /* werror(W_TOOMANY_SPILS,"stack", */
4466 /* _G.stackExtend,currFunc->name,""); */
4472 /* werror(W_TOOMANY_SPILS,"data space", */
4473 /* _G.dataExtend,currFunc->name,""); */
4477 /* after that create the register mask
4478 for each of the instruction */
4479 createRegMask (ebbs, count);
4481 /* redo that offsets for stacked automatic variables */
4482 redoStackOffsets ();
4484 if (options.dump_rassgn)
4485 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4487 // dumpLR(ebbs, count);
4489 /* now get back the chain */
4490 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4492 debugLog ("ebbs after optimizing:\n");
4493 dumpEbbsToDebug (ebbs, count);
4496 _inRegAllocator = 0;
4500 /* free up any _G.stackSpil locations allocated */
4501 applyToSet (_G.stackSpil, deallocStackSpil);
4503 setToNull ((void *) &_G.stackSpil);
4504 setToNull ((void *) &_G.spiltSet);
4505 /* mark all registers as free */
4506 pic16_freeAllRegs ();
4509 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");