1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
41 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
43 void _debugf(char *f, int l, char *frm, ...);
45 #define NEWREG_DEBUG 0
49 /*-----------------------------------------------------------------*/
50 /* At this point we start getting processor specific although */
51 /* some routines are non-processor specific & can be reused when */
52 /* targetting other processors. The decision for this will have */
53 /* to be made on a routine by routine basis */
54 /* routines used to pack registers are most definitely not reusable */
55 /* since the pack the registers depending strictly on the MCU */
56 /*-----------------------------------------------------------------*/
58 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
59 extern void genpic16Code (iCode *);
69 bitVect *funcrUsed; /* registers used in a function */
75 /* Shared with gen.c */
76 int pic16_ptrRegReq; /* one byte pointer register required */
79 set *pic16_dynAllocRegs=NULL;
80 set *pic16_dynStackRegs=NULL;
81 set *pic16_dynProcessorRegs=NULL;
82 set *pic16_dynDirectRegs=NULL;
83 set *pic16_dynDirectBitRegs=NULL;
84 set *pic16_dynInternalRegs=NULL;
85 set *pic16_dynAccessRegs=NULL;
87 static hTab *dynDirectRegNames=NULL;
88 static hTab *dynAllocRegNames=NULL;
89 static hTab *dynProcRegNames=NULL;
90 static hTab *dynAccessRegNames=NULL;
91 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
93 extern set *sectNames;
95 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
96 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
97 set *pic16_equ_data=NULL; /* registers used by equates */
98 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
99 set *pic16_acs_udata=NULL; /* access bank variables */
101 set *pic16_builtin_functions=NULL;
103 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
104 static int rDirectIdx=0;
106 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
108 int pic16_Gstack_base_addr=0; /* The starting address of registers that
109 * are used to pass and return parameters */
112 int _inRegAllocator=0; /* flag that marks whther allocReg happens while
113 * inside the register allocator function */
116 static void spillThis (symbol *);
117 int pic16_ralloc_debug = 0;
118 static FILE *debugF = NULL;
119 /*-----------------------------------------------------------------*/
120 /* debugLog - open a file for debugging information */
121 /*-----------------------------------------------------------------*/
122 //static void debugLog(char *inst,char *fmt, ...)
124 debugLog (char *fmt,...)
126 static int append = 0; // First time through, open the file without append.
129 //char *bufferP=buffer;
132 if (!pic16_ralloc_debug || !dstFileName)
138 /* create the file name */
139 strcpy (buffer, dstFileName);
140 strcat (buffer, ".d");
142 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
144 werror (E_FILE_OPEN_ERR, buffer);
147 append = 1; // Next time debubLog is called, we'll append the debug info
153 vsprintf (buffer, fmt, ap);
155 fprintf (debugF, "%s", buffer);
157 while (isspace((unsigned char)*bufferP)) bufferP++;
159 if (bufferP && *bufferP)
160 lineCurr = (lineCurr ?
161 connectLine(lineCurr,newLineNode(lb)) :
162 (lineHead = newLineNode(lb)));
163 lineCurr->isInline = _G.inLine;
164 lineCurr->isDebug = _G.debugLine;
173 if(!pic16_ralloc_debug)return;
176 fputc ('\n', debugF);
178 /*-----------------------------------------------------------------*/
179 /* debugLogClose - closes the debug log file (if opened) */
180 /*-----------------------------------------------------------------*/
190 #define AOP(op) op->aop
193 debugAopGet (char *str, operand * op)
195 if(!pic16_ralloc_debug)return NULL;
200 printOperand (op, debugF);
207 pic16_decodeOp (unsigned int op)
209 if (op < 128 && op > ' ') {
210 buffer[0] = (op & 0xff);
216 case IDENTIFIER: return "IDENTIFIER";
217 case TYPE_NAME: return "TYPE_NAME";
218 case CONSTANT: return "CONSTANT";
219 case STRING_LITERAL: return "STRING_LITERAL";
220 case SIZEOF: return "SIZEOF";
221 case PTR_OP: return "PTR_OP";
222 case INC_OP: return "INC_OP";
223 case DEC_OP: return "DEC_OP";
224 case LEFT_OP: return "LEFT_OP";
225 case RIGHT_OP: return "RIGHT_OP";
226 case LE_OP: return "LE_OP";
227 case GE_OP: return "GE_OP";
228 case EQ_OP: return "EQ_OP";
229 case NE_OP: return "NE_OP";
230 case AND_OP: return "AND_OP";
231 case OR_OP: return "OR_OP";
232 case MUL_ASSIGN: return "MUL_ASSIGN";
233 case DIV_ASSIGN: return "DIV_ASSIGN";
234 case MOD_ASSIGN: return "MOD_ASSIGN";
235 case ADD_ASSIGN: return "ADD_ASSIGN";
236 case SUB_ASSIGN: return "SUB_ASSIGN";
237 case LEFT_ASSIGN: return "LEFT_ASSIGN";
238 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
239 case AND_ASSIGN: return "AND_ASSIGN";
240 case XOR_ASSIGN: return "XOR_ASSIGN";
241 case OR_ASSIGN: return "OR_ASSIGN";
242 case TYPEDEF: return "TYPEDEF";
243 case EXTERN: return "EXTERN";
244 case STATIC: return "STATIC";
245 case AUTO: return "AUTO";
246 case REGISTER: return "REGISTER";
247 case CODE: return "CODE";
248 case EEPROM: return "EEPROM";
249 case INTERRUPT: return "INTERRUPT";
250 case SFR: return "SFR";
251 case AT: return "AT";
252 case SBIT: return "SBIT";
253 case REENTRANT: return "REENTRANT";
254 case USING: return "USING";
255 case XDATA: return "XDATA";
256 case DATA: return "DATA";
257 case IDATA: return "IDATA";
258 case PDATA: return "PDATA";
259 case VAR_ARGS: return "VAR_ARGS";
260 case CRITICAL: return "CRITICAL";
261 case NONBANKED: return "NONBANKED";
262 case BANKED: return "BANKED";
263 case CHAR: return "CHAR";
264 case SHORT: return "SHORT";
265 case INT: return "INT";
266 case LONG: return "LONG";
267 case SIGNED: return "SIGNED";
268 case UNSIGNED: return "UNSIGNED";
269 case FLOAT: return "FLOAT";
270 case DOUBLE: return "DOUBLE";
271 case CONST: return "CONST";
272 case VOLATILE: return "VOLATILE";
273 case VOID: return "VOID";
274 case BIT: return "BIT";
275 case STRUCT: return "STRUCT";
276 case UNION: return "UNION";
277 case ENUM: return "ENUM";
278 case ELIPSIS: return "ELIPSIS";
279 case RANGE: return "RANGE";
280 case FAR: return "FAR";
281 case CASE: return "CASE";
282 case DEFAULT: return "DEFAULT";
283 case IF: return "IF";
284 case ELSE: return "ELSE";
285 case SWITCH: return "SWITCH";
286 case WHILE: return "WHILE";
287 case DO: return "DO";
288 case FOR: return "FOR";
289 case GOTO: return "GOTO";
290 case CONTINUE: return "CONTINUE";
291 case BREAK: return "BREAK";
292 case RETURN: return "RETURN";
293 case INLINEASM: return "INLINEASM";
294 case IFX: return "IFX";
295 case ADDRESS_OF: return "ADDRESS_OF";
296 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
297 case SPIL: return "SPIL";
298 case UNSPIL: return "UNSPIL";
299 case GETHBIT: return "GETHBIT";
300 case BITWISEAND: return "BITWISEAND";
301 case UNARYMINUS: return "UNARYMINUS";
302 case IPUSH: return "IPUSH";
303 case IPOP: return "IPOP";
304 case PCALL: return "PCALL";
305 case ENDFUNCTION: return "ENDFUNCTION";
306 case JUMPTABLE: return "JUMPTABLE";
307 case RRC: return "RRC";
308 case RLC: return "RLC";
309 case CAST: return "CAST";
310 case CALL: return "CALL";
311 case PARAM: return "PARAM ";
312 case NULLOP: return "NULLOP";
313 case BLOCK: return "BLOCK";
314 case LABEL: return "LABEL";
315 case RECEIVE: return "RECEIVE";
316 case SEND: return "SEND";
317 case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
319 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
323 /*-----------------------------------------------------------------*/
324 /*-----------------------------------------------------------------*/
326 debugLogRegType (short type)
328 if(!pic16_ralloc_debug)return NULL;
330 case REG_GPR: return "REG_GPR";
331 case REG_PTR: return "REG_PTR";
332 case REG_CND: return "REG_CND";
334 sprintf (buffer, "unknown reg type %d", type);
339 /*-----------------------------------------------------------------*/
340 /*-----------------------------------------------------------------*/
341 static int regname2key(char const *name)
350 key += (*name++) + 1;
354 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
358 /*-----------------------------------------------------------------*/
359 /* newReg - allocate and init memory for a new register */
360 /*-----------------------------------------------------------------*/
361 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
366 dReg = Safe_calloc(1,sizeof(regs));
368 dReg->pc_type = pc_type;
371 dReg->name = Safe_strdup(name);
373 sprintf(buffer,"r0x%02X", dReg->rIdx);
374 if(type == REG_STK) {
377 dReg->name = Safe_strdup(buffer);
385 if(type == REG_SFR) {
387 dReg->address = rIdx;
388 dReg->accessBank = 1;
392 dReg->accessBank = 0;
396 fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
400 dReg->reg_alias = NULL;
401 dReg->reglives.usedpFlows = newSet();
402 dReg->reglives.assignedpFlows = newSet();
405 if(!(type == REG_SFR && alias == 0x80))
406 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
411 /*-----------------------------------------------------------------*/
412 /* regWithIdx - Search through a set of registers that matches idx */
413 /*-----------------------------------------------------------------*/
415 regWithIdx (set *dRegs, int idx, unsigned fixed)
419 for (dReg = setFirstItem(dRegs) ; dReg ;
420 dReg = setNextItem(dRegs)) {
422 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
430 /*-----------------------------------------------------------------*/
431 /* regFindFree - Search for a free register in a set of registers */
432 /*-----------------------------------------------------------------*/
434 regFindFree (set *dRegs)
438 for (dReg = setFirstItem(dRegs) ; dReg ;
439 dReg = setNextItem(dRegs)) {
441 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
442 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
453 regFindFreeNext(set *dRegs, regs *creg)
458 /* position at current register */
459 for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
462 for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
471 /*-----------------------------------------------------------------*/
472 /* pic16_initStack - allocate registers for a pseudo stack */
473 /*-----------------------------------------------------------------*/
474 void pic16_initStack(int base_address, int size)
479 pic16_Gstack_base_addr = base_address;
480 //fprintf(stderr,"initStack");
482 for(i = 0; i<size; i++)
483 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
486 /*-----------------------------------------------------------------*
487 *-----------------------------------------------------------------*/
489 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
491 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
493 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
495 reg->wasUsed = 0; // we do not know if they are going to be used at all
496 reg->accessBank = 1; // implicit add access Bank
498 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
500 return addSet(&pic16_dynProcessorRegs, reg);
503 /*-----------------------------------------------------------------*
504 *-----------------------------------------------------------------*/
507 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
509 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
511 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
515 return addSet(&pic16_dynInternalRegs,reg);
522 /*-----------------------------------------------------------------*/
523 /* allocReg - allocates register of given type */
524 /*-----------------------------------------------------------------*/
526 allocReg (short type)
530 #define MAX_P16_NREGS 6
534 if(dynrIdx > pic16_nRegs)
538 /* try to reuse some unused registers */
539 reg = regFindFree( pic16_dynAllocRegs );
542 // fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
546 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
547 // fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
550 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
551 // debugf("allocating more registers than available\n", 0);
556 // addSet(&pic16_dynAllocRegs, reg);
559 addSet(&pic16_dynAllocRegs, reg);
560 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
564 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
567 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
568 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
571 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
572 reg->isLocal = 1; /* this is a local frame register */
577 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
578 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
581 return (reg); // addSet(&pic16_dynAllocRegs,reg);
586 /*-----------------------------------------------------------------*/
587 /* pic16_dirregWithName - search for register by name */
588 /*-----------------------------------------------------------------*/
590 pic16_dirregWithName (char *name)
598 /* hash the name to get a key */
600 hkey = regname2key(name);
602 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
604 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
608 if(STRCASECMP(reg->name, name) == 0) {
609 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
613 reg = hTabNextItemWK (dynDirectRegNames);
617 return NULL; // name wasn't found in the hash table
620 /*-----------------------------------------------------------------*/
621 /* pic16_allocregWithName - search for register by name */
622 /*-----------------------------------------------------------------*/
624 pic16_allocregWithName (char *name)
632 /* hash the name to get a key */
634 hkey = regname2key(name);
636 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
638 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
642 if(STRCASECMP(reg->name, name) == 0) {
646 reg = hTabNextItemWK (dynAllocRegNames);
650 return NULL; // name wasn't found in the hash table
655 /*-----------------------------------------------------------------*/
656 /* pic16_procregWithName - search for register by name */
657 /*-----------------------------------------------------------------*/
659 pic16_procregWithName (char *name)
667 /* hash the name to get a key */
669 hkey = regname2key(name);
671 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
673 reg = hTabFirstItemWK(dynProcRegNames, hkey);
677 if(STRCASECMP(reg->name, name) == 0) {
681 reg = hTabNextItemWK (dynProcRegNames);
685 return NULL; // name wasn't found in the hash table
689 /*-----------------------------------------------------------------*/
690 /* pic16_accessregWithName - search for register by name */
691 /*-----------------------------------------------------------------*/
693 pic16_accessregWithName (char *name)
701 /* hash the name to get a key */
703 hkey = regname2key(name);
705 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
707 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
711 if(STRCASECMP(reg->name, name) == 0) {
715 reg = hTabNextItemWK (dynAccessRegNames);
719 return NULL; // name wasn't found in the hash table
723 regs *pic16_regWithName(char *name)
727 reg = pic16_dirregWithName( name );
730 reg = pic16_procregWithName( name );
733 reg = pic16_allocregWithName( name );
736 reg = pic16_accessregWithName( name );
743 /*-----------------------------------------------------------------*/
744 /* pic16_allocDirReg - allocates register of given type */
745 /*-----------------------------------------------------------------*/
747 pic16_allocDirReg (operand *op )
753 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
754 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
758 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
761 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
763 if(pic16_debug_verbose)
765 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
766 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
772 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
773 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
776 if(pic16_debug_verbose) {
777 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
778 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
779 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
780 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
781 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
782 IN_STACK( OP_SYM_ETYPE(op)),
783 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
784 IS_REGPARM(OP_SYM_ETYPE(op)),
787 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
788 OP_SYMBOL(op)->name);
796 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
797 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
801 if(IS_ITEMP(op))return NULL;
803 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
805 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
807 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
808 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
811 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
812 debugLog(" %d const char\n",__LINE__);
813 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
814 // fprintf(stderr, " %d const char\n",__LINE__);
815 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
819 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
820 if (IS_CODE ( OP_SYM_ETYPE(op)) )
821 debugLog(" %d code space\n",__LINE__);
823 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
824 debugLog(" %d integral\n",__LINE__);
826 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
827 debugLog(" %d literal\n",__LINE__);
829 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
830 debugLog(" %d specifier\n",__LINE__);
832 debugAopGet(NULL, op);
836 reg = pic16_dirregWithName(name);
840 int regtype = REG_GPR;
842 /* if this is at an absolute address, then get the address. */
843 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
844 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
845 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
848 /* Register wasn't found in hash, so let's create
849 * a new one and put it in the hash table AND in the
850 * dynDirectRegNames set */
851 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
852 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
858 if(OP_SYMBOL(op)->onStack) {
859 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
860 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
864 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
865 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
868 if(pic16_debug_verbose)
870 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
871 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
872 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
873 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
874 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
875 IN_STACK( OP_SYM_ETYPE(op)),
876 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
878 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
879 OP_SYMBOL(op)->name);
884 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
885 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
887 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
888 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
892 checkAddReg(&pic16_dynAccessRegs, reg);
893 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
899 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
900 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
901 // reg->type = REG_SFR;
904 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
905 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
906 addSet(&pic16_dynDirectBitRegs, reg);
909 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
910 // addSet(&pic16_dynDirectRegs, reg);
913 if(!(IS_STATIC(OP_SYM_ETYPE(op))
914 && OP_SYMBOL(op)->ival
917 checkAddReg(&pic16_dynDirectRegs, reg);
921 // debugLog (" -- %s is declared at address 0x30000x\n",name);
922 return (reg); /* This was NULL before, but since we found it
923 * why not just return it?! */
926 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
928 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
930 /* work around for user defined registers in access bank */
931 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
932 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
935 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
941 /*-----------------------------------------------------------------*/
942 /* pic16_allocRegByName - allocates register of given type */
943 /*-----------------------------------------------------------------*/
945 pic16_allocRegByName (char *name, int size, operand *op)
951 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
955 /* First, search the hash table to see if there is a register with this name */
956 reg = pic16_dirregWithName(name);
960 /* Register wasn't found in hash, so let's create
961 * a new one and put it in the hash table AND in the
962 * dynDirectRegNames set */
964 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
966 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
968 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
969 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
971 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
972 addSet(&pic16_dynDirectRegs, reg);
978 /*-----------------------------------------------------------------*/
979 /* RegWithIdx - returns pointer to register with index number */
980 /*-----------------------------------------------------------------*/
981 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
986 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
987 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
992 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
994 debugLog ("Found a Dynamic Register!\n");
997 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
998 debugLog ("Found a Direct Register!\n");
1004 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1005 debugLog ("Found a Stack Register!\n");
1010 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1011 debugLog ("Found a Processor Register!\n");
1025 /*-----------------------------------------------------------------*/
1026 /* pic16_regWithIdx - returns pointer to register with index number*/
1027 /*-----------------------------------------------------------------*/
1029 pic16_regWithIdx (int idx)
1033 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1036 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1040 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1047 /*-----------------------------------------------------------------*/
1048 /* pic16_regWithIdx - returns pointer to register with index number */
1049 /*-----------------------------------------------------------------*/
1051 pic16_allocWithIdx (int idx)
1056 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1057 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1059 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1061 debugLog ("Found a Dynamic Register!\n");
1062 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1063 debugLog ("Found a Stack Register!\n");
1064 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1065 debugLog ("Found a Processor Register!\n");
1066 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1067 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1068 debugLog ("Found an Internal Register!\n");
1071 debugLog ("Dynamic Register not found\n");
1074 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1075 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1076 "regWithIdx not found");
1086 /*-----------------------------------------------------------------*/
1087 /*-----------------------------------------------------------------*/
1089 pic16_findFreeReg(short type)
1096 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1098 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1102 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1116 pic16_findFreeRegNext(short type, regs *creg)
1123 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1125 return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1129 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1141 /*-----------------------------------------------------------------*/
1142 /* freeReg - frees a register */
1143 /*-----------------------------------------------------------------*/
1145 freeReg (regs * reg)
1147 debugLog ("%s\n", __FUNCTION__);
1148 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1153 /*-----------------------------------------------------------------*/
1154 /* nFreeRegs - returns number of free registers */
1155 /*-----------------------------------------------------------------*/
1157 nFreeRegs (int type)
1163 /* although I fixed the register allocation/freeing scheme
1164 * the for loop below doesn't give valid results. I do not
1165 * know why yet. -- VR 10-Jan-2003 */
1170 /* dynamically allocate as many as we need and worry about
1171 * fitting them into a PIC later */
1173 debugLog ("%s\n", __FUNCTION__);
1175 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1176 if((reg->type == type) && reg->isFree)nfr++;
1178 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1182 /*-----------------------------------------------------------------*/
1183 /* nfreeRegsType - free registers with type */
1184 /*-----------------------------------------------------------------*/
1186 nfreeRegsType (int type)
1189 debugLog ("%s\n", __FUNCTION__);
1190 if (type == REG_PTR)
1192 if ((nfr = nFreeRegs (type)) == 0)
1193 return nFreeRegs (REG_GPR);
1196 return nFreeRegs (type);
1199 static void writeSetUsedRegs(FILE *of, set *dRegs)
1204 for (dReg = setFirstItem(dRegs) ; dReg ;
1205 dReg = setNextItem(dRegs)) {
1208 fprintf (of, "\t%s\n",dReg->name);
1214 extern void pic16_groupRegistersInSection(set *regset);
1216 extern void pic16_dump_equates(FILE *of, set *equs);
1217 extern void pic16_dump_access(FILE *of, set *section);
1218 //extern void pic16_dump_map(void);
1219 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1220 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1221 extern void pic16_dump_int_registers(FILE *of, set *section);
1222 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1224 extern void pic16_dump_gsection(FILE *of, set *sections);
1226 static void packBits(set *bregs)
1230 regs *bitfield=NULL;
1231 regs *relocbitfield=NULL;
1237 for (regset = bregs ; regset ;
1238 regset = regset->next) {
1240 breg = regset->item;
1241 breg->isBitField = 1;
1242 //fprintf(stderr,"bit reg: %s\n",breg->name);
1245 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1247 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1248 breg->rIdx = breg->address & 7;
1249 breg->address >>= 3;
1252 sprintf (buffer, "fbitfield%02x", breg->address);
1253 //fprintf(stderr,"new bit field\n");
1254 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1255 bitfield->isBitField = 1;
1256 bitfield->isFixed = 1;
1257 bitfield->address = breg->address;
1258 addSet(&pic16_dynDirectRegs,bitfield);
1259 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1261 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1264 breg->reg_alias = bitfield;
1268 if(!relocbitfield || bit_no >7) {
1271 sprintf (buffer, "bitfield%d", byte_no);
1272 //fprintf(stderr,"new relocatable bit field\n");
1273 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1274 relocbitfield->isBitField = 1;
1275 addSet(&pic16_dynDirectRegs,relocbitfield);
1276 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1280 breg->reg_alias = relocbitfield;
1281 breg->address = rDirectIdx; /* byte_no; */
1282 breg->rIdx = bit_no++;
1288 void pic16_writeUsedRegs(FILE *of)
1290 packBits(pic16_dynDirectBitRegs);
1292 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1293 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1295 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1296 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1298 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1299 pic16_groupRegistersInSection(pic16_dynStackRegs);
1301 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1302 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1304 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1305 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1307 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1308 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1310 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1311 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1314 pic16_dump_equates(of, pic16_equ_data);
1316 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1317 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1319 /* dump access bank symbols */
1320 pic16_dump_access(of, pic16_acs_udata);
1322 /* dump initialised data */
1323 pic16_dump_isection(of, rel_idataSymSet, 0);
1324 pic16_dump_isection(of, fix_idataSymSet, 1);
1326 /* dump internal registers */
1327 pic16_dump_int_registers(of, pic16_int_regs);
1329 /* dump generic section variables */
1330 pic16_dump_gsection(of, sectNames);
1332 /* dump other variables */
1333 pic16_dump_usection(of, pic16_rel_udata, 0);
1334 pic16_dump_usection(of, pic16_fix_udata, 1);
1339 /*-----------------------------------------------------------------*/
1340 /* computeSpillable - given a point find the spillable live ranges */
1341 /*-----------------------------------------------------------------*/
1343 computeSpillable (iCode * ic)
1347 debugLog ("%s\n", __FUNCTION__);
1348 /* spillable live ranges are those that are live at this
1349 point . the following categories need to be subtracted
1351 a) - those that are already spilt
1352 b) - if being used by this one
1353 c) - defined by this one */
1355 spillable = bitVectCopy (ic->rlive);
1357 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1359 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1360 bitVectUnSetBit (spillable, ic->defKey);
1361 spillable = bitVectIntersect (spillable, _G.regAssigned);
1366 /*-----------------------------------------------------------------*/
1367 /* noSpilLoc - return true if a variable has no spil location */
1368 /*-----------------------------------------------------------------*/
1370 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1372 debugLog ("%s\n", __FUNCTION__);
1373 return (sym->usl.spillLoc ? 0 : 1);
1376 /*-----------------------------------------------------------------*/
1377 /* hasSpilLoc - will return 1 if the symbol has spil location */
1378 /*-----------------------------------------------------------------*/
1380 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1382 debugLog ("%s\n", __FUNCTION__);
1383 return (sym->usl.spillLoc ? 1 : 0);
1386 /*-----------------------------------------------------------------*/
1387 /* directSpilLoc - will return 1 if the splilocation is in direct */
1388 /*-----------------------------------------------------------------*/
1390 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1392 debugLog ("%s\n", __FUNCTION__);
1393 if (sym->usl.spillLoc &&
1394 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1400 /*-----------------------------------------------------------------*/
1401 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1402 /* but is not used as a pointer */
1403 /*-----------------------------------------------------------------*/
1405 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1407 debugLog ("%s\n", __FUNCTION__);
1408 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1411 /*-----------------------------------------------------------------*/
1412 /* rematable - will return 1 if the remat flag is set */
1413 /*-----------------------------------------------------------------*/
1415 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1417 debugLog ("%s\n", __FUNCTION__);
1421 /*-----------------------------------------------------------------*/
1422 /* notUsedInRemaining - not used or defined in remain of the block */
1423 /*-----------------------------------------------------------------*/
1425 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1427 debugLog ("%s\n", __FUNCTION__);
1428 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1429 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1432 /*-----------------------------------------------------------------*/
1433 /* allLRs - return true for all */
1434 /*-----------------------------------------------------------------*/
1436 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1438 debugLog ("%s\n", __FUNCTION__);
1442 /*-----------------------------------------------------------------*/
1443 /* liveRangesWith - applies function to a given set of live range */
1444 /*-----------------------------------------------------------------*/
1446 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1447 eBBlock * ebp, iCode * ic)
1452 debugLog ("%s\n", __FUNCTION__);
1453 if (!lrs || !lrs->size)
1456 for (i = 1; i < lrs->size; i++)
1459 if (!bitVectBitValue (lrs, i))
1462 /* if we don't find it in the live range
1463 hash table we are in serious trouble */
1464 if (!(sym = hTabItemWithKey (liveRanges, i)))
1466 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1467 "liveRangesWith could not find liveRange");
1471 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1472 addSetHead (&rset, sym);
1479 /*-----------------------------------------------------------------*/
1480 /* leastUsedLR - given a set determines which is the least used */
1481 /*-----------------------------------------------------------------*/
1483 leastUsedLR (set * sset)
1485 symbol *sym = NULL, *lsym = NULL;
1487 debugLog ("%s\n", __FUNCTION__);
1488 sym = lsym = setFirstItem (sset);
1493 for (; lsym; lsym = setNextItem (sset))
1496 /* if usage is the same then prefer
1497 the spill the smaller of the two */
1498 if (lsym->used == sym->used)
1499 if (getSize (lsym->type) < getSize (sym->type))
1503 if (lsym->used < sym->used)
1508 setToNull ((void *) &sset);
1513 /*-----------------------------------------------------------------*/
1514 /* noOverLap - will iterate through the list looking for over lap */
1515 /*-----------------------------------------------------------------*/
1517 noOverLap (set * itmpStack, symbol * fsym)
1520 debugLog ("%s\n", __FUNCTION__);
1523 for (sym = setFirstItem (itmpStack); sym;
1524 sym = setNextItem (itmpStack))
1526 if (sym->liveTo > fsym->liveFrom)
1534 /*-----------------------------------------------------------------*/
1535 /* isFree - will return 1 if the a free spil location is found */
1536 /*-----------------------------------------------------------------*/
1541 V_ARG (symbol **, sloc);
1542 V_ARG (symbol *, fsym);
1544 debugLog ("%s\n", __FUNCTION__);
1545 /* if already found */
1549 /* if it is free && and the itmp assigned to
1550 this does not have any overlapping live ranges
1551 with the one currently being assigned and
1552 the size can be accomodated */
1554 noOverLap (sym->usl.itmpStack, fsym) &&
1555 getSize (sym->type) >= getSize (fsym->type))
1564 /*-----------------------------------------------------------------*/
1565 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1566 /*-----------------------------------------------------------------*/
1568 spillLRWithPtrReg (symbol * forSym)
1574 debugLog ("%s\n", __FUNCTION__);
1575 if (!_G.regAssigned ||
1576 bitVectIsZero (_G.regAssigned))
1579 r0 = pic16_regWithIdx (R0_IDX);
1580 r1 = pic16_regWithIdx (R1_IDX);
1582 /* for all live ranges */
1583 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1584 lrsym = hTabNextItem (liveRanges, &k))
1588 /* if no registers assigned to it or
1590 /* if it does not overlap with this then
1591 not need to spill it */
1593 if (lrsym->isspilt || !lrsym->nRegs ||
1594 (lrsym->liveTo < forSym->liveFrom))
1597 /* go thru the registers : if it is either
1598 r0 or r1 then spil it */
1599 for (j = 0; j < lrsym->nRegs; j++)
1600 if (lrsym->regs[j] == r0 ||
1601 lrsym->regs[j] == r1)
1610 /*-----------------------------------------------------------------*/
1611 /* createStackSpil - create a location on the stack to spil */
1612 /*-----------------------------------------------------------------*/
1614 createStackSpil (symbol * sym)
1616 symbol *sloc = NULL;
1617 int useXstack, model, noOverlay;
1619 char slocBuffer[30];
1620 debugLog ("%s\n", __FUNCTION__);
1622 /* first go try and find a free one that is already
1623 existing on the stack */
1624 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1626 /* found a free one : just update & return */
1627 sym->usl.spillLoc = sloc;
1630 addSetHead (&sloc->usl.itmpStack, sym);
1634 /* could not then have to create one , this is the hard part
1635 we need to allocate this on the stack : this is really a
1636 hack!! but cannot think of anything better at this time */
1638 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1640 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1641 __FILE__, __LINE__);
1645 sloc = newiTemp (slocBuffer);
1647 /* set the type to the spilling symbol */
1648 sloc->type = copyLinkChain (sym->type);
1649 sloc->etype = getSpec (sloc->type);
1650 SPEC_SCLS (sloc->etype) = S_DATA;
1651 SPEC_EXTR (sloc->etype) = 0;
1652 SPEC_STAT (sloc->etype) = 0;
1654 /* we don't allow it to be allocated`
1655 onto the external stack since : so we
1656 temporarily turn it off ; we also
1657 turn off memory model to prevent
1658 the spil from going to the external storage
1659 and turn off overlaying
1662 useXstack = options.useXstack;
1663 model = options.model;
1664 noOverlay = options.noOverlay;
1665 options.noOverlay = 1;
1666 options.model = options.useXstack = 0;
1670 options.useXstack = useXstack;
1671 options.model = model;
1672 options.noOverlay = noOverlay;
1673 sloc->isref = 1; /* to prevent compiler warning */
1675 /* if it is on the stack then update the stack */
1676 if (IN_STACK (sloc->etype))
1678 currFunc->stack += getSize (sloc->type);
1679 _G.stackExtend += getSize (sloc->type);
1682 _G.dataExtend += getSize (sloc->type);
1684 /* add it to the _G.stackSpil set */
1685 addSetHead (&_G.stackSpil, sloc);
1686 sym->usl.spillLoc = sloc;
1689 /* add it to the set of itempStack set
1690 of the spill location */
1691 addSetHead (&sloc->usl.itmpStack, sym);
1695 /*-----------------------------------------------------------------*/
1696 /* isSpiltOnStack - returns true if the spil location is on stack */
1697 /*-----------------------------------------------------------------*/
1699 isSpiltOnStack (symbol * sym)
1703 debugLog ("%s\n", __FUNCTION__);
1710 /* if (sym->_G.stackSpil) */
1713 if (!sym->usl.spillLoc)
1716 etype = getSpec (sym->usl.spillLoc->type);
1717 if (IN_STACK (etype))
1723 /*-----------------------------------------------------------------*/
1724 /* spillThis - spils a specific operand */
1725 /*-----------------------------------------------------------------*/
1727 spillThis (symbol * sym)
1730 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1732 /* if this is rematerializable or has a spillLocation
1733 we are okay, else we need to create a spillLocation
1735 if (!(sym->remat || sym->usl.spillLoc))
1736 createStackSpil (sym);
1739 /* mark it has spilt & put it in the spilt set */
1741 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1743 bitVectUnSetBit (_G.regAssigned, sym->key);
1745 for (i = 0; i < sym->nRegs; i++)
1749 freeReg (sym->regs[i]);
1750 sym->regs[i] = NULL;
1753 /* if spilt on stack then free up r0 & r1
1754 if they could have been assigned to some
1756 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1759 spillLRWithPtrReg (sym);
1762 if (sym->usl.spillLoc && !sym->remat)
1763 sym->usl.spillLoc->allocreq = 1;
1767 /*-----------------------------------------------------------------*/
1768 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1769 /*-----------------------------------------------------------------*/
1771 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1773 bitVect *lrcs = NULL;
1777 debugLog ("%s\n", __FUNCTION__);
1778 /* get the spillable live ranges */
1779 lrcs = computeSpillable (ic);
1781 /* get all live ranges that are rematerizable */
1782 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1785 /* return the least used of these */
1786 return leastUsedLR (selectS);
1789 /* get live ranges with spillLocations in direct space */
1790 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1792 sym = leastUsedLR (selectS);
1793 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1794 sym->usl.spillLoc->rname :
1795 sym->usl.spillLoc->name));
1797 /* mark it as allocation required */
1798 sym->usl.spillLoc->allocreq = 1;
1802 /* if the symbol is local to the block then */
1803 if (forSym->liveTo < ebp->lSeq)
1806 /* check if there are any live ranges allocated
1807 to registers that are not used in this block */
1808 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1810 sym = leastUsedLR (selectS);
1811 /* if this is not rematerializable */
1820 /* check if there are any live ranges that not
1821 used in the remainder of the block */
1822 if (!_G.blockSpil &&
1823 !isiCodeInFunctionCall (ic) &&
1824 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1826 sym = leastUsedLR (selectS);
1829 sym->remainSpil = 1;
1836 /* find live ranges with spillocation && not used as pointers */
1837 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1840 sym = leastUsedLR (selectS);
1841 /* mark this as allocation required */
1842 sym->usl.spillLoc->allocreq = 1;
1846 /* find live ranges with spillocation */
1847 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1850 sym = leastUsedLR (selectS);
1851 sym->usl.spillLoc->allocreq = 1;
1855 /* couldn't find then we need to create a spil
1856 location on the stack , for which one? the least
1858 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1861 /* return a created spil location */
1862 sym = createStackSpil (leastUsedLR (selectS));
1863 sym->usl.spillLoc->allocreq = 1;
1867 /* this is an extreme situation we will spill
1868 this one : happens very rarely but it does happen */
1874 /*-----------------------------------------------------------------*/
1875 /* spilSomething - spil some variable & mark registers as free */
1876 /*-----------------------------------------------------------------*/
1878 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1883 debugLog ("%s\n", __FUNCTION__);
1884 /* get something we can spil */
1885 ssym = selectSpil (ic, ebp, forSym);
1887 /* mark it as spilt */
1889 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1891 /* mark it as not register assigned &
1892 take it away from the set */
1893 bitVectUnSetBit (_G.regAssigned, ssym->key);
1895 /* mark the registers as free */
1896 for (i = 0; i < ssym->nRegs; i++)
1898 freeReg (ssym->regs[i]);
1900 /* if spilt on stack then free up r0 & r1
1901 if they could have been assigned to as gprs */
1902 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1905 spillLRWithPtrReg (ssym);
1908 /* if this was a block level spil then insert push & pop
1909 at the start & end of block respectively */
1910 if (ssym->blockSpil)
1912 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1913 /* add push to the start of the block */
1914 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1915 ebp->sch->next : ebp->sch));
1916 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1917 /* add pop to the end of the block */
1918 addiCodeToeBBlock (ebp, nic, NULL);
1921 /* if spilt because not used in the remainder of the
1922 block then add a push before this instruction and
1923 a pop at the end of the block */
1924 if (ssym->remainSpil)
1927 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1928 /* add push just before this instruction */
1929 addiCodeToeBBlock (ebp, nic, ic);
1931 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1932 /* add pop to the end of the block */
1933 addiCodeToeBBlock (ebp, nic, NULL);
1942 /*-----------------------------------------------------------------*/
1943 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1944 /*-----------------------------------------------------------------*/
1946 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1951 debugLog ("%s\n", __FUNCTION__);
1953 /* try for a ptr type */
1954 if ((reg = allocReg (REG_PTR)))
1957 /* try for gpr type */
1958 if ((reg = allocReg (REG_GPR)))
1961 /* we have to spil */
1962 if (!spilSomething (ic, ebp, sym))
1965 /* make sure partially assigned registers aren't reused */
1966 for (j=0; j<=sym->nRegs; j++)
1968 sym->regs[j]->isFree = 0;
1970 /* this looks like an infinite loop but
1971 in really selectSpil will abort */
1975 /*-----------------------------------------------------------------*/
1976 /* getRegGpr - will try for GPR if not spil */
1977 /*-----------------------------------------------------------------*/
1979 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1984 debugLog ("%s\n", __FUNCTION__);
1986 /* try for gpr type */
1987 if ((reg = allocReg (REG_GPR)))
1990 if (!pic16_ptrRegReq)
1991 if ((reg = allocReg (REG_PTR)))
1994 /* we have to spil */
1995 if (!spilSomething (ic, ebp, sym))
1998 /* make sure partially assigned registers aren't reused */
1999 for (j=0; j<=sym->nRegs; j++)
2001 sym->regs[j]->isFree = 0;
2003 /* this looks like an infinite loop but
2004 in really selectSpil will abort */
2008 /*-----------------------------------------------------------------*/
2009 /* symHasReg - symbol has a given register */
2010 /*-----------------------------------------------------------------*/
2012 symHasReg (symbol * sym, regs * reg)
2016 debugLog ("%s\n", __FUNCTION__);
2017 for (i = 0; i < sym->nRegs; i++)
2018 if (sym->regs[i] == reg)
2024 /*-----------------------------------------------------------------*/
2025 /* deassignLRs - check the live to and if they have registers & are */
2026 /* not spilt then free up the registers */
2027 /*-----------------------------------------------------------------*/
2029 deassignLRs (iCode * ic, eBBlock * ebp)
2035 debugLog ("%s\n", __FUNCTION__);
2036 for (sym = hTabFirstItem (liveRanges, &k); sym;
2037 sym = hTabNextItem (liveRanges, &k))
2040 symbol *psym = NULL;
2041 /* if it does not end here */
2042 if (sym->liveTo > ic->seq)
2045 /* if it was spilt on stack then we can
2046 mark the stack spil location as free */
2051 sym->usl.spillLoc->isFree = 1;
2057 if (!bitVectBitValue (_G.regAssigned, sym->key))
2060 /* special case for shifting: there is a case where shift count
2061 * can be allocated in the same register as the result, so do not
2062 * free right registers if same as result registers, cause genShiftLeft
2063 * will fail -- VR */
2064 if(ic->op == LEFT_OP)
2067 /* special case check if this is an IFX &
2068 the privious one was a pop and the
2069 previous one was not spilt then keep track
2071 if (ic->op == IFX && ic->prev &&
2072 ic->prev->op == IPOP &&
2073 !ic->prev->parmPush &&
2074 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2075 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2081 bitVectUnSetBit (_G.regAssigned, sym->key);
2083 /* if the result of this one needs registers
2084 and does not have it then assign it right
2086 if (IC_RESULT (ic) &&
2087 !(SKIP_IC2 (ic) || /* not a special icode */
2088 ic->op == JUMPTABLE ||
2093 POINTER_SET (ic)) &&
2094 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2095 result->liveTo > ic->seq && /* and will live beyond this */
2096 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2097 result->liveFrom == ic->seq && /* does not start before here */
2098 result->regType == sym->regType && /* same register types */
2099 result->nRegs && /* which needs registers */
2100 !result->isspilt && /* and does not already have them */
2102 !bitVectBitValue (_G.regAssigned, result->key) &&
2103 /* the number of free regs + number of regs in this LR
2104 can accomodate the what result Needs */
2105 ((nfreeRegsType (result->regType) +
2106 sym->nRegs) >= result->nRegs)
2110 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2112 result->regs[i] = sym->regs[i];
2114 result->regs[i] = getRegGpr (ic, ebp, result);
2116 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2120 /* free the remaining */
2121 for (; i < sym->nRegs; i++)
2125 if (!symHasReg (psym, sym->regs[i]))
2126 freeReg (sym->regs[i]);
2129 freeReg (sym->regs[i]);
2136 /*-----------------------------------------------------------------*/
2137 /* reassignLR - reassign this to registers */
2138 /*-----------------------------------------------------------------*/
2140 reassignLR (operand * op)
2142 symbol *sym = OP_SYMBOL (op);
2145 debugLog ("%s\n", __FUNCTION__);
2146 /* not spilt any more */
2147 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2148 bitVectUnSetBit (_G.spiltSet, sym->key);
2150 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2154 for (i = 0; i < sym->nRegs; i++)
2155 sym->regs[i]->isFree = 0;
2158 /*-----------------------------------------------------------------*/
2159 /* willCauseSpill - determines if allocating will cause a spill */
2160 /*-----------------------------------------------------------------*/
2162 willCauseSpill (int nr, int rt)
2164 debugLog ("%s\n", __FUNCTION__);
2165 /* first check if there are any avlb registers
2166 of te type required */
2169 /* special case for pointer type
2170 if pointer type not avlb then
2171 check for type gpr */
2172 if (nFreeRegs (rt) >= nr)
2174 if (nFreeRegs (REG_GPR) >= nr)
2179 if (pic16_ptrRegReq)
2181 if (nFreeRegs (rt) >= nr)
2186 if (nFreeRegs (REG_PTR) +
2187 nFreeRegs (REG_GPR) >= nr)
2192 debugLog (" ... yep it will (cause a spill)\n");
2193 /* it will cause a spil */
2197 /*-----------------------------------------------------------------*/
2198 /* positionRegs - the allocator can allocate same registers to res- */
2199 /* ult and operand, if this happens make sure they are in the same */
2200 /* position as the operand otherwise chaos results */
2201 /*-----------------------------------------------------------------*/
2203 positionRegs (symbol * result, symbol * opsym, int lineno)
2205 int count = min (result->nRegs, opsym->nRegs);
2206 int i, j = 0, shared = 0;
2208 debugLog ("%s\n", __FUNCTION__);
2209 /* if the result has been spilt then cannot share */
2214 /* first make sure that they actually share */
2215 for (i = 0; i < count; i++)
2217 for (j = 0; j < count; j++)
2219 if (result->regs[i] == opsym->regs[j] && i != j)
2229 regs *tmp = result->regs[i];
2230 result->regs[i] = result->regs[j];
2231 result->regs[j] = tmp;
2236 /*------------------------------------------------------------------*/
2237 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2238 /* it should either have registers or have beed spilled. Otherwise, */
2239 /* there was an uninitialized variable, so just spill this to get */
2240 /* the operand in a valid state. */
2241 /*------------------------------------------------------------------*/
2243 verifyRegsAssigned (operand *op, iCode * ic)
2248 if (!IS_ITEMP (op)) return;
2250 sym = OP_SYMBOL (op);
2251 if (sym->isspilt) return;
2252 if (!sym->nRegs) return;
2253 if (sym->regs[0]) return;
2255 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2256 sym->prereqv ? sym->prereqv->name : sym->name);
2261 /*-----------------------------------------------------------------*/
2262 /* serialRegAssign - serially allocate registers to the variables */
2263 /*-----------------------------------------------------------------*/
2265 serialRegAssign (eBBlock ** ebbs, int count)
2270 debugLog ("%s\n", __FUNCTION__);
2271 /* for all blocks */
2272 for (i = 0; i < count; i++)
2274 if (ebbs[i]->noPath &&
2275 (ebbs[i]->entryLabel != entryLabel &&
2276 ebbs[i]->entryLabel != returnLabel))
2279 /* of all instructions do */
2280 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2283 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2285 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2286 pic16_allocDirReg(IC_RESULT(ic));
2288 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2289 pic16_allocDirReg(IC_LEFT(ic));
2291 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2292 pic16_allocDirReg(IC_RIGHT(ic));
2294 /* if this is an ipop that means some live
2295 range will have to be assigned again */
2297 reassignLR (IC_LEFT (ic));
2299 /* if result is present && is a true symbol */
2300 if (IC_RESULT (ic) && ic->op != IFX &&
2301 IS_TRUE_SYMOP (IC_RESULT (ic)))
2302 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2304 /* take away registers from live
2305 ranges that end at this instruction */
2306 deassignLRs (ic, ebbs[i]);
2308 /* some don't need registers */
2309 if (SKIP_IC2 (ic) ||
2310 ic->op == JUMPTABLE ||
2314 (IC_RESULT (ic) && POINTER_SET (ic)))
2317 /* now we need to allocate registers
2318 only for the result */
2321 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2327 /* Make sure any spill location is definately allocated */
2328 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2329 !sym->usl.spillLoc->allocreq)
2331 sym->usl.spillLoc->allocreq++;
2334 /* if it does not need or is spilt
2335 or is already assigned to registers
2336 or will not live beyond this instructions */
2339 bitVectBitValue (_G.regAssigned, sym->key) ||
2340 sym->liveTo <= ic->seq)
2343 /* if some liverange has been spilt at the block level
2344 and this one live beyond this block then spil this
2346 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2351 /* if trying to allocate this will cause
2352 a spill and there is nothing to spill
2353 or this one is rematerializable then
2355 willCS = willCauseSpill (sym->nRegs, sym->regType);
2357 /* explicit turn off register spilling */
2360 spillable = computeSpillable (ic);
2362 (willCS && bitVectIsZero (spillable)))
2370 /* If the live range preceeds the point of definition
2371 then ideally we must take into account registers that
2372 have been allocated after sym->liveFrom but freed
2373 before ic->seq. This is complicated, so spill this
2374 symbol instead and let fillGaps handle the allocation. */
2376 if (sym->liveFrom < ic->seq)
2382 /* if it has a spillocation & is used less than
2383 all other live ranges then spill this */
2385 if (sym->usl.spillLoc) {
2386 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2387 allLRs, ebbs[i], ic));
2388 if (leastUsed && leastUsed->used > sym->used) {
2393 /* if none of the liveRanges have a spillLocation then better
2394 to spill this one than anything else already assigned to registers */
2395 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2396 /* if this is local to this block then we might find a block spil */
2397 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2405 if (ic->op == RECEIVE)
2406 debugLog ("When I get clever, I'll optimize the receive logic\n");
2408 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2409 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2410 && (ic->next->op == IFX)
2411 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2413 /* skip register allocation since none will be used */
2414 for(j=0;j<sym->nRegs;j++)
2415 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2416 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2421 /* if we need ptr regs for the right side
2423 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2424 <= (unsigned) PTRSIZE)
2429 /* else we assign registers to it */
2430 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2433 bitVectDebugOn(_G.regAssigned, debugF);
2435 for (j = 0; j < sym->nRegs; j++)
2437 if (sym->regType == REG_PTR)
2438 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2440 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2442 /* if the allocation falied which means
2443 this was spilt then break */
2447 debugLog (" %d - \n", __LINE__);
2449 /* if it shares registers with operands make sure
2450 that they are in the same position */
2451 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2452 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2453 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2454 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2455 /* do the same for the right operand */
2456 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2457 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2458 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2459 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2461 debugLog (" %d - \n", __LINE__);
2464 debugLog (" %d - \n", __LINE__);
2473 /* Check for and fix any problems with uninitialized operands */
2474 for (i = 0; i < count; i++)
2478 if (ebbs[i]->noPath &&
2479 (ebbs[i]->entryLabel != entryLabel &&
2480 ebbs[i]->entryLabel != returnLabel))
2483 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2490 verifyRegsAssigned (IC_COND (ic), ic);
2494 if (ic->op == JUMPTABLE)
2496 verifyRegsAssigned (IC_JTCOND (ic), ic);
2500 verifyRegsAssigned (IC_RESULT (ic), ic);
2501 verifyRegsAssigned (IC_LEFT (ic), ic);
2502 verifyRegsAssigned (IC_RIGHT (ic), ic);
2508 /*-----------------------------------------------------------------*/
2509 /* rUmaskForOp :- returns register mask for an operand */
2510 /*-----------------------------------------------------------------*/
2512 rUmaskForOp (operand * op)
2518 debugLog ("%s\n", __FUNCTION__);
2519 /* only temporaries are assigned registers */
2523 sym = OP_SYMBOL (op);
2525 /* if spilt or no registers assigned to it
2527 if (sym->isspilt || !sym->nRegs)
2530 rumask = newBitVect (pic16_nRegs);
2532 for (j = 0; j < sym->nRegs; j++)
2534 rumask = bitVectSetBit (rumask,
2535 sym->regs[j]->rIdx);
2541 /*-----------------------------------------------------------------*/
2542 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2543 /*-----------------------------------------------------------------*/
2545 regsUsedIniCode (iCode * ic)
2547 bitVect *rmask = newBitVect (pic16_nRegs);
2549 debugLog ("%s\n", __FUNCTION__);
2550 /* do the special cases first */
2553 rmask = bitVectUnion (rmask,
2554 rUmaskForOp (IC_COND (ic)));
2558 /* for the jumptable */
2559 if (ic->op == JUMPTABLE)
2561 rmask = bitVectUnion (rmask,
2562 rUmaskForOp (IC_JTCOND (ic)));
2567 /* of all other cases */
2569 rmask = bitVectUnion (rmask,
2570 rUmaskForOp (IC_LEFT (ic)));
2574 rmask = bitVectUnion (rmask,
2575 rUmaskForOp (IC_RIGHT (ic)));
2578 rmask = bitVectUnion (rmask,
2579 rUmaskForOp (IC_RESULT (ic)));
2585 /*-----------------------------------------------------------------*/
2586 /* createRegMask - for each instruction will determine the regsUsed */
2587 /*-----------------------------------------------------------------*/
2589 createRegMask (eBBlock ** ebbs, int count)
2593 debugLog ("%s\n", __FUNCTION__);
2594 /* for all blocks */
2595 for (i = 0; i < count; i++)
2599 if (ebbs[i]->noPath &&
2600 (ebbs[i]->entryLabel != entryLabel &&
2601 ebbs[i]->entryLabel != returnLabel))
2604 /* for all instructions */
2605 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2610 if (SKIP_IC2 (ic) || !ic->rlive)
2613 /* first mark the registers used in this
2615 ic->rUsed = regsUsedIniCode (ic);
2616 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2618 /* now create the register mask for those
2619 registers that are in use : this is a
2620 super set of ic->rUsed */
2621 ic->rMask = newBitVect (pic16_nRegs + 1);
2623 /* for all live Ranges alive at this point */
2624 for (j = 1; j < ic->rlive->size; j++)
2629 /* if not alive then continue */
2630 if (!bitVectBitValue (ic->rlive, j))
2633 /* find the live range we are interested in */
2634 if (!(sym = hTabItemWithKey (liveRanges, j)))
2636 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2637 "createRegMask cannot find live range");
2641 /* if no register assigned to it */
2642 if (!sym->nRegs || sym->isspilt)
2645 /* for all the registers allocated to it */
2646 for (k = 0; k < sym->nRegs; k++)
2649 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2655 /*-----------------------------------------------------------------*/
2656 /* rematStr - returns the rematerialized string for a remat var */
2657 /*-----------------------------------------------------------------*/
2659 rematStr (symbol * sym)
2662 iCode *ic = sym->rematiCode;
2663 symbol *psym = NULL;
2665 debugLog ("%s\n", __FUNCTION__);
2667 //printf ("%s\n", s);
2669 /* if plus or minus print the right hand side */
2671 if (ic->op == '+' || ic->op == '-') {
2673 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2675 sprintf (s, "(%s %c 0x%04x)",
2676 OP_SYMBOL (IC_LEFT (ric))->rname,
2678 (int) operandLitValue (IC_RIGHT (ic)));
2681 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2683 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2684 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2689 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2690 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2692 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2697 /*-----------------------------------------------------------------*/
2698 /* rematStr - returns the rematerialized string for a remat var */
2699 /*-----------------------------------------------------------------*/
2701 rematStr (symbol * sym)
2704 iCode *ic = sym->rematiCode;
2706 debugLog ("%s\n", __FUNCTION__);
2711 /* if plus or minus print the right hand side */
2713 if (ic->op == '+' || ic->op == '-') {
2714 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2717 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2721 if (ic->op == '+' || ic->op == '-')
2723 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2724 sprintf (s, "(%s %c 0x%04x)",
2725 OP_SYMBOL (IC_LEFT (ric))->rname,
2727 (int) operandLitValue (IC_RIGHT (ic)));
2730 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2732 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2736 /* we reached the end */
2737 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2741 printf ("%s\n", buffer);
2746 /*-----------------------------------------------------------------*/
2747 /* regTypeNum - computes the type & number of registers required */
2748 /*-----------------------------------------------------------------*/
2756 debugLog ("%s\n", __FUNCTION__);
2757 /* for each live range do */
2758 for (sym = hTabFirstItem (liveRanges, &k); sym;
2759 sym = hTabNextItem (liveRanges, &k)) {
2761 debugLog (" %d - %s\n", __LINE__, sym->rname);
2762 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2764 /* if used zero times then no registers needed */
2765 if ((sym->liveTo - sym->liveFrom) == 0)
2769 /* if the live range is a temporary */
2772 debugLog (" %d - itemp register\n", __LINE__);
2774 /* if the type is marked as a conditional */
2775 if (sym->regType == REG_CND)
2778 /* if used in return only then we don't
2780 if (sym->ruonly || sym->accuse) {
2781 if (IS_AGGREGATE (sym->type) || sym->isptr)
2782 sym->type = aggrToPtr (sym->type, FALSE);
2783 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2787 /* if the symbol has only one definition &
2788 that definition is a get_pointer and the
2789 pointer we are getting is rematerializable and
2792 if (bitVectnBitsOn (sym->defs) == 1 &&
2793 (ic = hTabItemWithKey (iCodehTab,
2794 bitVectFirstBit (sym->defs))) &&
2796 !IS_BITVAR (sym->etype) &&
2797 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2799 if (ptrPseudoSymSafe (sym, ic)) {
2803 debugLog (" %d - \n", __LINE__);
2805 /* create a psuedo symbol & force a spil */
2806 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2807 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2808 psym->type = sym->type;
2809 psym->etype = sym->etype;
2810 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2811 strcpy (psym->rname, psym->name);
2813 sym->usl.spillLoc = psym;
2817 /* if in data space or idata space then try to
2818 allocate pointer register */
2822 /* if not then we require registers */
2823 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2824 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2825 getSize (sym->type));
2829 if(IS_PTR_CONST (sym->type)) {
2831 if(IS_CODEPTR (sym->type)) {
2833 // what IS this ???? (HJD)
2834 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2835 sym->nRegs = 3; // patch 14
2838 if (sym->nRegs > 4) {
2839 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2840 printTypeChain (sym->type, stderr);
2841 fprintf (stderr, "\n");
2844 /* determine the type of register required */
2845 if (sym->nRegs == 1 &&
2846 IS_PTR (sym->type) &&
2848 sym->regType = REG_PTR;
2850 sym->regType = REG_GPR;
2853 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2857 /* for the first run we don't provide */
2858 /* registers for true symbols we will */
2859 /* see how things go */
2865 static DEFSETFUNC (markRegFree)
2867 ((regs *)item)->isFree = 1;
2872 DEFSETFUNC (pic16_deallocReg)
2874 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2875 ((regs *)item)->isFree = 1;
2876 ((regs *)item)->wasUsed = 0;
2880 /*-----------------------------------------------------------------*/
2881 /* freeAllRegs - mark all registers as free */
2882 /*-----------------------------------------------------------------*/
2884 pic16_freeAllRegs ()
2886 debugLog ("%s\n", __FUNCTION__);
2888 applyToSet(pic16_dynAllocRegs,markRegFree);
2889 applyToSet(pic16_dynStackRegs,markRegFree);
2892 /*-----------------------------------------------------------------*/
2893 /*-----------------------------------------------------------------*/
2895 pic16_deallocateAllRegs ()
2897 debugLog ("%s\n", __FUNCTION__);
2899 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2903 /*-----------------------------------------------------------------*/
2904 /* deallocStackSpil - this will set the stack pointer back */
2905 /*-----------------------------------------------------------------*/
2907 DEFSETFUNC (deallocStackSpil)
2911 debugLog ("%s\n", __FUNCTION__);
2916 /*-----------------------------------------------------------------*/
2917 /* farSpacePackable - returns the packable icode for far variables */
2918 /*-----------------------------------------------------------------*/
2920 farSpacePackable (iCode * ic)
2924 debugLog ("%s\n", __FUNCTION__);
2925 /* go thru till we find a definition for the
2926 symbol on the right */
2927 for (dic = ic->prev; dic; dic = dic->prev)
2930 /* if the definition is a call then no */
2931 if ((dic->op == CALL || dic->op == PCALL) &&
2932 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2937 /* if shift by unknown amount then not */
2938 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2939 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2942 /* if pointer get and size > 1 */
2943 if (POINTER_GET (dic) &&
2944 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2947 if (POINTER_SET (dic) &&
2948 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2951 /* if any three is a true symbol in far space */
2952 if (IC_RESULT (dic) &&
2953 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2954 isOperandInFarSpace (IC_RESULT (dic)))
2957 if (IC_RIGHT (dic) &&
2958 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2959 isOperandInFarSpace (IC_RIGHT (dic)) &&
2960 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2963 if (IC_LEFT (dic) &&
2964 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2965 isOperandInFarSpace (IC_LEFT (dic)) &&
2966 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2969 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2971 if ((dic->op == LEFT_OP ||
2972 dic->op == RIGHT_OP ||
2974 IS_OP_LITERAL (IC_RIGHT (dic)))
2985 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
2989 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2990 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
2991 debugAopGet (" result:", IC_RESULT (ic));
2992 debugAopGet (" left:", IC_LEFT (ic));
2993 debugAopGet (" right:", IC_RIGHT (ic));
3002 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3004 /*-----------------------------------------------------------------*/
3005 /* packRegsForAssign - register reduction for assignment */
3006 /*-----------------------------------------------------------------*/
3008 packRegsForAssign (iCode * ic, eBBlock * ebp)
3012 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3013 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3014 debugAopGet (" result:", IC_RESULT (ic));
3015 debugAopGet (" left:", IC_LEFT (ic));
3016 debugAopGet (" right:", IC_RIGHT (ic));
3018 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3020 debugLog(" %d - actuall processing\n", __LINE__ );
3022 if (!IS_ITEMP (IC_RESULT (ic))) {
3023 pic16_allocDirReg(IC_RESULT (ic));
3024 debugLog (" %d - result is not temp\n", __LINE__);
3027 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3029 /* See BUGLOG0001 - VR */
3031 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3032 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3033 pic16_allocDirReg(IC_RIGHT (ic));
3038 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3039 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3041 debugLog (" %d - not packing - right side fails \n", __LINE__);
3045 /* if the true symbol is defined in far space or on stack
3046 then we should not since this will increase register pressure */
3047 if (isOperandInFarSpace (IC_RESULT (ic)))
3049 if ((dic = farSpacePackable (ic)))
3056 /* find the definition of iTempNN scanning backwards if we find a
3057 a use of the true symbol before we find the definition then
3059 for (dic = ic->prev; dic; dic = dic->prev)
3062 /* if there is a function call and this is
3063 a parameter & not my parameter then don't pack it */
3064 if ((dic->op == CALL || dic->op == PCALL) &&
3065 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3066 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3068 debugLog (" %d - \n", __LINE__);
3077 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3079 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3080 IS_OP_VOLATILE (IC_RESULT (dic)))
3082 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3088 if( IS_SYMOP( IC_RESULT(dic)) &&
3089 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3091 debugLog (" %d - result is bitfield\n", __LINE__);
3097 if (IS_SYMOP (IC_RESULT (dic)) &&
3098 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3100 /* A previous result was assigned to the same register - we'll our definition */
3101 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3102 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3103 if (POINTER_SET (dic))
3109 if (IS_SYMOP (IC_RIGHT (dic)) &&
3110 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3111 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3113 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3118 if (IS_SYMOP (IC_LEFT (dic)) &&
3119 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3120 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3122 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3127 if (POINTER_SET (dic) &&
3128 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3130 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3138 return 0; /* did not find */
3141 /* This code is taken from the hc08 port. Do not know
3142 * if it fits for pic16, but I leave it here just in case */
3144 /* if assignment then check that right is not a bit */
3145 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3146 sym_link *etype = operandType (IC_RIGHT (dic));
3148 if (IS_BITFIELD (etype)) {
3149 /* if result is a bit too then it's ok */
3150 etype = operandType (IC_RESULT (dic));
3151 if (!IS_BITFIELD (etype)) {
3152 debugLog(" %d bitfields\n");
3159 /* if the result is on stack or iaccess then it must be
3160 the same atleast one of the operands */
3161 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3162 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3164 /* the operation has only one symbol
3165 operator then we can pack */
3166 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3167 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3170 if (!((IC_LEFT (dic) &&
3171 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3173 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3177 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3178 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3179 /* found the definition */
3180 /* replace the result with the result of */
3181 /* this assignment and remove this assignment */
3184 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3185 IC_RESULT (dic) = IC_RESULT (ic);
3187 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3189 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3191 /* delete from liverange table also
3192 delete from all the points inbetween and the new
3194 for (sic = dic; sic != ic; sic = sic->next)
3196 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3197 if (IS_ITEMP (IC_RESULT (dic)))
3198 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3201 remiCodeFromeBBlock (ebp, ic);
3202 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3204 debugLog(" %d\n", __LINE__ );
3205 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3206 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3213 #define NO_packRegsForAccUse
3214 #define NO_packRegsForSupport
3215 #define NO_packRegsForOneuse
3216 #define NO_cast_peep
3221 #ifndef NO_packRegsForSupport
3222 /*-----------------------------------------------------------------*/
3223 /* findAssignToSym : scanning backwards looks for first assig found */
3224 /*-----------------------------------------------------------------*/
3226 findAssignToSym (operand * op, iCode * ic)
3230 debugLog ("%s\n", __FUNCTION__);
3231 for (dic = ic->prev; dic; dic = dic->prev)
3234 /* if definition by assignment */
3235 if (dic->op == '=' &&
3236 !POINTER_SET (dic) &&
3237 IC_RESULT (dic)->key == op->key
3238 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3242 /* we are interested only if defined in far space */
3243 /* or in stack space in case of + & - */
3245 /* if assigned to a non-symbol then return
3247 if (!IS_SYMOP (IC_RIGHT (dic)))
3250 /* if the symbol is in far space then
3252 if (isOperandInFarSpace (IC_RIGHT (dic)))
3255 /* for + & - operations make sure that
3256 if it is on the stack it is the same
3257 as one of the three operands */
3258 if ((ic->op == '+' || ic->op == '-') &&
3259 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3261 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3262 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3263 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3271 /* if we find an usage then we cannot delete it */
3272 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3275 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3278 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3282 /* now make sure that the right side of dic
3283 is not defined between ic & dic */
3286 iCode *sic = dic->next;
3288 for (; sic != ic; sic = sic->next)
3289 if (IC_RESULT (sic) &&
3290 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3301 #ifndef NO_packRegsForSupport
3302 /*-----------------------------------------------------------------*/
3303 /* packRegsForSupport :- reduce some registers for support calls */
3304 /*-----------------------------------------------------------------*/
3306 packRegsForSupport (iCode * ic, eBBlock * ebp)
3310 debugLog ("%s\n", __FUNCTION__);
3311 /* for the left & right operand :- look to see if the
3312 left was assigned a true symbol in far space in that
3313 case replace them */
3314 if (IS_ITEMP (IC_LEFT (ic)) &&
3315 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3317 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3323 debugAopGet ("removing left:", IC_LEFT (ic));
3325 /* found it we need to remove it from the
3327 for (sic = dic; sic != ic; sic = sic->next)
3328 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3330 IC_LEFT (ic)->operand.symOperand =
3331 IC_RIGHT (dic)->operand.symOperand;
3332 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3333 remiCodeFromeBBlock (ebp, dic);
3334 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3335 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3339 /* do the same for the right operand */
3342 IS_ITEMP (IC_RIGHT (ic)) &&
3343 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3345 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3351 /* if this is a subtraction & the result
3352 is a true symbol in far space then don't pack */
3353 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3355 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3356 if (IN_FARSPACE (SPEC_OCLS (etype)))
3360 debugAopGet ("removing right:", IC_RIGHT (ic));
3362 /* found it we need to remove it from the
3364 for (sic = dic; sic != ic; sic = sic->next)
3365 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3367 IC_RIGHT (ic)->operand.symOperand =
3368 IC_RIGHT (dic)->operand.symOperand;
3369 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3371 remiCodeFromeBBlock (ebp, dic);
3372 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3373 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3382 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3384 #ifndef NO_packRegsForOneuse
3385 /*-----------------------------------------------------------------*/
3386 /* packRegsForOneuse : - will reduce some registers for single Use */
3387 /*-----------------------------------------------------------------*/
3389 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3394 debugLog ("%s\n", __FUNCTION__);
3395 /* if returning a literal then do nothing */
3399 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3402 /* only upto 2 bytes since we cannot predict
3403 the usage of b, & acc */
3404 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3412 /* this routine will mark the a symbol as used in one
3413 instruction use only && if the definition is local
3414 (ie. within the basic block) && has only one definition &&
3415 that definition is either a return value from a
3416 function or does not contain any variables in
3420 uses = bitVectCopy (OP_USES (op));
3421 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3422 if (!bitVectIsZero (uses)) /* has other uses */
3427 if (bitVectnBitsOn (OP_USES (op)) > 1)
3431 /* if it has only one defintion */
3432 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3433 return NULL; /* has more than one definition */
3435 /* get that definition */
3437 hTabItemWithKey (iCodehTab,
3438 bitVectFirstBit (OP_DEFS (op)))))
3441 /* found the definition now check if it is local */
3442 if (dic->seq < ebp->fSeq ||
3443 dic->seq > ebp->lSeq)
3444 return NULL; /* non-local */
3446 /* now check if it is the return from
3448 if (dic->op == CALL || dic->op == PCALL)
3450 if (ic->op != SEND && ic->op != RETURN &&
3451 !POINTER_SET(ic) && !POINTER_GET(ic))
3453 OP_SYMBOL (op)->ruonly = 1;
3462 /* otherwise check that the definition does
3463 not contain any symbols in far space */
3464 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3465 isOperandInFarSpace (IC_RIGHT (dic)) ||
3466 IS_OP_RUONLY (IC_LEFT (ic)) ||
3467 IS_OP_RUONLY (IC_RIGHT (ic)))
3472 /* if pointer set then make sure the pointer
3474 if (POINTER_SET (dic) &&
3475 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3478 if (POINTER_GET (dic) &&
3479 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3485 /* also make sure the intervenening instructions
3486 don't have any thing in far space */
3487 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3490 /* if there is an intervening function call then no */
3491 if (dic->op == CALL || dic->op == PCALL)
3493 /* if pointer set then make sure the pointer
3495 if (POINTER_SET (dic) &&
3496 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3499 if (POINTER_GET (dic) &&
3500 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3503 /* if address of & the result is remat then okay */
3504 if (dic->op == ADDRESS_OF &&
3505 OP_SYMBOL (IC_RESULT (dic))->remat)
3508 /* if operand has size of three or more & this
3509 operation is a '*','/' or '%' then 'b' may
3511 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3512 getSize (operandType (op)) >= 2)
3515 /* if left or right or result is in far space */
3516 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3517 isOperandInFarSpace (IC_RIGHT (dic)) ||
3518 isOperandInFarSpace (IC_RESULT (dic)) ||
3519 IS_OP_RUONLY (IC_LEFT (dic)) ||
3520 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3521 IS_OP_RUONLY (IC_RESULT (dic)))
3527 OP_SYMBOL (op)->ruonly = 1;
3534 /*-----------------------------------------------------------------*/
3535 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3536 /*-----------------------------------------------------------------*/
3538 isBitwiseOptimizable (iCode * ic)
3540 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3541 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3543 debugLog ("%s\n", __FUNCTION__);
3544 /* bitwise operations are considered optimizable
3545 under the following conditions (Jean-Louis VERN)
3557 if (IS_LITERAL (rtype) ||
3558 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3565 #ifndef NO_packRegsForAccUse
3567 /*-----------------------------------------------------------------*/
3568 /* packRegsForAccUse - pack registers for acc use */
3569 /*-----------------------------------------------------------------*/
3571 packRegsForAccUse (iCode * ic)
3575 debugLog ("%s\n", __FUNCTION__);
3577 /* if this is an aggregate, e.g. a one byte char array */
3578 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3581 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3583 /* if + or - then it has to be one byte result */
3584 if ((ic->op == '+' || ic->op == '-')
3585 && getSize (operandType (IC_RESULT (ic))) > 1)
3588 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3589 /* if shift operation make sure right side is not a literal */
3590 if (ic->op == RIGHT_OP &&
3591 (isOperandLiteral (IC_RIGHT (ic)) ||
3592 getSize (operandType (IC_RESULT (ic))) > 1))
3595 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3596 if (ic->op == LEFT_OP &&
3597 (isOperandLiteral (IC_RIGHT (ic)) ||
3598 getSize (operandType (IC_RESULT (ic))) > 1))
3601 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3602 if (IS_BITWISE_OP (ic) &&
3603 getSize (operandType (IC_RESULT (ic))) > 1)
3607 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3608 /* has only one definition */
3609 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3612 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3613 /* has only one use */
3614 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3617 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3618 /* and the usage immediately follows this iCode */
3619 if (!(uic = hTabItemWithKey (iCodehTab,
3620 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3623 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3624 if (ic->next != uic)
3627 /* if it is a conditional branch then we definitely can */
3631 if (uic->op == JUMPTABLE)
3634 /* if the usage is not is an assignment
3635 or an arithmetic / bitwise / shift operation then not */
3636 if (POINTER_SET (uic) &&
3637 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3640 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3641 if (uic->op != '=' &&
3642 !IS_ARITHMETIC_OP (uic) &&
3643 !IS_BITWISE_OP (uic) &&
3644 uic->op != LEFT_OP &&
3645 uic->op != RIGHT_OP)
3648 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3649 /* if used in ^ operation then make sure right is not a
3651 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3654 /* if shift operation make sure right side is not a literal */
3655 if (uic->op == RIGHT_OP &&
3656 (isOperandLiteral (IC_RIGHT (uic)) ||
3657 getSize (operandType (IC_RESULT (uic))) > 1))
3660 if (uic->op == LEFT_OP &&
3661 (isOperandLiteral (IC_RIGHT (uic)) ||
3662 getSize (operandType (IC_RESULT (uic))) > 1))
3665 /* make sure that the result of this icode is not on the
3666 stack, since acc is used to compute stack offset */
3667 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3668 OP_SYMBOL (IC_RESULT (uic))->onStack)
3671 /* if either one of them in far space then we cannot */
3672 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3673 isOperandInFarSpace (IC_LEFT (uic))) ||
3674 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3675 isOperandInFarSpace (IC_RIGHT (uic))))
3678 /* if the usage has only one operand then we can */
3679 if (IC_LEFT (uic) == NULL ||
3680 IC_RIGHT (uic) == NULL)
3683 /* make sure this is on the left side if not
3684 a '+' since '+' is commutative */
3685 if (ic->op != '+' &&
3686 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3690 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3691 /* if one of them is a literal then we can */
3692 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3693 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3694 (getSize (operandType (IC_RESULT (uic))) <= 1))
3696 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3701 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3702 /* if the other one is not on stack then we can */
3703 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3704 (IS_ITEMP (IC_RIGHT (uic)) ||
3705 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3706 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3709 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3710 (IS_ITEMP (IC_LEFT (uic)) ||
3711 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3712 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3718 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3719 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3726 /*-----------------------------------------------------------------*/
3727 /* packForPush - hueristics to reduce iCode for pushing */
3728 /*-----------------------------------------------------------------*/
3730 packForReceive (iCode * ic, eBBlock * ebp)
3734 debugLog ("%s\n", __FUNCTION__);
3735 debugAopGet (" result:", IC_RESULT (ic));
3736 debugAopGet (" left:", IC_LEFT (ic));
3737 debugAopGet (" right:", IC_RIGHT (ic));
3742 for (dic = ic->next; dic; dic = dic->next)
3744 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3745 debugLog (" used on left\n");
3746 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3747 debugLog (" used on right\n");
3748 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3749 debugLog (" used on result\n");
3751 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3752 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3756 debugLog (" hey we can remove this unnecessary assign\n");
3758 /*-----------------------------------------------------------------*/
3759 /* packForPush - hueristics to reduce iCode for pushing */
3760 /*-----------------------------------------------------------------*/
3762 packForPush (iCode * ic, eBBlock * ebp)
3766 debugLog ("%s\n", __FUNCTION__);
3767 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3774 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3775 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3776 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3777 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3781 /* must have only definition & one usage */
3782 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3783 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3786 /* find the definition */
3787 if (!(dic = hTabItemWithKey (iCodehTab,
3788 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3791 /* if definition is not assignment,
3792 * or is not pointer (because pointer might have changed) */
3793 if (dic->op != '=' || POINTER_SET (dic))
3796 /* we must ensure that we can use the delete the assignment,
3797 * because the source might have been modified in between.
3798 * Until I know how to fix this, I'll use the adhoc fix
3799 * to check the liveranges */
3800 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3802 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3806 /* we now we know that it has one & only one def & use
3807 and the that the definition is an assignment */
3808 IC_LEFT (ic) = IC_RIGHT (dic);
3810 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3812 remiCodeFromeBBlock (ebp, dic);
3813 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3814 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3817 static void printSymType(char * str, sym_link *sl)
3819 if(!pic16_ralloc_debug)return;
3821 debugLog (" %s Symbol type: ",str);
3822 printTypeChain( sl, debugF);
3826 /*-----------------------------------------------------------------*/
3827 /* some debug code to print the symbol S_TYPE. Note that
3828 * the function checkSClass in src/SDCCsymt.c dinks with
3829 * the S_TYPE in ways the PIC port doesn't fully like...*/
3830 /*-----------------------------------------------------------------*/
3831 static void isData(sym_link *sl)
3835 if(!pic16_ralloc_debug)return;
3842 for ( ; sl; sl=sl->next) {
3844 switch (SPEC_SCLS(sl)) {
3845 case S_DATA: fprintf (of, "data "); break;
3846 case S_XDATA: fprintf (of, "xdata "); break;
3847 case S_SFR: fprintf (of, "sfr "); break;
3848 case S_SBIT: fprintf (of, "sbit "); break;
3849 case S_CODE: fprintf (of, "code "); break;
3850 case S_IDATA: fprintf (of, "idata "); break;
3851 case S_PDATA: fprintf (of, "pdata "); break;
3852 case S_LITERAL: fprintf (of, "literal "); break;
3853 case S_STACK: fprintf (of, "stack "); break;
3854 case S_XSTACK: fprintf (of, "xstack "); break;
3855 case S_BIT: fprintf (of, "bit "); break;
3856 case S_EEPROM: fprintf (of, "eeprom "); break;
3864 /*--------------------------------------------------------------------*/
3865 /* pic16_packRegisters - does some transformations to reduce */
3866 /* register pressure */
3868 /*--------------------------------------------------------------------*/
3870 pic16_packRegisters (eBBlock * ebp)
3875 debugLog ("%s\n", __FUNCTION__);
3881 /* look for assignments of the form */
3882 /* iTempNN = TRueSym (someoperation) SomeOperand */
3884 /* TrueSym := iTempNN:1 */
3885 for (ic = ebp->sch; ic; ic = ic->next)
3887 // debugLog("%d\n", __LINE__);
3888 /* find assignment of the form TrueSym := iTempNN:1 */
3889 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3890 change += packRegsForAssign (ic, ebp);
3894 if (POINTER_SET (ic))
3895 debugLog ("pointer is set\n");
3896 debugAopGet (" result:", IC_RESULT (ic));
3897 debugAopGet (" left:", IC_LEFT (ic));
3898 debugAopGet (" right:", IC_RIGHT (ic));
3907 for (ic = ebp->sch; ic; ic = ic->next) {
3909 if(IS_SYMOP ( IC_LEFT(ic))) {
3910 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3912 debugAopGet ("x left:", IC_LEFT (ic));
3914 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3916 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3918 debugLog (" is a pointer\n");
3920 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3921 debugLog (" is a ptr\n");
3923 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3924 debugLog (" is volatile\n");
3928 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3929 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3930 pic16_allocDirReg(IC_LEFT (ic));
3933 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3936 if(IS_SYMOP ( IC_RIGHT(ic))) {
3937 debugAopGet (" right:", IC_RIGHT (ic));
3938 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3941 if(IS_SYMOP ( IC_RESULT(ic))) {
3942 debugAopGet (" result:", IC_RESULT (ic));
3943 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3946 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3947 debugAopGet (" right:", IC_RIGHT (ic));
3948 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3949 // pic16_allocDirReg(IC_RIGHT(ic));
3952 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3953 debugAopGet (" result:", IC_RESULT (ic));
3954 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3955 // pic16_allocDirReg(IC_RESULT(ic));
3959 if (POINTER_SET (ic))
3960 debugLog (" %d - Pointer set\n", __LINE__);
3962 /* Look for two subsequent iCodes with */
3964 /* _c = iTemp & op; */
3965 /* and replace them by */
3968 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3970 && ic->prev->op == '='
3971 && IS_ITEMP (IC_LEFT (ic))
3972 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3973 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3975 iCode* ic_prev = ic->prev;
3976 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3978 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3979 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
3980 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3981 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3982 prev_result_sym->liveTo == ic->seq)
3984 prev_result_sym->liveTo = ic_prev->seq;
3987 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3989 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3991 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
3992 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3993 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3994 remiCodeFromeBBlock (ebp, ic_prev);
3995 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3999 /* if this is an itemp & result of a address of a true sym
4000 then mark this as rematerialisable */
4001 if (ic->op == ADDRESS_OF &&
4002 IS_ITEMP (IC_RESULT (ic)) &&
4003 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4004 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4005 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4008 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4010 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4011 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4012 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4016 /* if straight assignment then carry remat flag if
4017 this is the only definition */
4018 if (ic->op == '=' &&
4019 !POINTER_SET (ic) &&
4020 IS_SYMOP (IC_RIGHT (ic)) &&
4021 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4022 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4024 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4026 OP_SYMBOL (IC_RESULT (ic))->remat =
4027 OP_SYMBOL (IC_RIGHT (ic))->remat;
4028 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4029 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4032 /* if this is a +/- operation with a rematerizable
4033 then mark this as rematerializable as well */
4034 if ((ic->op == '+' || ic->op == '-') &&
4035 (IS_SYMOP (IC_LEFT (ic)) &&
4036 IS_ITEMP (IC_RESULT (ic)) &&
4037 OP_SYMBOL (IC_LEFT (ic))->remat &&
4038 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4039 IS_OP_LITERAL (IC_RIGHT (ic))))
4041 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4043 operandLitValue (IC_RIGHT (ic));
4044 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4045 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4046 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4051 /* if this is an arithmetic operation
4052 * && result or left is not rematerializable (so it is a plain arithmetic op)
4053 * && and left is not used after this iCode */
4055 if(getenv("OPTIMIZE_NEAR_POINTER_GET"))
4057 if (IS_ARITHMETIC_OP(ic)
4058 && !IS_OP_LITERAL (IC_LEFT (ic))
4059 && !OP_SYMBOL (IC_RESULT(ic))->rematiCode
4060 && !OP_SYMBOL (IC_LEFT(ic))->rematiCode
4061 && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq)
4063 iCode *dic = ic->prev;
4065 /* search backwards to find assignment from a remat pointer */
4066 while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) {
4068 /* is it a pointer_get? */
4070 && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) {
4071 fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__,
4072 OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq);
4074 /* so we can replace ic->left with dic->left, & remove assignment */
4075 ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) );
4077 bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key);
4078 bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key );
4080 // dic->op = DUMMY_READ_VOLATILE;
4082 remiCodeFromeBBlock(ebp, dic);
4083 hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4092 /* mark the pointer usages */
4093 if (POINTER_SET (ic))
4095 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4096 debugLog (" marking as a pointer (set) =>");
4097 debugAopGet (" result:", IC_RESULT (ic));
4101 if (POINTER_GET (ic))
4103 if(IS_SYMOP(IC_LEFT(ic))) {
4104 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4105 debugLog (" marking as a pointer (get) =>");
4106 debugAopGet (" left:", IC_LEFT (ic));
4109 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4110 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4111 iCode *dic = ic->prev;
4113 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4115 if(dic && dic->op == '='
4116 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4118 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4121 /* replace prev->left with ic->left */
4122 IC_LEFT(ic) = IC_RIGHT(dic);
4123 IC_RIGHT(ic->prev) = NULL;
4125 /* remove ic->prev iCode (assignment) */
4126 remiCodeFromeBBlock (ebp, dic);
4127 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4130 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4136 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4140 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4141 /* if we are using a symbol on the stack
4142 then we should say pic16_ptrRegReq */
4143 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4144 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4145 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4146 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4147 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4148 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4152 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4153 if (IS_SYMOP (IC_LEFT (ic)))
4154 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4155 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4156 if (IS_SYMOP (IC_RIGHT (ic)))
4157 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4158 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4159 if (IS_SYMOP (IC_RESULT (ic)))
4160 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4161 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4164 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4168 /* if the condition of an if instruction
4169 is defined in the previous instruction then
4170 mark the itemp as a conditional */
4171 if ((IS_CONDITIONAL (ic) ||
4172 ((ic->op == BITWISEAND ||
4175 isBitwiseOptimizable (ic))) &&
4176 ic->next && ic->next->op == IFX &&
4177 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4178 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4181 debugLog (" %d\n", __LINE__);
4182 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4186 debugLog(" %d\n", __LINE__);
4188 #ifndef NO_packRegsForSupport
4189 /* reduce for support function calls */
4190 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4191 packRegsForSupport (ic, ebp);
4194 /* if a parameter is passed, it's in W, so we may not
4195 need to place a copy in a register */
4196 if (ic->op == RECEIVE)
4197 packForReceive (ic, ebp);
4199 #ifndef NO_packRegsForOneuse
4200 /* some cases the redundant moves can
4201 can be eliminated for return statements */
4202 if ((ic->op == RETURN || ic->op == SEND) &&
4203 !isOperandInFarSpace (IC_LEFT (ic)) &&
4205 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4208 #ifndef NO_packRegsForOneuse
4209 /* if pointer set & left has a size more than
4210 one and right is not in far space */
4211 if (POINTER_SET (ic) &&
4212 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4213 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4214 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4215 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4217 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4220 #ifndef NO_packRegsForOneuse
4221 /* if pointer get */
4222 if (POINTER_GET (ic) &&
4223 !isOperandInFarSpace (IC_RESULT (ic)) &&
4224 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4225 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4226 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4228 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4229 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4232 #ifndef NO_cast_peep
4233 /* if this is cast for intergral promotion then
4234 check if only use of the definition of the
4235 operand being casted/ if yes then replace
4236 the result of that arithmetic operation with
4237 this result and get rid of the cast */
4238 if (ic->op == CAST) {
4240 sym_link *fromType = operandType (IC_RIGHT (ic));
4241 sym_link *toType = operandType (IC_LEFT (ic));
4243 debugLog (" %d - casting\n", __LINE__);
4245 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4246 getSize (fromType) != getSize (toType)) {
4249 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4252 if (IS_ARITHMETIC_OP (dic)) {
4253 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4255 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4256 IC_RESULT (dic) = IC_RESULT (ic);
4257 remiCodeFromeBBlock (ebp, ic);
4258 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4259 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4260 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4264 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4268 /* if the type from and type to are the same
4269 then if this is the only use then packit */
4270 if (compareType (operandType (IC_RIGHT (ic)),
4271 operandType (IC_LEFT (ic))) == 1) {
4273 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4276 debugLog(" %d\n", __LINE__);
4278 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4279 IC_RESULT (dic) = IC_RESULT (ic);
4280 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4281 remiCodeFromeBBlock (ebp, ic);
4282 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4283 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4292 /* there are some problems with packing variables
4293 * it seems that the live range estimator doesn't
4294 * estimate correctly the liveranges of some symbols */
4297 iTempNN := (some variable in farspace) V1
4302 if (ic->op == IPUSH)
4304 packForPush (ic, ebp);
4308 #ifndef NO_packRegsForAccUse
4309 /* pack registers for accumulator use, when the
4310 result of an arithmetic or bit wise operation
4311 has only one use, that use is immediately following
4312 the defintion and the using iCode has only one
4313 operand or has two operands but one is literal &
4314 the result of that operation is not on stack then
4315 we can leave the result of this operation in acc:b
4317 if ((IS_ARITHMETIC_OP (ic)
4319 || IS_BITWISE_OP (ic)
4321 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4324 IS_ITEMP (IC_RESULT (ic)) &&
4325 getSize (operandType (IC_RESULT (ic))) <= 1)
4327 packRegsForAccUse (ic);
4334 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4338 if (!pic16_ralloc_debug || !debugF)
4341 for (i = 0; i < count; i++)
4343 fprintf (debugF, "\n----------------------------------------------------------------\n");
4344 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4345 ebbs[i]->entryLabel->name,
4348 ebbs[i]->isLastInLoop);
4349 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4354 fprintf (debugF, "visited %d : hasFcall = %d\n",
4358 fprintf (debugF, "\ndefines bitVector :");
4359 bitVectDebugOn (ebbs[i]->defSet, debugF);
4360 fprintf (debugF, "\nlocal defines bitVector :");
4361 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4362 fprintf (debugF, "\npointers Set bitvector :");
4363 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4364 fprintf (debugF, "\nin pointers Set bitvector :");
4365 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4366 fprintf (debugF, "\ninDefs Set bitvector :");
4367 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4368 fprintf (debugF, "\noutDefs Set bitvector :");
4369 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4370 fprintf (debugF, "\nusesDefs Set bitvector :");
4371 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4372 fprintf (debugF, "\n----------------------------------------------------------------\n");
4373 printiCChain (ebbs[i]->sch, debugF);
4376 /*-----------------------------------------------------------------*/
4377 /* pic16_assignRegisters - assigns registers to each live range as need */
4378 /*-----------------------------------------------------------------*/
4380 pic16_assignRegisters (ebbIndex * ebbi)
4382 eBBlock ** ebbs = ebbi->bbOrder;
4383 int count = ebbi->count;
4387 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4388 debugLog ("\nebbs before optimizing:\n");
4389 dumpEbbsToDebug (ebbs, count);
4391 _inRegAllocator = 1;
4393 setToNull ((void *) &_G.funcrUsed);
4394 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4397 /* change assignments this will remove some
4398 live ranges reducing some register pressure */
4399 for (i = 0; i < count; i++)
4400 pic16_packRegisters (ebbs[i]);
4407 debugLog("dir registers allocated so far:\n");
4408 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4411 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4412 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4413 reg = hTabNextItem(dynDirectRegNames, &hkey);
4418 /* liveranges probably changed by register packing
4419 so we compute them again */
4420 recomputeLiveRanges (ebbs, count);
4422 if (options.dump_pack)
4423 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4425 /* first determine for each live range the number of
4426 registers & the type of registers required for each */
4429 /* start counting function temporary registers from zero */
4432 /* and serially allocate registers */
4433 serialRegAssign (ebbs, count);
4436 debugLog ("ebbs after serialRegAssign:\n");
4437 dumpEbbsToDebug (ebbs, count);
4440 //pic16_freeAllRegs();
4442 /* if stack was extended then tell the user */
4445 /* werror(W_TOOMANY_SPILS,"stack", */
4446 /* _G.stackExtend,currFunc->name,""); */
4452 /* werror(W_TOOMANY_SPILS,"data space", */
4453 /* _G.dataExtend,currFunc->name,""); */
4457 /* after that create the register mask
4458 for each of the instruction */
4459 createRegMask (ebbs, count);
4461 /* redo that offsets for stacked automatic variables */
4462 redoStackOffsets ();
4464 if (options.dump_rassgn)
4465 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4467 /* now get back the chain */
4468 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4470 debugLog ("ebbs after optimizing:\n");
4471 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");