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_SPIL_LOC (sym) ? 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_SPIL_LOC (sym) ? 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_SPIL_LOC (sym) &&
1404 (IN_DIRSPACE (SPEC_OCLS (SYM_SPIL_LOC (sym)->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_SPIL_LOC (sym) && !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_SPIL_LOC (sym) = 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_SPIL_LOC (sym) = 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_SPIL_LOC (sym))
1726 etype = getSpec (SYM_SPIL_LOC (sym)->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_SPIL_LOC (sym)))
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_SPIL_LOC (sym) && !sym->remat)
1773 SYM_SPIL_LOC (sym)->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_SPIL_LOC (sym)->rname[0] ?
1804 SYM_SPIL_LOC (sym)->rname :
1805 SYM_SPIL_LOC (sym)->name));
1807 /* mark it as allocation required */
1808 SYM_SPIL_LOC (sym)->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_SPIL_LOC (sym)->allocreq = 1;
1856 /* find live ranges with spillocation */
1857 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1860 sym = leastUsedLR (selectS);
1861 SYM_SPIL_LOC (sym)->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_SPIL_LOC (sym)->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_SPIL_LOC (sym)->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)
2120 for (i = 0; i < result->nRegs; i++)
2122 result->regs[i] = sym->regs[i];
2124 result->regs[i] = getRegGpr (ic, ebp, result);
2126 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2130 /* free the remaining */
2131 for (; i < sym->nRegs; i++)
2135 if (!symHasReg (psym, sym->regs[i]))
2136 freeReg (sym->regs[i]);
2139 freeReg (sym->regs[i]);
2146 /*-----------------------------------------------------------------*/
2147 /* reassignLR - reassign this to registers */
2148 /*-----------------------------------------------------------------*/
2150 reassignLR (operand * op)
2152 symbol *sym = OP_SYMBOL (op);
2155 debugLog ("%s\n", __FUNCTION__);
2156 /* not spilt any more */
2157 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2158 bitVectUnSetBit (_G.spiltSet, sym->key);
2160 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2164 for (i = 0; i < sym->nRegs; i++)
2165 sym->regs[i]->isFree = 0;
2168 /*-----------------------------------------------------------------*/
2169 /* willCauseSpill - determines if allocating will cause a spill */
2170 /*-----------------------------------------------------------------*/
2172 willCauseSpill (int nr, int rt)
2174 debugLog ("%s\n", __FUNCTION__);
2175 /* first check if there are any avlb registers
2176 of te type required */
2179 /* special case for pointer type
2180 if pointer type not avlb then
2181 check for type gpr */
2182 if (nFreeRegs (rt) >= nr)
2184 if (nFreeRegs (REG_GPR) >= nr)
2189 if (pic16_ptrRegReq)
2191 if (nFreeRegs (rt) >= nr)
2196 if (nFreeRegs (REG_PTR) +
2197 nFreeRegs (REG_GPR) >= nr)
2202 debugLog (" ... yep it will (cause a spill)\n");
2203 /* it will cause a spil */
2207 /*-----------------------------------------------------------------*/
2208 /* positionRegs - the allocator can allocate same registers to res- */
2209 /* ult and operand, if this happens make sure they are in the same */
2210 /* position as the operand otherwise chaos results */
2211 /*-----------------------------------------------------------------*/
2213 positionRegs (symbol * result, symbol * opsym, int lineno)
2215 int count = min (result->nRegs, opsym->nRegs);
2216 int i, j = 0, shared = 0;
2218 debugLog ("%s\n", __FUNCTION__);
2219 /* if the result has been spilt then cannot share */
2224 /* first make sure that they actually share */
2225 for (i = 0; i < count; i++)
2227 for (j = 0; j < count; j++)
2229 if (result->regs[i] == opsym->regs[j] && i != j)
2239 regs *tmp = result->regs[i];
2240 result->regs[i] = result->regs[j];
2241 result->regs[j] = tmp;
2246 /*------------------------------------------------------------------*/
2247 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2248 /* it should either have registers or have beed spilled. Otherwise, */
2249 /* there was an uninitialized variable, so just spill this to get */
2250 /* the operand in a valid state. */
2251 /*------------------------------------------------------------------*/
2253 verifyRegsAssigned (operand *op, iCode * ic)
2258 if (!IS_ITEMP (op)) return;
2260 sym = OP_SYMBOL (op);
2261 if (sym->isspilt) return;
2262 if (!sym->nRegs) return;
2263 if (sym->regs[0]) return;
2265 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2266 sym->prereqv ? sym->prereqv->name : sym->name);
2271 /*-----------------------------------------------------------------*/
2272 /* serialRegAssign - serially allocate registers to the variables */
2273 /*-----------------------------------------------------------------*/
2275 serialRegAssign (eBBlock ** ebbs, int count)
2280 debugLog ("%s\n", __FUNCTION__);
2281 /* for all blocks */
2282 for (i = 0; i < count; i++)
2284 if (ebbs[i]->noPath &&
2285 (ebbs[i]->entryLabel != entryLabel &&
2286 ebbs[i]->entryLabel != returnLabel))
2289 /* of all instructions do */
2290 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2293 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2295 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2296 pic16_allocDirReg(IC_RESULT(ic));
2298 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2299 pic16_allocDirReg(IC_LEFT(ic));
2301 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2302 pic16_allocDirReg(IC_RIGHT(ic));
2304 /* if this is an ipop that means some live
2305 range will have to be assigned again */
2307 reassignLR (IC_LEFT (ic));
2309 /* if result is present && is a true symbol */
2310 if (IC_RESULT (ic) && ic->op != IFX &&
2311 IS_TRUE_SYMOP (IC_RESULT (ic)))
2312 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2314 /* take away registers from live
2315 ranges that end at this instruction */
2316 deassignLRs (ic, ebbs[i]);
2318 /* some don't need registers */
2319 if (SKIP_IC2 (ic) ||
2320 ic->op == JUMPTABLE ||
2324 (IC_RESULT (ic) && POINTER_SET (ic)))
2327 /* now we need to allocate registers
2328 only for the result */
2331 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2337 /* Make sure any spill location is definately allocated */
2338 if (sym->isspilt && !sym->remat && SYM_SPIL_LOC (sym) &&
2339 !SYM_SPIL_LOC (sym)->allocreq)
2341 SYM_SPIL_LOC (sym)->allocreq++;
2344 /* if it does not need or is spilt
2345 or is already assigned to registers
2346 or will not live beyond this instructions */
2349 bitVectBitValue (_G.regAssigned, sym->key) ||
2350 sym->liveTo <= ic->seq)
2353 /* if some liverange has been spilt at the block level
2354 and this one live beyond this block then spil this
2356 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2361 /* if trying to allocate this will cause
2362 a spill and there is nothing to spill
2363 or this one is rematerializable then
2365 willCS = willCauseSpill (sym->nRegs, sym->regType);
2367 /* explicit turn off register spilling */
2370 spillable = computeSpillable (ic);
2372 (willCS && bitVectIsZero (spillable)))
2380 /* If the live range preceeds the point of definition
2381 then ideally we must take into account registers that
2382 have been allocated after sym->liveFrom but freed
2383 before ic->seq. This is complicated, so spill this
2384 symbol instead and let fillGaps handle the allocation. */
2385 if (sym->liveFrom < ic->seq)
2391 /* if it has a spillocation & is used less than
2392 all other live ranges then spill this */
2394 if (SYM_SPIL_LOC (sym)) {
2395 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2396 allLRs, ebbs[i], ic));
2397 if (leastUsed && leastUsed->used > sym->used) {
2402 /* if none of the liveRanges have a spillLocation then better
2403 to spill this one than anything else already assigned to registers */
2404 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2405 /* if this is local to this block then we might find a block spil */
2406 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2414 if (ic->op == RECEIVE)
2415 debugLog ("When I get clever, I'll optimize the receive logic\n");
2417 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2418 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2419 && (ic->next->op == IFX)
2420 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2422 /* skip register allocation since none will be used */
2423 for(j=0;j<sym->nRegs;j++)
2424 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2425 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2430 /* if we need ptr regs for the right side
2432 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2433 <= (unsigned) PTRSIZE)
2438 /* else we assign registers to it */
2439 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2442 bitVectDebugOn(_G.regAssigned, debugF);
2444 for (j = 0; j < sym->nRegs; j++)
2446 if (sym->regType == REG_PTR)
2447 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2449 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2451 /* if the allocation falied which means
2452 this was spilt then break */
2456 debugLog (" %d - \n", __LINE__);
2458 /* if it shares registers with operands make sure
2459 that they are in the same position */
2460 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2461 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2462 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2463 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2464 /* do the same for the right operand */
2465 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2466 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2467 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2468 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2470 debugLog (" %d - \n", __LINE__);
2473 debugLog (" %d - \n", __LINE__);
2482 /* Check for and fix any problems with uninitialized operands */
2483 for (i = 0; i < count; i++)
2487 if (ebbs[i]->noPath &&
2488 (ebbs[i]->entryLabel != entryLabel &&
2489 ebbs[i]->entryLabel != returnLabel))
2492 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2499 verifyRegsAssigned (IC_COND (ic), ic);
2503 if (ic->op == JUMPTABLE)
2505 verifyRegsAssigned (IC_JTCOND (ic), ic);
2509 verifyRegsAssigned (IC_RESULT (ic), ic);
2510 verifyRegsAssigned (IC_LEFT (ic), ic);
2511 verifyRegsAssigned (IC_RIGHT (ic), ic);
2517 /*-----------------------------------------------------------------*/
2518 /* rUmaskForOp :- returns register mask for an operand */
2519 /*-----------------------------------------------------------------*/
2521 rUmaskForOp (operand * op)
2527 debugLog ("%s\n", __FUNCTION__);
2528 /* only temporaries are assigned registers */
2532 sym = OP_SYMBOL (op);
2534 /* if spilt or no registers assigned to it
2536 if (sym->isspilt || !sym->nRegs)
2539 rumask = newBitVect (pic16_nRegs);
2541 for (j = 0; j < sym->nRegs; j++)
2543 rumask = bitVectSetBit (rumask,
2544 sym->regs[j]->rIdx);
2550 /*-----------------------------------------------------------------*/
2551 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2552 /*-----------------------------------------------------------------*/
2554 regsUsedIniCode (iCode * ic)
2556 bitVect *rmask = newBitVect (pic16_nRegs);
2558 debugLog ("%s\n", __FUNCTION__);
2559 /* do the special cases first */
2562 rmask = bitVectUnion (rmask,
2563 rUmaskForOp (IC_COND (ic)));
2567 /* for the jumptable */
2568 if (ic->op == JUMPTABLE)
2570 rmask = bitVectUnion (rmask,
2571 rUmaskForOp (IC_JTCOND (ic)));
2576 /* of all other cases */
2578 rmask = bitVectUnion (rmask,
2579 rUmaskForOp (IC_LEFT (ic)));
2583 rmask = bitVectUnion (rmask,
2584 rUmaskForOp (IC_RIGHT (ic)));
2587 rmask = bitVectUnion (rmask,
2588 rUmaskForOp (IC_RESULT (ic)));
2594 /*-----------------------------------------------------------------*/
2595 /* createRegMask - for each instruction will determine the regsUsed */
2596 /*-----------------------------------------------------------------*/
2598 createRegMask (eBBlock ** ebbs, int count)
2602 debugLog ("%s\n", __FUNCTION__);
2603 /* for all blocks */
2604 for (i = 0; i < count; i++)
2608 if (ebbs[i]->noPath &&
2609 (ebbs[i]->entryLabel != entryLabel &&
2610 ebbs[i]->entryLabel != returnLabel))
2613 /* for all instructions */
2614 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2619 if (SKIP_IC2 (ic) || !ic->rlive)
2622 /* first mark the registers used in this
2624 ic->rUsed = regsUsedIniCode (ic);
2625 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2627 /* now create the register mask for those
2628 registers that are in use : this is a
2629 super set of ic->rUsed */
2630 ic->rMask = newBitVect (pic16_nRegs + 1);
2632 /* for all live Ranges alive at this point */
2633 for (j = 1; j < ic->rlive->size; j++)
2638 /* if not alive then continue */
2639 if (!bitVectBitValue (ic->rlive, j))
2642 /* find the live range we are interested in */
2643 if (!(sym = hTabItemWithKey (liveRanges, j)))
2645 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2646 "createRegMask cannot find live range");
2650 /* if no register assigned to it */
2651 if (!sym->nRegs || sym->isspilt)
2654 /* for all the registers allocated to it */
2655 for (k = 0; k < sym->nRegs; k++)
2658 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2664 /*-----------------------------------------------------------------*/
2665 /* rematStr - returns the rematerialized string for a remat var */
2666 /*-----------------------------------------------------------------*/
2668 rematStr (symbol * sym)
2670 iCode *ic = sym->rematiCode;
2671 symbol *psym = NULL;
2674 debugLog ("%s\n", __FUNCTION__);
2676 while (ic->op == '+' || ic->op == '-') {
2677 /* if plus or minus print the right hand side */
2679 offset += (int) operandLitValue (IC_RIGHT (ic));
2680 ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2683 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2684 psym->offset = offset;
2689 /*-----------------------------------------------------------------*/
2690 /* rematStr - returns the rematerialized string for a remat var */
2691 /*-----------------------------------------------------------------*/
2693 rematStr (symbol * sym)
2696 iCode *ic = sym->rematiCode;
2698 debugLog ("%s\n", __FUNCTION__);
2703 /* if plus or minus print the right hand side */
2705 if (ic->op == '+' || ic->op == '-') {
2706 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2709 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2713 if (ic->op == '+' || ic->op == '-')
2715 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2716 sprintf (s, "(%s %c 0x%04x)",
2717 OP_SYMBOL (IC_LEFT (ric))->rname,
2719 (int) operandLitValue (IC_RIGHT (ic)));
2722 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2724 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2728 /* we reached the end */
2729 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2733 printf ("%s\n", buffer);
2738 /*-----------------------------------------------------------------*/
2739 /* regTypeNum - computes the type & number of registers required */
2740 /*-----------------------------------------------------------------*/
2748 debugLog ("%s\n", __FUNCTION__);
2749 /* for each live range do */
2750 for (sym = hTabFirstItem (liveRanges, &k); sym;
2751 sym = hTabNextItem (liveRanges, &k)) {
2753 debugLog (" %d - %s\n", __LINE__, sym->rname);
2754 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2756 /* if used zero times then no registers needed */
2757 if ((sym->liveTo - sym->liveFrom) == 0)
2761 /* if the live range is a temporary */
2764 debugLog (" %d - itemp register\n", __LINE__);
2766 /* if the type is marked as a conditional */
2767 if (sym->regType == REG_CND)
2770 /* if used in return only then we don't
2772 if (sym->ruonly || sym->accuse) {
2773 if (IS_AGGREGATE (sym->type) || sym->isptr)
2774 sym->type = aggrToPtr (sym->type, FALSE);
2775 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2779 /* if the symbol has only one definition &
2780 that definition is a get_pointer and the
2781 pointer we are getting is rematerializable and
2784 if (bitVectnBitsOn (sym->defs) == 1 &&
2785 (ic = hTabItemWithKey (iCodehTab,
2786 bitVectFirstBit (sym->defs))) &&
2788 !IS_BITVAR (sym->etype) &&
2789 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2791 // continue; /* FIXME -- VR */
2792 if (ptrPseudoSymSafe (sym, ic)) {
2796 debugLog (" %d - \n", __LINE__);
2798 /* create a psuedo symbol & force a spil */
2799 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2800 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2801 psym->type = sym->type;
2802 psym->etype = sym->etype;
2803 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2804 strcpy (psym->rname, psym->name);
2806 SYM_SPIL_LOC (sym) = psym;
2810 /* if in data space or idata space then try to
2811 allocate pointer register */
2815 /* if not then we require registers */
2816 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2817 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2818 getSize (sym->type));
2822 if(IS_PTR_CONST (sym->type)) {
2824 if(IS_CODEPTR (sym->type)) {
2826 // what IS this ???? (HJD)
2827 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2828 sym->nRegs = 3; // patch 14
2831 if (sym->nRegs > 4) {
2832 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2833 printTypeChain (sym->type, stderr);
2834 fprintf (stderr, "\n");
2837 /* determine the type of register required */
2838 if (sym->nRegs == 1 &&
2839 IS_PTR (sym->type) &&
2841 sym->regType = REG_PTR;
2843 sym->regType = REG_GPR;
2846 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2850 /* for the first run we don't provide */
2851 /* registers for true symbols we will */
2852 /* see how things go */
2858 static DEFSETFUNC (markRegFree)
2860 ((regs *)item)->isFree = 1;
2861 // ((regs *)item)->wasUsed = 0;
2866 DEFSETFUNC (pic16_deallocReg)
2868 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2869 ((regs *)item)->isFree = 1;
2870 ((regs *)item)->wasUsed = 0;
2874 /*-----------------------------------------------------------------*/
2875 /* freeAllRegs - mark all registers as free */
2876 /*-----------------------------------------------------------------*/
2878 pic16_freeAllRegs ()
2880 debugLog ("%s\n", __FUNCTION__);
2882 applyToSet(pic16_dynAllocRegs,markRegFree);
2883 applyToSet(pic16_dynStackRegs,markRegFree);
2886 /*-----------------------------------------------------------------*/
2887 /*-----------------------------------------------------------------*/
2889 pic16_deallocateAllRegs ()
2891 debugLog ("%s\n", __FUNCTION__);
2893 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2897 /*-----------------------------------------------------------------*/
2898 /* deallocStackSpil - this will set the stack pointer back */
2899 /*-----------------------------------------------------------------*/
2901 DEFSETFUNC (deallocStackSpil)
2905 debugLog ("%s\n", __FUNCTION__);
2910 /*-----------------------------------------------------------------*/
2911 /* farSpacePackable - returns the packable icode for far variables */
2912 /*-----------------------------------------------------------------*/
2914 farSpacePackable (iCode * ic)
2918 debugLog ("%s\n", __FUNCTION__);
2919 /* go thru till we find a definition for the
2920 symbol on the right */
2921 for (dic = ic->prev; dic; dic = dic->prev)
2924 /* if the definition is a call then no */
2925 if ((dic->op == CALL || dic->op == PCALL) &&
2926 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2931 /* if shift by unknown amount then not */
2932 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2933 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2936 /* if pointer get and size > 1 */
2937 if (POINTER_GET (dic) &&
2938 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2941 if (POINTER_SET (dic) &&
2942 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2945 /* if any three is a true symbol in far space */
2946 if (IC_RESULT (dic) &&
2947 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2948 isOperandInFarSpace (IC_RESULT (dic)))
2951 if (IC_RIGHT (dic) &&
2952 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2953 isOperandInFarSpace (IC_RIGHT (dic)) &&
2954 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2957 if (IC_LEFT (dic) &&
2958 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2959 isOperandInFarSpace (IC_LEFT (dic)) &&
2960 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2963 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2965 if ((dic->op == LEFT_OP ||
2966 dic->op == RIGHT_OP ||
2968 IS_OP_LITERAL (IC_RIGHT (dic)))
2979 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
2983 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2984 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
2985 debugAopGet (" result:", IC_RESULT (ic));
2986 debugAopGet (" left:", IC_LEFT (ic));
2987 debugAopGet (" right:", IC_RIGHT (ic));
2996 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
2998 /*-----------------------------------------------------------------*/
2999 /* packRegsForAssign - register reduction for assignment */
3000 /*-----------------------------------------------------------------*/
3002 packRegsForAssign (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));
3012 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3014 debugLog(" %d - actuall processing\n", __LINE__ );
3016 if (!IS_ITEMP (IC_RESULT (ic))) {
3017 pic16_allocDirReg(IC_RESULT (ic));
3018 debugLog (" %d - result is not temp\n", __LINE__);
3021 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3023 /* See BUGLOG0001 - VR */
3025 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3026 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3027 pic16_allocDirReg(IC_RIGHT (ic));
3032 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3033 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3035 debugLog (" %d - not packing - right side fails \n", __LINE__);
3039 /* if the true symbol is defined in far space or on stack
3040 then we should not since this will increase register pressure */
3041 if (isOperandInFarSpace (IC_RESULT (ic)))
3043 if ((dic = farSpacePackable (ic)))
3050 /* find the definition of iTempNN scanning backwards if we find a
3051 a use of the true symbol before we find the definition then
3053 for (dic = ic->prev; dic; dic = dic->prev)
3056 /* if there is a function call and this is
3057 a parameter & not my parameter then don't pack it */
3058 if ((dic->op == CALL || dic->op == PCALL) &&
3059 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3060 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3062 debugLog (" %d - \n", __LINE__);
3071 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3073 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3074 IS_OP_VOLATILE (IC_RESULT (dic)))
3076 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3082 if( IS_SYMOP( IC_RESULT(dic)) &&
3083 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3085 debugLog (" %d - result is bitfield\n", __LINE__);
3091 if (IS_SYMOP (IC_RESULT (dic)) &&
3092 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3094 /* A previous result was assigned to the same register - we'll our definition */
3095 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3096 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3097 if (POINTER_SET (dic))
3103 if (IS_SYMOP (IC_RIGHT (dic)) &&
3104 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3105 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3107 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3112 if (IS_SYMOP (IC_LEFT (dic)) &&
3113 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3114 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3116 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3121 if (POINTER_SET (dic) &&
3122 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3124 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3132 return 0; /* did not find */
3135 /* This code is taken from the hc08 port. Do not know
3136 * if it fits for pic16, but I leave it here just in case */
3138 /* if assignment then check that right is not a bit */
3139 if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
3140 sym_link *etype = operandType (IC_RESULT (dic));
3142 if (IS_BITFIELD (etype)) {
3143 /* if result is a bit too then it's ok */
3144 etype = operandType (IC_RESULT (ic));
3145 if (!IS_BITFIELD (etype)) {
3146 debugLog(" %d bitfields\n");
3153 /* if the result is on stack or iaccess then it must be
3154 the same atleast one of the operands */
3155 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3156 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3158 /* the operation has only one symbol
3159 operator then we can pack */
3160 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3161 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3164 if (!((IC_LEFT (dic) &&
3165 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3167 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3171 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3172 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3173 /* found the definition */
3174 /* replace the result with the result of */
3175 /* this assignment and remove this assignment */
3178 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3179 IC_RESULT (dic) = IC_RESULT (ic);
3181 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3183 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3185 /* delete from liverange table also
3186 delete from all the points inbetween and the new
3188 for (sic = dic; sic != ic; sic = sic->next)
3190 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3191 if (IS_ITEMP (IC_RESULT (dic)))
3192 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3195 remiCodeFromeBBlock (ebp, ic);
3196 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3198 debugLog(" %d\n", __LINE__ );
3199 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3200 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3207 #define NO_packRegsForAccUse
3208 #define NO_packRegsForSupport
3209 #define NO_packRegsForOneuse
3210 #define NO_cast_peep
3215 #ifndef NO_packRegsForSupport
3216 /*-----------------------------------------------------------------*/
3217 /* findAssignToSym : scanning backwards looks for first assig found */
3218 /*-----------------------------------------------------------------*/
3220 findAssignToSym (operand * op, iCode * ic)
3224 debugLog ("%s\n", __FUNCTION__);
3225 for (dic = ic->prev; dic; dic = dic->prev)
3228 /* if definition by assignment */
3229 if (dic->op == '=' &&
3230 !POINTER_SET (dic) &&
3231 IC_RESULT (dic)->key == op->key
3232 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3236 /* we are interested only if defined in far space */
3237 /* or in stack space in case of + & - */
3239 /* if assigned to a non-symbol then return
3241 if (!IS_SYMOP (IC_RIGHT (dic)))
3244 /* if the symbol is in far space then
3246 if (isOperandInFarSpace (IC_RIGHT (dic)))
3249 /* for + & - operations make sure that
3250 if it is on the stack it is the same
3251 as one of the three operands */
3252 if ((ic->op == '+' || ic->op == '-') &&
3253 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3255 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3256 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3257 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3265 /* if we find an usage then we cannot delete it */
3266 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3269 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3272 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3276 /* now make sure that the right side of dic
3277 is not defined between ic & dic */
3280 iCode *sic = dic->next;
3282 for (; sic != ic; sic = sic->next)
3283 if (IC_RESULT (sic) &&
3284 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3295 #ifndef NO_packRegsForSupport
3296 /*-----------------------------------------------------------------*/
3297 /* packRegsForSupport :- reduce some registers for support calls */
3298 /*-----------------------------------------------------------------*/
3300 packRegsForSupport (iCode * ic, eBBlock * ebp)
3304 debugLog ("%s\n", __FUNCTION__);
3305 /* for the left & right operand :- look to see if the
3306 left was assigned a true symbol in far space in that
3307 case replace them */
3308 if (IS_ITEMP (IC_LEFT (ic)) &&
3309 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3311 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3317 debugAopGet ("removing left:", IC_LEFT (ic));
3319 /* found it we need to remove it from the
3321 for (sic = dic; sic != ic; sic = sic->next)
3322 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3324 IC_LEFT (ic)->operand.symOperand =
3325 IC_RIGHT (dic)->operand.symOperand;
3326 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3327 remiCodeFromeBBlock (ebp, dic);
3328 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3329 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3333 /* do the same for the right operand */
3336 IS_ITEMP (IC_RIGHT (ic)) &&
3337 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3339 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3345 /* if this is a subtraction & the result
3346 is a true symbol in far space then don't pack */
3347 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3349 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3350 if (IN_FARSPACE (SPEC_OCLS (etype)))
3354 debugAopGet ("removing right:", IC_RIGHT (ic));
3356 /* found it we need to remove it from the
3358 for (sic = dic; sic != ic; sic = sic->next)
3359 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3361 IC_RIGHT (ic)->operand.symOperand =
3362 IC_RIGHT (dic)->operand.symOperand;
3363 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3365 remiCodeFromeBBlock (ebp, dic);
3366 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3367 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3376 #ifndef NO_packRegsForOneuse
3377 /*-----------------------------------------------------------------*/
3378 /* packRegsForOneuse : - will reduce some registers for single Use */
3379 /*-----------------------------------------------------------------*/
3381 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3388 debugLog ("%s\n", __FUNCTION__);
3389 /* if returning a literal then do nothing */
3393 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3396 /* only upto 2 bytes since we cannot predict
3397 the usage of b, & acc */
3398 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3406 /* this routine will mark the a symbol as used in one
3407 instruction use only && if the definition is local
3408 (ie. within the basic block) && has only one definition &&
3409 that definition is either a return value from a
3410 function or does not contain any variables in
3414 uses = bitVectCopy (OP_USES (op));
3415 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3416 if (!bitVectIsZero (uses)) /* has other uses */
3421 if (bitVectnBitsOn (OP_USES (op)) > 1)
3425 /* if it has only one defintion */
3426 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3427 return NULL; /* has more than one definition */
3429 /* get that definition */
3431 hTabItemWithKey (iCodehTab,
3432 bitVectFirstBit (OP_DEFS (op)))))
3435 /* found the definition now check if it is local */
3436 if (dic->seq < ebp->fSeq ||
3437 dic->seq > ebp->lSeq)
3438 return NULL; /* non-local */
3440 /* now check if it is the return from
3442 if (dic->op == CALL || dic->op == PCALL)
3444 if (ic->op != SEND && ic->op != RETURN &&
3445 !POINTER_SET(ic) && !POINTER_GET(ic))
3447 OP_SYMBOL (op)->ruonly = 1;
3456 /* otherwise check that the definition does
3457 not contain any symbols in far space */
3458 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3459 isOperandInFarSpace (IC_RIGHT (dic)) ||
3460 IS_OP_RUONLY (IC_LEFT (ic)) ||
3461 IS_OP_RUONLY (IC_RIGHT (ic)))
3466 /* if pointer set then make sure the pointer
3468 if (POINTER_SET (dic) &&
3469 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3472 if (POINTER_GET (dic) &&
3473 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3479 /* also make sure the intervenening instructions
3480 don't have any thing in far space */
3481 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3484 /* if there is an intervening function call then no */
3485 if (dic->op == CALL || dic->op == PCALL)
3487 /* if pointer set then make sure the pointer
3489 if (POINTER_SET (dic) &&
3490 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3493 if (POINTER_GET (dic) &&
3494 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3497 /* if address of & the result is remat then okay */
3498 if (dic->op == ADDRESS_OF &&
3499 OP_SYMBOL (IC_RESULT (dic))->remat)
3502 /* if operand has size of three or more & this
3503 operation is a '*','/' or '%' then 'b' may
3505 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3506 getSize (operandType (op)) >= 2)
3509 /* if left or right or result is in far space */
3510 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3511 isOperandInFarSpace (IC_RIGHT (dic)) ||
3512 isOperandInFarSpace (IC_RESULT (dic)) ||
3513 IS_OP_RUONLY (IC_LEFT (dic)) ||
3514 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3515 IS_OP_RUONLY (IC_RESULT (dic)))
3521 OP_SYMBOL (op)->ruonly = 1;
3528 /*-----------------------------------------------------------------*/
3529 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3530 /*-----------------------------------------------------------------*/
3532 isBitwiseOptimizable (iCode * ic)
3534 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3535 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3537 debugLog ("%s\n", __FUNCTION__);
3538 /* bitwise operations are considered optimizable
3539 under the following conditions (Jean-Louis VERN)
3551 if (IS_LITERAL (rtype) ||
3552 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3559 #ifndef NO_packRegsForAccUse
3561 /*-----------------------------------------------------------------*/
3562 /* packRegsForAccUse - pack registers for acc use */
3563 /*-----------------------------------------------------------------*/
3565 packRegsForAccUse (iCode * ic)
3569 debugLog ("%s\n", __FUNCTION__);
3571 /* if this is an aggregate, e.g. a one byte char array */
3572 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3575 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3577 /* if + or - then it has to be one byte result */
3578 if ((ic->op == '+' || ic->op == '-')
3579 && getSize (operandType (IC_RESULT (ic))) > 1)
3582 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3583 /* if shift operation make sure right side is not a literal */
3584 if (ic->op == RIGHT_OP &&
3585 (isOperandLiteral (IC_RIGHT (ic)) ||
3586 getSize (operandType (IC_RESULT (ic))) > 1))
3589 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3590 if (ic->op == LEFT_OP &&
3591 (isOperandLiteral (IC_RIGHT (ic)) ||
3592 getSize (operandType (IC_RESULT (ic))) > 1))
3595 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3596 if (IS_BITWISE_OP (ic) &&
3597 getSize (operandType (IC_RESULT (ic))) > 1)
3601 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3602 /* has only one definition */
3603 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3606 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3607 /* has only one use */
3608 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3611 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3612 /* and the usage immediately follows this iCode */
3613 if (!(uic = hTabItemWithKey (iCodehTab,
3614 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3617 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3618 if (ic->next != uic)
3621 /* if it is a conditional branch then we definitely can */
3625 if (uic->op == JUMPTABLE)
3628 /* if the usage is not is an assignment
3629 or an arithmetic / bitwise / shift operation then not */
3630 if (POINTER_SET (uic) &&
3631 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3634 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3635 if (uic->op != '=' &&
3636 !IS_ARITHMETIC_OP (uic) &&
3637 !IS_BITWISE_OP (uic) &&
3638 uic->op != LEFT_OP &&
3639 uic->op != RIGHT_OP)
3642 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3643 /* if used in ^ operation then make sure right is not a
3645 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3648 /* if shift operation make sure right side is not a literal */
3649 if (uic->op == RIGHT_OP &&
3650 (isOperandLiteral (IC_RIGHT (uic)) ||
3651 getSize (operandType (IC_RESULT (uic))) > 1))
3654 if (uic->op == LEFT_OP &&
3655 (isOperandLiteral (IC_RIGHT (uic)) ||
3656 getSize (operandType (IC_RESULT (uic))) > 1))
3659 /* make sure that the result of this icode is not on the
3660 stack, since acc is used to compute stack offset */
3661 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3662 OP_SYMBOL (IC_RESULT (uic))->onStack)
3665 /* if either one of them in far space then we cannot */
3666 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3667 isOperandInFarSpace (IC_LEFT (uic))) ||
3668 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3669 isOperandInFarSpace (IC_RIGHT (uic))))
3672 /* if the usage has only one operand then we can */
3673 if (IC_LEFT (uic) == NULL ||
3674 IC_RIGHT (uic) == NULL)
3677 /* make sure this is on the left side if not
3678 a '+' since '+' is commutative */
3679 if (ic->op != '+' &&
3680 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3684 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3685 /* if one of them is a literal then we can */
3686 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3687 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3688 (getSize (operandType (IC_RESULT (uic))) <= 1))
3690 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3695 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3696 /* if the other one is not on stack then we can */
3697 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3698 (IS_ITEMP (IC_RIGHT (uic)) ||
3699 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3700 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3703 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3704 (IS_ITEMP (IC_LEFT (uic)) ||
3705 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3706 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3712 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3713 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3720 /*-----------------------------------------------------------------*/
3721 /* packForPush - hueristics to reduce iCode for pushing */
3722 /*-----------------------------------------------------------------*/
3724 packForReceive (iCode * ic, eBBlock * ebp)
3728 debugLog ("%s\n", __FUNCTION__);
3729 debugAopGet (" result:", IC_RESULT (ic));
3730 debugAopGet (" left:", IC_LEFT (ic));
3731 debugAopGet (" right:", IC_RIGHT (ic));
3736 for (dic = ic->next; dic; dic = dic->next)
3738 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3739 debugLog (" used on left\n");
3740 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3741 debugLog (" used on right\n");
3742 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3743 debugLog (" used on result\n");
3745 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3746 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3750 debugLog (" hey we can remove this unnecessary assign\n");
3752 /*-----------------------------------------------------------------*/
3753 /* packForPush - hueristics to reduce iCode for pushing */
3754 /*-----------------------------------------------------------------*/
3756 packForPush (iCode * ic, eBBlock * ebp)
3761 debugLog ("%s\n", __FUNCTION__);
3762 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3769 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3770 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3771 iLine = printILine(ic);
3772 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3774 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3778 /* must have only definition & one usage */
3779 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3780 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3783 /* find the definition */
3784 if (!(dic = hTabItemWithKey (iCodehTab,
3785 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3788 /* if definition is not assignment,
3789 * or is not pointer (because pointer might have changed) */
3790 if (dic->op != '=' || POINTER_SET (dic))
3793 /* we must ensure that we can use the delete the assignment,
3794 * because the source might have been modified in between.
3795 * Until I know how to fix this, I'll use the adhoc fix
3796 * to check the liveranges */
3797 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3799 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3803 /* we now we know that it has one & only one def & use
3804 and the that the definition is an assignment */
3805 IC_LEFT (ic) = IC_RIGHT (dic);
3807 iLine = printILine(dic);
3808 debugf("remiCodeFromeBBlock: %s\n", iLine);
3811 remiCodeFromeBBlock (ebp, dic);
3812 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3813 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3816 static void printSymType(char * str, sym_link *sl)
3818 if(!pic16_ralloc_debug)return;
3820 debugLog (" %s Symbol type: ",str);
3821 printTypeChain (sl, debugF);
3825 /*-----------------------------------------------------------------*/
3826 /* some debug code to print the symbol S_TYPE. Note that
3827 * the function checkSClass in src/SDCCsymt.c dinks with
3828 * the S_TYPE in ways the PIC port doesn't fully like...*/
3829 /*-----------------------------------------------------------------*/
3830 static void isData(sym_link *sl)
3834 if(!pic16_ralloc_debug)return;
3841 for ( ; sl; sl=sl->next) {
3843 switch (SPEC_SCLS(sl)) {
3844 case S_DATA: fprintf (of, "data "); break;
3845 case S_XDATA: fprintf (of, "xdata "); break;
3846 case S_SFR: fprintf (of, "sfr "); break;
3847 case S_SBIT: fprintf (of, "sbit "); break;
3848 case S_CODE: fprintf (of, "code "); break;
3849 case S_IDATA: fprintf (of, "idata "); break;
3850 case S_PDATA: fprintf (of, "pdata "); break;
3851 case S_LITERAL: fprintf (of, "literal "); break;
3852 case S_STACK: fprintf (of, "stack "); break;
3853 case S_XSTACK: fprintf (of, "xstack "); break;
3854 case S_BIT: fprintf (of, "bit "); break;
3855 case S_EEPROM: fprintf (of, "eeprom "); break;
3863 /*--------------------------------------------------------------------*/
3864 /* pic16_packRegisters - does some transformations to reduce */
3865 /* register pressure */
3867 /*--------------------------------------------------------------------*/
3869 pic16_packRegisters (eBBlock * ebp)
3874 debugLog ("%s\n", __FUNCTION__);
3880 /* look for assignments of the form */
3881 /* iTempNN = TRueSym (someoperation) SomeOperand */
3883 /* TrueSym := iTempNN:1 */
3884 for (ic = ebp->sch; ic; ic = ic->next)
3886 // debugLog("%d\n", __LINE__);
3887 /* find assignment of the form TrueSym := iTempNN:1 */
3888 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3889 change += packRegsForAssign (ic, ebp);
3893 if (POINTER_SET (ic))
3894 debugLog ("pointer is set\n");
3895 debugAopGet (" result:", IC_RESULT (ic));
3896 debugAopGet (" left:", IC_LEFT (ic));
3897 debugAopGet (" right:", IC_RIGHT (ic));
3906 for (ic = ebp->sch; ic; ic = ic->next) {
3908 if(IS_SYMOP ( IC_LEFT(ic))) {
3909 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3911 debugAopGet ("x left:", IC_LEFT (ic));
3913 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3915 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3917 debugLog (" is a pointer\n");
3919 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3920 debugLog (" is a ptr\n");
3922 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3923 debugLog (" is volatile\n");
3927 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3928 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3929 pic16_allocDirReg(IC_LEFT (ic));
3932 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3935 if(IS_SYMOP ( IC_RIGHT(ic))) {
3936 debugAopGet (" right:", IC_RIGHT (ic));
3937 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3940 if(IS_SYMOP ( IC_RESULT(ic))) {
3941 debugAopGet (" result:", IC_RESULT (ic));
3942 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3945 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3946 debugAopGet (" right:", IC_RIGHT (ic));
3947 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3948 // pic16_allocDirReg(IC_RIGHT(ic));
3951 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3952 debugAopGet (" result:", IC_RESULT (ic));
3953 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3954 // pic16_allocDirReg(IC_RESULT(ic));
3958 if (POINTER_SET (ic))
3959 debugLog (" %d - Pointer set\n", __LINE__);
3961 /* Look for two subsequent iCodes with */
3963 /* _c = iTemp & op; */
3964 /* and replace them by */
3967 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3969 && ic->prev->op == '='
3970 && IS_ITEMP (IC_LEFT (ic))
3971 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3972 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3974 iCode* ic_prev = ic->prev;
3975 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3977 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3978 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
3979 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3980 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3981 prev_result_sym->liveTo == ic->seq)
3983 prev_result_sym->liveTo = ic_prev->seq;
3986 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3988 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3990 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
3991 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3992 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3993 remiCodeFromeBBlock (ebp, ic_prev);
3994 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3998 /* if this is an itemp & result of a address of a true sym
3999 then mark this as rematerialisable */
4000 if (ic->op == ADDRESS_OF &&
4001 IS_ITEMP (IC_RESULT (ic)) &&
4002 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4003 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4004 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4007 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4009 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4010 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4011 SPIL_LOC (IC_RESULT (ic)) = NULL;
4015 /* if straight assignment then carry remat flag if
4016 this is the only definition */
4017 if (ic->op == '=' &&
4018 !POINTER_SET (ic) &&
4019 IS_SYMOP (IC_RIGHT (ic)) &&
4020 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4021 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4023 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4025 OP_SYMBOL (IC_RESULT (ic))->remat =
4026 OP_SYMBOL (IC_RIGHT (ic))->remat;
4027 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4028 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4031 /* if this is a +/- operation with a rematerizable
4032 then mark this as rematerializable as well */
4033 if ((ic->op == '+' || ic->op == '-') &&
4034 (IS_SYMOP (IC_LEFT (ic)) &&
4035 IS_ITEMP (IC_RESULT (ic)) &&
4036 OP_SYMBOL (IC_LEFT (ic))->remat &&
4037 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4038 IS_OP_LITERAL (IC_RIGHT (ic))))
4040 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4042 operandLitValue (IC_RIGHT (ic));
4043 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4044 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4045 SPIL_LOC (IC_RESULT (ic)) = NULL;
4050 /* try to optimize FSR0 usage when reading data memory pointers */
4052 if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4053 static int fsr0usage=0;
4056 if(POINTER_GET(ic) /* this is a memory read */
4057 && ic->loop /* this is in a loop */
4059 fprintf(stderr, "might optimize FSR0 usage\n");
4064 /* mark the pointer usages */
4065 if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)))
4067 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4068 debugLog (" marking as a pointer (set) =>");
4069 debugAopGet (" result:", IC_RESULT (ic));
4073 if (POINTER_GET (ic))
4075 if(IS_SYMOP(IC_LEFT(ic))) {
4076 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4077 debugLog (" marking as a pointer (get) =>");
4078 debugAopGet (" left:", IC_LEFT (ic));
4081 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4082 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4083 iCode *dic = ic->prev;
4085 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4087 if(dic && dic->op == '='
4088 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4090 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4093 /* replace prev->left with ic->left */
4094 IC_LEFT(ic) = IC_RIGHT(dic);
4095 IC_RIGHT(ic->prev) = NULL;
4097 /* remove ic->prev iCode (assignment) */
4098 remiCodeFromeBBlock (ebp, dic);
4099 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4102 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4108 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4112 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4113 /* if we are using a symbol on the stack
4114 then we should say pic16_ptrRegReq */
4115 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4116 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4117 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4118 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4119 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4120 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4124 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4125 if (IS_SYMOP (IC_LEFT (ic)))
4126 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4127 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4128 if (IS_SYMOP (IC_RIGHT (ic)))
4129 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4130 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4131 if (IS_SYMOP (IC_RESULT (ic)))
4132 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4133 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4136 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4140 /* if the condition of an if instruction
4141 is defined in the previous instruction then
4142 mark the itemp as a conditional */
4143 if ((IS_CONDITIONAL (ic) ||
4144 ((ic->op == BITWISEAND ||
4147 isBitwiseOptimizable (ic))) &&
4148 ic->next && ic->next->op == IFX &&
4149 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4150 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4153 debugLog (" %d\n", __LINE__);
4154 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4158 debugLog(" %d\n", __LINE__);
4160 #ifndef NO_packRegsForSupport
4161 /* reduce for support function calls */
4162 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4163 packRegsForSupport (ic, ebp);
4166 /* if a parameter is passed, it's in W, so we may not
4167 need to place a copy in a register */
4168 if (ic->op == RECEIVE)
4169 packForReceive (ic, ebp);
4171 #ifndef NO_packRegsForOneuse
4172 /* some cases the redundant moves can
4173 can be eliminated for return statements */
4174 if ((ic->op == RETURN || ic->op == SEND) &&
4175 !isOperandInFarSpace (IC_LEFT (ic)) &&
4177 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4180 #ifndef NO_packRegsForOneuse
4181 /* if pointer set & left has a size more than
4182 one and right is not in far space */
4183 if (POINTER_SET (ic) &&
4184 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4185 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4186 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4187 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4189 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4192 #ifndef NO_packRegsForOneuse
4193 /* if pointer get */
4194 if (POINTER_GET (ic) &&
4195 !isOperandInFarSpace (IC_RESULT (ic)) &&
4196 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4197 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4198 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4200 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4201 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4204 #ifndef NO_cast_peep
4205 /* if this is cast for intergral promotion then
4206 check if only use of the definition of the
4207 operand being casted/ if yes then replace
4208 the result of that arithmetic operation with
4209 this result and get rid of the cast */
4210 if (ic->op == CAST) {
4212 sym_link *fromType = operandType (IC_RIGHT (ic));
4213 sym_link *toType = operandType (IC_LEFT (ic));
4215 debugLog (" %d - casting\n", __LINE__);
4217 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4218 getSize (fromType) != getSize (toType)) {
4221 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4224 if (IS_ARITHMETIC_OP (dic)) {
4225 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4227 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4228 IC_RESULT (dic) = IC_RESULT (ic);
4229 remiCodeFromeBBlock (ebp, ic);
4230 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4231 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4232 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4236 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4240 /* if the type from and type to are the same
4241 then if this is the only use then packit */
4242 if (compareType (operandType (IC_RIGHT (ic)),
4243 operandType (IC_LEFT (ic))) == 1) {
4245 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4248 debugLog(" %d\n", __LINE__);
4250 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4251 IC_RESULT (dic) = IC_RESULT (ic);
4252 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4253 remiCodeFromeBBlock (ebp, ic);
4254 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4255 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4264 /* there are some problems with packing variables
4265 * it seems that the live range estimator doesn't
4266 * estimate correctly the liveranges of some symbols */
4269 iTempNN := (some variable in farspace) V1
4274 if (ic->op == IPUSH)
4276 packForPush (ic, ebp);
4280 #ifndef NO_packRegsForAccUse
4281 /* pack registers for accumulator use, when the
4282 result of an arithmetic or bit wise operation
4283 has only one use, that use is immediately following
4284 the defintion and the using iCode has only one
4285 operand or has two operands but one is literal &
4286 the result of that operation is not on stack then
4287 we can leave the result of this operation in acc:b
4289 if ((IS_ARITHMETIC_OP (ic)
4291 || IS_BITWISE_OP (ic)
4293 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4296 IS_ITEMP (IC_RESULT (ic)) &&
4297 getSize (operandType (IC_RESULT (ic))) <= 1)
4299 packRegsForAccUse (ic);
4306 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4310 if (!pic16_ralloc_debug || !debugF)
4313 for (i = 0; i < count; i++)
4315 fprintf (debugF, "\n----------------------------------------------------------------\n");
4316 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4317 ebbs[i]->entryLabel->name,
4320 ebbs[i]->isLastInLoop);
4321 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4326 fprintf (debugF, "visited %d : hasFcall = %d\n",
4330 fprintf (debugF, "\ndefines bitVector :");
4331 bitVectDebugOn (ebbs[i]->defSet, debugF);
4332 fprintf (debugF, "\nlocal defines bitVector :");
4333 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4334 fprintf (debugF, "\npointers Set bitvector :");
4335 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4336 fprintf (debugF, "\nin pointers Set bitvector :");
4337 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4338 fprintf (debugF, "\ninDefs Set bitvector :");
4339 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4340 fprintf (debugF, "\noutDefs Set bitvector :");
4341 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4342 fprintf (debugF, "\nusesDefs Set bitvector :");
4343 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4344 fprintf (debugF, "\n----------------------------------------------------------------\n");
4345 printiCChain (ebbs[i]->sch, debugF);
4349 void dbg_dumpregusage(void);
4351 /*-----------------------------------------------------------------*/
4352 /* pic16_assignRegisters - assigns registers to each live range as need */
4353 /*-----------------------------------------------------------------*/
4355 pic16_assignRegisters (ebbIndex * ebbi)
4357 eBBlock ** ebbs = ebbi->bbOrder;
4358 int count = ebbi->count;
4362 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4363 debugLog ("\nebbs before optimizing:\n");
4364 dumpEbbsToDebug (ebbs, count);
4366 _inRegAllocator = 1;
4368 pic16_freeAllRegs();
4371 /* clear whats left over from peephole parser */
4372 pic16_dynAllocRegs= newSet(); //NULL;
4373 // pic16_dynStackRegs= newSet(); //NULL;
4374 // pic16_dynProcessorRegs=newSet(); //NULL;
4375 // pic16_dynDirectRegs=newSet(); //NULL;
4376 // pic16_dynDirectBitRegs=newSet(); //NULL;
4377 // pic16_dynInternalRegs=newSet(); //NULL;
4378 // pic16_dynAccessRegs=newSet(); //NULL;
4380 // dynDirectRegNames=NULL;
4381 dynAllocRegNames=NULL;
4382 // dynProcRegNames=NULL;
4383 // dynAccessRegNames=NULL;
4386 setToNull ((void *) &_G.funcrUsed);
4387 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4390 /* change assignments this will remove some
4391 live ranges reducing some register pressure */
4392 for (i = 0; i < count; i++)
4393 pic16_packRegisters (ebbs[i]);
4400 debugLog("dir registers allocated so far:\n");
4401 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4405 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4406 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4407 reg = hTabNextItem(dynDirectRegNames, &hkey);
4413 /* liveranges probably changed by register packing
4414 so we compute them again */
4415 recomputeLiveRanges (ebbs, count);
4417 if (options.dump_pack)
4418 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4420 /* first determine for each live range the number of
4421 registers & the type of registers required for each */
4424 /* start counting function temporary registers from zero */
4425 /* XXX: Resetting dynrIdx breaks register allocation,
4426 * see #1489055, #1483693 (?), and #1445850! */
4429 /* and serially allocate registers */
4430 serialRegAssign (ebbs, count);
4433 debugLog ("ebbs after serialRegAssign:\n");
4434 dumpEbbsToDebug (ebbs, count);
4437 //pic16_freeAllRegs();
4439 /* if stack was extended then tell the user */
4442 /* werror(W_TOOMANY_SPILS,"stack", */
4443 /* _G.stackExtend,currFunc->name,""); */
4449 /* werror(W_TOOMANY_SPILS,"data space", */
4450 /* _G.dataExtend,currFunc->name,""); */
4454 /* after that create the register mask
4455 for each of the instruction */
4456 createRegMask (ebbs, count);
4458 /* redo that offsets for stacked automatic variables */
4459 redoStackOffsets ();
4461 if (options.dump_rassgn)
4462 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4464 // dumpLR(ebbs, count);
4466 /* now get back the chain */
4467 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4469 debugLog ("ebbs after optimizing:\n");
4470 dumpEbbsToDebug (ebbs, count);
4473 _inRegAllocator = 0;
4477 /* free up any _G.stackSpil locations allocated */
4478 applyToSet (_G.stackSpil, deallocStackSpil);
4480 setToNull ((void *) &_G.stackSpil);
4481 setToNull ((void *) &_G.spiltSet);
4482 /* mark all registers as free */
4483 pic16_freeAllRegs ();
4486 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");