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 FUNCTION: return "FUNCTION";
306 case ENDFUNCTION: return "ENDFUNCTION";
307 case JUMPTABLE: return "JUMPTABLE";
308 case RRC: return "RRC";
309 case RLC: return "RLC";
310 case CAST: return "CAST";
311 case CALL: return "CALL";
312 case PARAM: return "PARAM ";
313 case NULLOP: return "NULLOP";
314 case BLOCK: return "BLOCK";
315 case LABEL: return "LABEL";
316 case RECEIVE: return "RECEIVE";
317 case SEND: return "SEND";
318 case DUMMY_READ_VOLATILE: return "DUMMY_READ_VOLATILE";
320 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
326 static char *decodeRegType(short type)
329 case REG_GPR: return "REG_GPR";
330 case REG_PTR: return "REG_PTR";
331 case REG_CND: return "REG_CNT";
339 /*-----------------------------------------------------------------*/
340 /*-----------------------------------------------------------------*/
342 debugLogRegType (short type)
344 if(!pic16_ralloc_debug)return NULL;
346 case REG_GPR: return "REG_GPR";
347 case REG_PTR: return "REG_PTR";
348 case REG_CND: return "REG_CND";
350 sprintf (buffer, "unknown reg type %d", type);
355 /*-----------------------------------------------------------------*/
356 /*-----------------------------------------------------------------*/
357 static int regname2key(char const *name)
366 key += (*name++) + 1;
370 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
374 /*-----------------------------------------------------------------*/
375 /* newReg - allocate and init memory for a new register */
376 /*-----------------------------------------------------------------*/
377 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
382 dReg = Safe_calloc(1,sizeof(regs));
384 dReg->pc_type = pc_type;
387 dReg->name = Safe_strdup(name);
389 if(xinst && pc_type == PO_GPR_TEMP) {
390 sprintf(buffer,"0x%02x", dReg->rIdx);
392 sprintf(buffer,"r0x%02x", dReg->rIdx);
395 if(type == REG_STK) {
398 dReg->name = Safe_strdup(buffer);
406 if(type == REG_SFR) {
408 dReg->address = rIdx;
409 dReg->accessBank = 1;
413 dReg->accessBank = 0;
417 fprintf(stderr,"newReg @ %p: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg, dReg->name,rIdx, dReg->accessBank, refop);
421 dReg->reg_alias = NULL;
422 dReg->reglives.usedpFlows = newSet();
423 dReg->reglives.assignedpFlows = newSet();
426 if(!(type == REG_SFR && alias == 0x80))
427 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
432 /*-----------------------------------------------------------------*/
433 /* regWithIdx - Search through a set of registers that matches idx */
434 /*-----------------------------------------------------------------*/
436 regWithIdx (set *dRegs, int idx, unsigned fixed)
440 //#define D(text) text
443 for (dReg = setFirstItem(dRegs) ; dReg ;
444 dReg = setNextItem(dRegs)) {
446 D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed));
447 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
448 D(fprintf(stderr, "found!\n"));
451 D(fprintf(stderr, "not found!\n"));
457 /*-----------------------------------------------------------------*/
458 /* regFindFree - Search for a free register in a set of registers */
459 /*-----------------------------------------------------------------*/
461 regFindFree (set *dRegs)
465 for (dReg = setFirstItem(dRegs) ; dReg ;
466 dReg = setNextItem(dRegs)) {
468 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
469 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
472 // fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx);
482 regFindFreeNext(set *dRegs, regs *creg)
487 /* position at current register */
488 for(dReg = setFirstItem(dRegs); dReg != creg; dReg = setNextItem(dRegs));
491 for(dReg = setNextItem(dRegs); dReg; dReg = setNextItem(dRegs)) {
500 /*-----------------------------------------------------------------*/
501 /* pic16_initStack - allocate registers for a pseudo stack */
502 /*-----------------------------------------------------------------*/
503 void pic16_initStack(int base_address, int size)
508 pic16_Gstack_base_addr = base_address;
509 //fprintf(stderr,"initStack");
511 for(i = 0; i<size; i++)
512 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
515 /*-----------------------------------------------------------------*
516 *-----------------------------------------------------------------*/
518 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
520 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
522 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
524 reg->wasUsed = 0; // we do not know if they are going to be used at all
525 reg->accessBank = 1; // implicit add access Bank
527 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
529 return addSet(&pic16_dynProcessorRegs, reg);
532 /*-----------------------------------------------------------------*
533 *-----------------------------------------------------------------*/
536 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
538 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
540 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
544 return addSet(&pic16_dynInternalRegs,reg);
551 /*-----------------------------------------------------------------*/
552 /* allocReg - allocates register of given type */
553 /*-----------------------------------------------------------------*/
555 allocReg (short type)
559 #define MAX_P16_NREGS 16
563 if(dynrIdx > pic16_nRegs)
564 werror(W_POSSBUG2, __FILE__, __LINE__);
568 /* try to reuse some unused registers */
569 reg = regFindFree( pic16_dynAllocRegs );
572 // fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
576 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
577 // fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__,
578 // (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx);
581 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
582 // debugf("allocating more registers than available\n", 0);
588 addSet(&pic16_dynAllocRegs, reg);
589 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
591 // fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
593 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
596 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
597 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
601 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
602 reg->isLocal = 1; /* this is a local frame register */
607 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
608 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
611 return (reg); // addSet(&pic16_dynAllocRegs,reg);
616 /*-----------------------------------------------------------------*/
617 /* pic16_dirregWithName - search for register by name */
618 /*-----------------------------------------------------------------*/
620 pic16_dirregWithName (char *name)
628 /* hash the name to get a key */
630 hkey = regname2key(name);
632 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
634 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
638 if(STRCASECMP(reg->name, name) == 0) {
639 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
643 reg = hTabNextItemWK (dynDirectRegNames);
647 return NULL; // name wasn't found in the hash table
650 /*-----------------------------------------------------------------*/
651 /* pic16_allocregWithName - search for register by name */
652 /*-----------------------------------------------------------------*/
654 pic16_allocregWithName (char *name)
662 /* hash the name to get a key */
664 hkey = regname2key(name);
666 //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
668 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
672 if(STRCASECMP(reg->name, name) == 0) {
676 reg = hTabNextItemWK (dynAllocRegNames);
680 return NULL; // name wasn't found in the hash table
685 /*-----------------------------------------------------------------*/
686 /* pic16_procregWithName - search for register by name */
687 /*-----------------------------------------------------------------*/
689 pic16_procregWithName (char *name)
697 /* hash the name to get a key */
699 hkey = regname2key(name);
701 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
703 reg = hTabFirstItemWK(dynProcRegNames, hkey);
707 if(STRCASECMP(reg->name, name) == 0) {
711 reg = hTabNextItemWK (dynProcRegNames);
715 return NULL; // name wasn't found in the hash table
719 /*-----------------------------------------------------------------*/
720 /* pic16_accessregWithName - search for register by name */
721 /*-----------------------------------------------------------------*/
723 pic16_accessregWithName (char *name)
731 /* hash the name to get a key */
733 hkey = regname2key(name);
735 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
737 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
741 if(STRCASECMP(reg->name, name) == 0) {
745 reg = hTabNextItemWK (dynAccessRegNames);
749 return NULL; // name wasn't found in the hash table
753 regs *pic16_regWithName(char *name)
757 reg = pic16_dirregWithName( name );
760 reg = pic16_procregWithName( name );
763 reg = pic16_allocregWithName( name );
766 reg = pic16_accessregWithName( name );
773 /*-----------------------------------------------------------------*/
774 /* pic16_allocDirReg - allocates register of given type */
775 /*-----------------------------------------------------------------*/
777 pic16_allocDirReg (operand *op )
783 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
784 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
788 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
791 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
793 if(pic16_debug_verbose)
795 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
796 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
802 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
803 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
806 if(pic16_debug_verbose) {
807 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
808 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
809 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
810 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
811 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
812 IN_STACK( OP_SYM_ETYPE(op)),
813 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
814 IS_REGPARM(OP_SYM_ETYPE(op)),
817 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
818 OP_SYMBOL(op)->name);
826 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
827 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
831 if(IS_ITEMP(op))return NULL;
833 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
835 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
837 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
838 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
841 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
842 debugLog(" %d const char\n",__LINE__);
843 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
844 // fprintf(stderr, " %d const char\n",__LINE__);
845 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
849 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
850 if (IS_CODE ( OP_SYM_ETYPE(op)) )
851 debugLog(" %d code space\n",__LINE__);
853 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
854 debugLog(" %d integral\n",__LINE__);
856 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
857 debugLog(" %d literal\n",__LINE__);
859 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
860 debugLog(" %d specifier\n",__LINE__);
862 debugAopGet(NULL, op);
866 reg = pic16_dirregWithName(name);
870 int regtype = REG_GPR;
872 /* if this is at an absolute address, then get the address. */
873 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
874 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
875 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
878 /* Register wasn't found in hash, so let's create
879 * a new one and put it in the hash table AND in the
880 * dynDirectRegNames set */
881 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
882 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
888 if(OP_SYMBOL(op)->onStack) {
889 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
890 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
894 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
895 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
898 if(pic16_debug_verbose)
900 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
901 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
902 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
903 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
904 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
905 IN_STACK( OP_SYM_ETYPE(op)),
906 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
908 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
909 OP_SYMBOL(op)->name);
914 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
915 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
917 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
918 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
922 checkAddReg(&pic16_dynAccessRegs, reg);
923 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
929 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
930 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
931 // reg->type = REG_SFR;
934 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
935 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
936 addSet(&pic16_dynDirectBitRegs, reg);
939 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
940 // addSet(&pic16_dynDirectRegs, reg);
943 if(!(IS_STATIC(OP_SYM_ETYPE(op))
944 && OP_SYMBOL(op)->ival
947 checkAddReg(&pic16_dynDirectRegs, reg);
951 // debugLog (" -- %s is declared at address 0x30000x\n",name);
952 return (reg); /* This was NULL before, but since we found it
953 * why not just return it?! */
956 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
958 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
960 /* work around for user defined registers in access bank */
961 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
962 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
965 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
971 /*-----------------------------------------------------------------*/
972 /* pic16_allocRegByName - allocates register of given type */
973 /*-----------------------------------------------------------------*/
975 pic16_allocRegByName (char *name, int size, operand *op)
981 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
985 /* First, search the hash table to see if there is a register with this name */
986 reg = pic16_dirregWithName(name);
990 /* Register wasn't found in hash, so let's create
991 * a new one and put it in the hash table AND in the
992 * dynDirectRegNames set */
994 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
996 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
998 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
999 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
1001 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
1002 addSet(&pic16_dynDirectRegs, reg);
1008 /*-----------------------------------------------------------------*/
1009 /* RegWithIdx - returns pointer to register with index number */
1010 /*-----------------------------------------------------------------*/
1011 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
1016 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
1017 // fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
1022 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
1024 debugLog ("Found a Dynamic Register!\n");
1027 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
1028 debugLog ("Found a Direct Register!\n");
1032 if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
1033 debugLog ("Found an Internal Register!\n");
1039 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1040 debugLog ("Found a Stack Register!\n");
1045 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1046 debugLog ("Found a Processor Register!\n");
1060 /*-----------------------------------------------------------------*/
1061 /* pic16_regWithIdx - returns pointer to register with index number*/
1062 /*-----------------------------------------------------------------*/
1064 pic16_regWithIdx (int idx)
1068 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1071 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1075 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1082 /*-----------------------------------------------------------------*/
1083 /* pic16_regWithIdx - returns pointer to register with index number */
1084 /*-----------------------------------------------------------------*/
1086 pic16_allocWithIdx (int idx)
1091 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1092 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1094 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1096 debugLog ("Found a Dynamic Register!\n");
1097 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1098 debugLog ("Found a Stack Register!\n");
1099 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1100 debugLog ("Found a Processor Register!\n");
1101 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1102 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1103 debugLog ("Found an Internal Register!\n");
1106 debugLog ("Dynamic Register not found\n");
1109 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1110 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1111 "allocWithIdx not found");
1121 /*-----------------------------------------------------------------*/
1122 /*-----------------------------------------------------------------*/
1124 pic16_findFreeReg(short type)
1131 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1133 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1134 return allocReg( REG_GPR );
1138 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1152 pic16_findFreeRegNext(short type, regs *creg)
1159 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1161 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1162 return (allocReg( REG_GPR ) );
1166 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1178 /*-----------------------------------------------------------------*/
1179 /* freeReg - frees a register */
1180 /*-----------------------------------------------------------------*/
1182 freeReg (regs * reg)
1184 debugLog ("%s\n", __FUNCTION__);
1185 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1190 /*-----------------------------------------------------------------*/
1191 /* nFreeRegs - returns number of free registers */
1192 /*-----------------------------------------------------------------*/
1194 nFreeRegs (int type)
1200 /* although I fixed the register allocation/freeing scheme
1201 * the for loop below doesn't give valid results. I do not
1202 * know why yet. -- VR 10-Jan-2003 */
1207 /* dynamically allocate as many as we need and worry about
1208 * fitting them into a PIC later */
1210 debugLog ("%s\n", __FUNCTION__);
1212 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1213 if((reg->type == type) && reg->isFree)nfr++;
1215 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1219 /*-----------------------------------------------------------------*/
1220 /* nfreeRegsType - free registers with type */
1221 /*-----------------------------------------------------------------*/
1223 nfreeRegsType (int type)
1226 debugLog ("%s\n", __FUNCTION__);
1227 if (type == REG_PTR)
1229 if ((nfr = nFreeRegs (type)) == 0)
1230 return nFreeRegs (REG_GPR);
1233 return nFreeRegs (type);
1236 static void writeSetUsedRegs(FILE *of, set *dRegs)
1241 for (dReg = setFirstItem(dRegs) ; dReg ;
1242 dReg = setNextItem(dRegs)) {
1245 fprintf (of, "\t%s\n",dReg->name);
1251 extern void pic16_groupRegistersInSection(set *regset);
1253 extern void pic16_dump_equates(FILE *of, set *equs);
1254 extern void pic16_dump_access(FILE *of, set *section);
1255 //extern void pic16_dump_map(void);
1256 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1257 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1258 extern void pic16_dump_int_registers(FILE *of, set *section);
1259 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1261 extern void pic16_dump_gsection(FILE *of, set *sections);
1263 static void packBits(set *bregs)
1267 regs *bitfield=NULL;
1268 regs *relocbitfield=NULL;
1274 for (regset = bregs ; regset ;
1275 regset = regset->next) {
1277 breg = regset->item;
1278 breg->isBitField = 1;
1279 //fprintf(stderr,"bit reg: %s\n",breg->name);
1282 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1284 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1285 breg->rIdx = breg->address & 7;
1286 breg->address >>= 3;
1289 sprintf (buffer, "fbitfield%02x", breg->address);
1290 //fprintf(stderr,"new bit field\n");
1291 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1292 bitfield->isBitField = 1;
1293 bitfield->isFixed = 1;
1294 bitfield->address = breg->address;
1295 addSet(&pic16_dynDirectRegs,bitfield);
1296 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1298 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1301 breg->reg_alias = bitfield;
1305 if(!relocbitfield || bit_no >7) {
1308 sprintf (buffer, "bitfield%d", byte_no);
1309 //fprintf(stderr,"new relocatable bit field\n");
1310 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1311 relocbitfield->isBitField = 1;
1312 addSet(&pic16_dynDirectRegs,relocbitfield);
1313 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1317 breg->reg_alias = relocbitfield;
1318 breg->address = rDirectIdx; /* byte_no; */
1319 breg->rIdx = bit_no++;
1325 void pic16_writeUsedRegs(FILE *of)
1327 packBits(pic16_dynDirectBitRegs);
1329 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1330 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1331 pic16_groupRegistersInSection(pic16_dynStackRegs);
1332 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1333 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1334 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1335 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1338 pic16_dump_equates(of, pic16_equ_data);
1340 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1341 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1343 /* dump access bank symbols */
1344 pic16_dump_access(of, pic16_acs_udata);
1346 /* dump initialised data */
1347 pic16_dump_isection(of, rel_idataSymSet, 0);
1348 pic16_dump_isection(of, fix_idataSymSet, 1);
1351 /* dump internal registers */
1352 pic16_dump_int_registers(of, pic16_int_regs);
1355 /* dump generic section variables */
1356 pic16_dump_gsection(of, sectNames);
1358 /* dump other variables */
1359 pic16_dump_usection(of, pic16_rel_udata, 0);
1360 pic16_dump_usection(of, pic16_fix_udata, 1);
1364 /*-----------------------------------------------------------------*/
1365 /* computeSpillable - given a point find the spillable live ranges */
1366 /*-----------------------------------------------------------------*/
1368 computeSpillable (iCode * ic)
1372 debugLog ("%s\n", __FUNCTION__);
1373 /* spillable live ranges are those that are live at this
1374 point . the following categories need to be subtracted
1376 a) - those that are already spilt
1377 b) - if being used by this one
1378 c) - defined by this one */
1380 spillable = bitVectCopy (ic->rlive);
1382 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1384 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1385 bitVectUnSetBit (spillable, ic->defKey);
1386 spillable = bitVectIntersect (spillable, _G.regAssigned);
1391 /*-----------------------------------------------------------------*/
1392 /* noSpilLoc - return true if a variable has no spil location */
1393 /*-----------------------------------------------------------------*/
1395 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1397 debugLog ("%s\n", __FUNCTION__);
1398 return (sym->usl.spillLoc ? 0 : 1);
1401 /*-----------------------------------------------------------------*/
1402 /* hasSpilLoc - will return 1 if the symbol has spil location */
1403 /*-----------------------------------------------------------------*/
1405 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1407 debugLog ("%s\n", __FUNCTION__);
1408 return (sym->usl.spillLoc ? 1 : 0);
1411 /*-----------------------------------------------------------------*/
1412 /* directSpilLoc - will return 1 if the splilocation is in direct */
1413 /*-----------------------------------------------------------------*/
1415 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1417 debugLog ("%s\n", __FUNCTION__);
1418 if (sym->usl.spillLoc &&
1419 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1425 /*-----------------------------------------------------------------*/
1426 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1427 /* but is not used as a pointer */
1428 /*-----------------------------------------------------------------*/
1430 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1432 debugLog ("%s\n", __FUNCTION__);
1433 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1436 /*-----------------------------------------------------------------*/
1437 /* rematable - will return 1 if the remat flag is set */
1438 /*-----------------------------------------------------------------*/
1440 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1442 debugLog ("%s\n", __FUNCTION__);
1446 /*-----------------------------------------------------------------*/
1447 /* notUsedInRemaining - not used or defined in remain of the block */
1448 /*-----------------------------------------------------------------*/
1450 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1452 debugLog ("%s\n", __FUNCTION__);
1453 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1454 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1457 /*-----------------------------------------------------------------*/
1458 /* allLRs - return true for all */
1459 /*-----------------------------------------------------------------*/
1461 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1463 debugLog ("%s\n", __FUNCTION__);
1467 /*-----------------------------------------------------------------*/
1468 /* liveRangesWith - applies function to a given set of live range */
1469 /*-----------------------------------------------------------------*/
1471 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1472 eBBlock * ebp, iCode * ic)
1477 debugLog ("%s\n", __FUNCTION__);
1478 if (!lrs || !lrs->size)
1481 for (i = 1; i < lrs->size; i++)
1484 if (!bitVectBitValue (lrs, i))
1487 /* if we don't find it in the live range
1488 hash table we are in serious trouble */
1489 if (!(sym = hTabItemWithKey (liveRanges, i)))
1491 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1492 "liveRangesWith could not find liveRange");
1496 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1497 addSetHead (&rset, sym);
1504 /*-----------------------------------------------------------------*/
1505 /* leastUsedLR - given a set determines which is the least used */
1506 /*-----------------------------------------------------------------*/
1508 leastUsedLR (set * sset)
1510 symbol *sym = NULL, *lsym = NULL;
1512 debugLog ("%s\n", __FUNCTION__);
1513 sym = lsym = setFirstItem (sset);
1518 for (; lsym; lsym = setNextItem (sset))
1521 /* if usage is the same then prefer
1522 the spill the smaller of the two */
1523 if (lsym->used == sym->used)
1524 if (getSize (lsym->type) < getSize (sym->type))
1528 if (lsym->used < sym->used)
1533 setToNull ((void *) &sset);
1538 /*-----------------------------------------------------------------*/
1539 /* noOverLap - will iterate through the list looking for over lap */
1540 /*-----------------------------------------------------------------*/
1542 noOverLap (set * itmpStack, symbol * fsym)
1545 debugLog ("%s\n", __FUNCTION__);
1548 for (sym = setFirstItem (itmpStack); sym;
1549 sym = setNextItem (itmpStack))
1551 if (sym->liveTo > fsym->liveFrom)
1559 /*-----------------------------------------------------------------*/
1560 /* isFree - will return 1 if the a free spil location is found */
1561 /*-----------------------------------------------------------------*/
1566 V_ARG (symbol **, sloc);
1567 V_ARG (symbol *, fsym);
1569 debugLog ("%s\n", __FUNCTION__);
1570 /* if already found */
1574 /* if it is free && and the itmp assigned to
1575 this does not have any overlapping live ranges
1576 with the one currently being assigned and
1577 the size can be accomodated */
1579 noOverLap (sym->usl.itmpStack, fsym) &&
1580 getSize (sym->type) >= getSize (fsym->type))
1589 /*-----------------------------------------------------------------*/
1590 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1591 /*-----------------------------------------------------------------*/
1593 spillLRWithPtrReg (symbol * forSym)
1599 debugLog ("%s\n", __FUNCTION__);
1600 if (!_G.regAssigned ||
1601 bitVectIsZero (_G.regAssigned))
1604 r0 = pic16_regWithIdx (R0_IDX);
1605 r1 = pic16_regWithIdx (R1_IDX);
1607 /* for all live ranges */
1608 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1609 lrsym = hTabNextItem (liveRanges, &k))
1613 /* if no registers assigned to it or
1615 /* if it does not overlap with this then
1616 not need to spill it */
1618 if (lrsym->isspilt || !lrsym->nRegs ||
1619 (lrsym->liveTo < forSym->liveFrom))
1622 /* go thru the registers : if it is either
1623 r0 or r1 then spil it */
1624 for (j = 0; j < lrsym->nRegs; j++)
1625 if (lrsym->regs[j] == r0 ||
1626 lrsym->regs[j] == r1)
1635 /*-----------------------------------------------------------------*/
1636 /* createStackSpil - create a location on the stack to spil */
1637 /*-----------------------------------------------------------------*/
1639 createStackSpil (symbol * sym)
1641 symbol *sloc = NULL;
1642 int useXstack, model, noOverlay;
1644 char slocBuffer[30];
1645 debugLog ("%s\n", __FUNCTION__);
1647 /* first go try and find a free one that is already
1648 existing on the stack */
1649 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1651 /* found a free one : just update & return */
1652 sym->usl.spillLoc = sloc;
1655 addSetHead (&sloc->usl.itmpStack, sym);
1659 /* could not then have to create one , this is the hard part
1660 we need to allocate this on the stack : this is really a
1661 hack!! but cannot think of anything better at this time */
1663 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1665 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1666 __FILE__, __LINE__);
1670 sloc = newiTemp (slocBuffer);
1672 /* set the type to the spilling symbol */
1673 sloc->type = copyLinkChain (sym->type);
1674 sloc->etype = getSpec (sloc->type);
1675 SPEC_SCLS (sloc->etype) = S_DATA;
1676 SPEC_EXTR (sloc->etype) = 0;
1677 SPEC_STAT (sloc->etype) = 0;
1679 /* we don't allow it to be allocated`
1680 onto the external stack since : so we
1681 temporarily turn it off ; we also
1682 turn off memory model to prevent
1683 the spil from going to the external storage
1684 and turn off overlaying
1687 useXstack = options.useXstack;
1688 model = options.model;
1689 noOverlay = options.noOverlay;
1690 options.noOverlay = 1;
1691 options.model = options.useXstack = 0;
1695 options.useXstack = useXstack;
1696 options.model = model;
1697 options.noOverlay = noOverlay;
1698 sloc->isref = 1; /* to prevent compiler warning */
1700 /* if it is on the stack then update the stack */
1701 if (IN_STACK (sloc->etype))
1703 currFunc->stack += getSize (sloc->type);
1704 _G.stackExtend += getSize (sloc->type);
1707 _G.dataExtend += getSize (sloc->type);
1709 /* add it to the _G.stackSpil set */
1710 addSetHead (&_G.stackSpil, sloc);
1711 sym->usl.spillLoc = sloc;
1714 /* add it to the set of itempStack set
1715 of the spill location */
1716 addSetHead (&sloc->usl.itmpStack, sym);
1720 /*-----------------------------------------------------------------*/
1721 /* isSpiltOnStack - returns true if the spil location is on stack */
1722 /*-----------------------------------------------------------------*/
1724 isSpiltOnStack (symbol * sym)
1728 debugLog ("%s\n", __FUNCTION__);
1735 /* if (sym->_G.stackSpil) */
1738 if (!sym->usl.spillLoc)
1741 etype = getSpec (sym->usl.spillLoc->type);
1742 if (IN_STACK (etype))
1748 /*-----------------------------------------------------------------*/
1749 /* spillThis - spils a specific operand */
1750 /*-----------------------------------------------------------------*/
1752 spillThis (symbol * sym)
1755 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1757 /* if this is rematerializable or has a spillLocation
1758 we are okay, else we need to create a spillLocation
1760 if (!(sym->remat || sym->usl.spillLoc))
1761 createStackSpil (sym);
1764 /* mark it has spilt & put it in the spilt set */
1766 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1768 bitVectUnSetBit (_G.regAssigned, sym->key);
1770 for (i = 0; i < sym->nRegs; i++)
1774 freeReg (sym->regs[i]);
1775 sym->regs[i] = NULL;
1778 /* if spilt on stack then free up r0 & r1
1779 if they could have been assigned to some
1781 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1784 spillLRWithPtrReg (sym);
1787 if (sym->usl.spillLoc && !sym->remat)
1788 sym->usl.spillLoc->allocreq = 1;
1792 /*-----------------------------------------------------------------*/
1793 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1794 /*-----------------------------------------------------------------*/
1796 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1798 bitVect *lrcs = NULL;
1802 debugLog ("%s\n", __FUNCTION__);
1803 /* get the spillable live ranges */
1804 lrcs = computeSpillable (ic);
1806 /* get all live ranges that are rematerizable */
1807 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1810 /* return the least used of these */
1811 return leastUsedLR (selectS);
1814 /* get live ranges with spillLocations in direct space */
1815 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1817 sym = leastUsedLR (selectS);
1818 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1819 sym->usl.spillLoc->rname :
1820 sym->usl.spillLoc->name));
1822 /* mark it as allocation required */
1823 sym->usl.spillLoc->allocreq = 1;
1827 /* if the symbol is local to the block then */
1828 if (forSym->liveTo < ebp->lSeq)
1831 /* check if there are any live ranges allocated
1832 to registers that are not used in this block */
1833 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1835 sym = leastUsedLR (selectS);
1836 /* if this is not rematerializable */
1845 /* check if there are any live ranges that not
1846 used in the remainder of the block */
1847 if (!_G.blockSpil &&
1848 !isiCodeInFunctionCall (ic) &&
1849 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1851 sym = leastUsedLR (selectS);
1854 sym->remainSpil = 1;
1861 /* find live ranges with spillocation && not used as pointers */
1862 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1865 sym = leastUsedLR (selectS);
1866 /* mark this as allocation required */
1867 sym->usl.spillLoc->allocreq = 1;
1871 /* find live ranges with spillocation */
1872 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1875 sym = leastUsedLR (selectS);
1876 sym->usl.spillLoc->allocreq = 1;
1880 /* couldn't find then we need to create a spil
1881 location on the stack , for which one? the least
1883 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1886 /* return a created spil location */
1887 sym = createStackSpil (leastUsedLR (selectS));
1888 sym->usl.spillLoc->allocreq = 1;
1892 /* this is an extreme situation we will spill
1893 this one : happens very rarely but it does happen */
1899 /*-----------------------------------------------------------------*/
1900 /* spilSomething - spil some variable & mark registers as free */
1901 /*-----------------------------------------------------------------*/
1903 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1908 debugLog ("%s\n", __FUNCTION__);
1909 /* get something we can spil */
1910 ssym = selectSpil (ic, ebp, forSym);
1912 /* mark it as spilt */
1914 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1916 /* mark it as not register assigned &
1917 take it away from the set */
1918 bitVectUnSetBit (_G.regAssigned, ssym->key);
1920 /* mark the registers as free */
1921 for (i = 0; i < ssym->nRegs; i++)
1923 freeReg (ssym->regs[i]);
1925 /* if spilt on stack then free up r0 & r1
1926 if they could have been assigned to as gprs */
1927 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1930 spillLRWithPtrReg (ssym);
1933 /* if this was a block level spil then insert push & pop
1934 at the start & end of block respectively */
1935 if (ssym->blockSpil)
1937 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1938 /* add push to the start of the block */
1939 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1940 ebp->sch->next : ebp->sch));
1941 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1942 /* add pop to the end of the block */
1943 addiCodeToeBBlock (ebp, nic, NULL);
1946 /* if spilt because not used in the remainder of the
1947 block then add a push before this instruction and
1948 a pop at the end of the block */
1949 if (ssym->remainSpil)
1952 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1953 /* add push just before this instruction */
1954 addiCodeToeBBlock (ebp, nic, ic);
1956 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1957 /* add pop to the end of the block */
1958 addiCodeToeBBlock (ebp, nic, NULL);
1967 /*-----------------------------------------------------------------*/
1968 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1969 /*-----------------------------------------------------------------*/
1971 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1976 debugLog ("%s\n", __FUNCTION__);
1978 /* try for a ptr type */
1979 if ((reg = allocReg (REG_PTR)))
1982 /* try for gpr type */
1983 if ((reg = allocReg (REG_GPR)))
1986 /* we have to spil */
1987 if (!spilSomething (ic, ebp, sym))
1990 /* make sure partially assigned registers aren't reused */
1991 for (j=0; j<=sym->nRegs; j++)
1993 sym->regs[j]->isFree = 0;
1995 /* this looks like an infinite loop but
1996 in really selectSpil will abort */
2000 /*-----------------------------------------------------------------*/
2001 /* getRegGpr - will try for GPR if not spil */
2002 /*-----------------------------------------------------------------*/
2004 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
2009 debugLog ("%s\n", __FUNCTION__);
2011 /* try for gpr type */
2012 if ((reg = allocReg (REG_GPR)))
2015 if (!pic16_ptrRegReq)
2016 if ((reg = allocReg (REG_PTR)))
2019 /* we have to spil */
2020 if (!spilSomething (ic, ebp, sym))
2023 /* make sure partially assigned registers aren't reused */
2024 for (j=0; j<=sym->nRegs; j++)
2026 sym->regs[j]->isFree = 0;
2028 /* this looks like an infinite loop but
2029 in really selectSpil will abort */
2033 /*-----------------------------------------------------------------*/
2034 /* symHasReg - symbol has a given register */
2035 /*-----------------------------------------------------------------*/
2037 symHasReg (symbol * sym, regs * reg)
2041 debugLog ("%s\n", __FUNCTION__);
2042 for (i = 0; i < sym->nRegs; i++)
2043 if (sym->regs[i] == reg)
2049 /*-----------------------------------------------------------------*/
2050 /* deassignLRs - check the live to and if they have registers & are */
2051 /* not spilt then free up the registers */
2052 /*-----------------------------------------------------------------*/
2054 deassignLRs (iCode * ic, eBBlock * ebp)
2060 debugLog ("%s\n", __FUNCTION__);
2061 for (sym = hTabFirstItem (liveRanges, &k); sym;
2062 sym = hTabNextItem (liveRanges, &k))
2065 symbol *psym = NULL;
2066 /* if it does not end here */
2067 if (sym->liveTo > ic->seq)
2070 /* if it was spilt on stack then we can
2071 mark the stack spil location as free */
2076 sym->usl.spillLoc->isFree = 1;
2082 if (!bitVectBitValue (_G.regAssigned, sym->key))
2085 /* special case for shifting: there is a case where shift count
2086 * can be allocated in the same register as the result, so do not
2087 * free right registers if same as result registers, cause genShiftLeft
2088 * will fail -- VR */
2089 if(ic->op == LEFT_OP)
2092 /* special case check if this is an IFX &
2093 the privious one was a pop and the
2094 previous one was not spilt then keep track
2096 if (ic->op == IFX && ic->prev &&
2097 ic->prev->op == IPOP &&
2098 !ic->prev->parmPush &&
2099 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2100 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2106 bitVectUnSetBit (_G.regAssigned, sym->key);
2108 /* if the result of this one needs registers
2109 and does not have it then assign it right
2111 if (IC_RESULT (ic) &&
2112 !(SKIP_IC2 (ic) || /* not a special icode */
2113 ic->op == JUMPTABLE ||
2118 POINTER_SET (ic)) &&
2119 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2120 result->liveTo > ic->seq && /* and will live beyond this */
2121 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2122 result->liveFrom == ic->seq && /* does not start before here */
2123 result->regType == sym->regType && /* same register types */
2124 result->nRegs && /* which needs registers */
2125 !result->isspilt && /* and does not already have them */
2127 !bitVectBitValue (_G.regAssigned, result->key) &&
2128 /* the number of free regs + number of regs in this LR
2129 can accomodate the what result Needs */
2130 ((nfreeRegsType (result->regType) +
2131 sym->nRegs) >= result->nRegs)
2136 // for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2137 /* the above does not free the unsued registers in sym,
2138 * leaving them marked as used, and increasing register usage
2139 * until the end of the function - VR 23/11/05 */
2141 for (i = 0; i < result->nRegs; i++)
2143 result->regs[i] = sym->regs[i];
2145 result->regs[i] = getRegGpr (ic, ebp, result);
2147 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2150 /* free the remaining */
2151 for (; i < sym->nRegs; i++)
2155 if (!symHasReg (psym, sym->regs[i]))
2156 freeReg (sym->regs[i]);
2159 freeReg (sym->regs[i]);
2166 /*-----------------------------------------------------------------*/
2167 /* reassignLR - reassign this to registers */
2168 /*-----------------------------------------------------------------*/
2170 reassignLR (operand * op)
2172 symbol *sym = OP_SYMBOL (op);
2175 debugLog ("%s\n", __FUNCTION__);
2176 /* not spilt any more */
2177 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2178 bitVectUnSetBit (_G.spiltSet, sym->key);
2180 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2184 for (i = 0; i < sym->nRegs; i++)
2185 sym->regs[i]->isFree = 0;
2188 /*-----------------------------------------------------------------*/
2189 /* willCauseSpill - determines if allocating will cause a spill */
2190 /*-----------------------------------------------------------------*/
2192 willCauseSpill (int nr, int rt)
2194 debugLog ("%s\n", __FUNCTION__);
2195 /* first check if there are any avlb registers
2196 of te type required */
2199 /* special case for pointer type
2200 if pointer type not avlb then
2201 check for type gpr */
2202 if (nFreeRegs (rt) >= nr)
2204 if (nFreeRegs (REG_GPR) >= nr)
2209 if (pic16_ptrRegReq)
2211 if (nFreeRegs (rt) >= nr)
2216 if (nFreeRegs (REG_PTR) +
2217 nFreeRegs (REG_GPR) >= nr)
2222 debugLog (" ... yep it will (cause a spill)\n");
2223 /* it will cause a spil */
2227 /*-----------------------------------------------------------------*/
2228 /* positionRegs - the allocator can allocate same registers to res- */
2229 /* ult and operand, if this happens make sure they are in the same */
2230 /* position as the operand otherwise chaos results */
2231 /*-----------------------------------------------------------------*/
2233 positionRegs (symbol * result, symbol * opsym, int lineno)
2235 int count = min (result->nRegs, opsym->nRegs);
2236 int i, j = 0, shared = 0;
2238 debugLog ("%s\n", __FUNCTION__);
2239 /* if the result has been spilt then cannot share */
2244 /* first make sure that they actually share */
2245 for (i = 0; i < count; i++)
2247 for (j = 0; j < count; j++)
2249 if (result->regs[i] == opsym->regs[j] && i != j)
2259 regs *tmp = result->regs[i];
2260 result->regs[i] = result->regs[j];
2261 result->regs[j] = tmp;
2266 /*------------------------------------------------------------------*/
2267 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2268 /* it should either have registers or have beed spilled. Otherwise, */
2269 /* there was an uninitialized variable, so just spill this to get */
2270 /* the operand in a valid state. */
2271 /*------------------------------------------------------------------*/
2273 verifyRegsAssigned (operand *op, iCode * ic)
2278 if (!IS_ITEMP (op)) return;
2280 sym = OP_SYMBOL (op);
2281 if (sym->isspilt) return;
2282 if (!sym->nRegs) return;
2283 if (sym->regs[0]) return;
2285 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2286 sym->prereqv ? sym->prereqv->name : sym->name);
2291 /*-----------------------------------------------------------------*/
2292 /* serialRegAssign - serially allocate registers to the variables */
2293 /*-----------------------------------------------------------------*/
2295 serialRegAssign (eBBlock ** ebbs, int count)
2300 debugLog ("%s\n", __FUNCTION__);
2301 /* for all blocks */
2302 for (i = 0; i < count; i++)
2304 if (ebbs[i]->noPath &&
2305 (ebbs[i]->entryLabel != entryLabel &&
2306 ebbs[i]->entryLabel != returnLabel))
2309 /* of all instructions do */
2310 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2313 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2315 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2316 pic16_allocDirReg(IC_RESULT(ic));
2318 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2319 pic16_allocDirReg(IC_LEFT(ic));
2321 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2322 pic16_allocDirReg(IC_RIGHT(ic));
2324 /* if this is an ipop that means some live
2325 range will have to be assigned again */
2327 reassignLR (IC_LEFT (ic));
2329 /* if result is present && is a true symbol */
2330 if (IC_RESULT (ic) && ic->op != IFX &&
2331 IS_TRUE_SYMOP (IC_RESULT (ic)))
2332 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2334 /* take away registers from live
2335 ranges that end at this instruction */
2336 deassignLRs (ic, ebbs[i]);
2338 /* some don't need registers */
2339 if (SKIP_IC2 (ic) ||
2340 ic->op == JUMPTABLE ||
2344 (IC_RESULT (ic) && POINTER_SET (ic)))
2347 /* now we need to allocate registers
2348 only for the result */
2351 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2357 /* Make sure any spill location is definately allocated */
2358 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2359 !sym->usl.spillLoc->allocreq)
2361 sym->usl.spillLoc->allocreq++;
2364 /* if it does not need or is spilt
2365 or is already assigned to registers
2366 or will not live beyond this instructions */
2369 bitVectBitValue (_G.regAssigned, sym->key) ||
2370 sym->liveTo <= ic->seq)
2373 /* if some liverange has been spilt at the block level
2374 and this one live beyond this block then spil this
2376 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2381 /* if trying to allocate this will cause
2382 a spill and there is nothing to spill
2383 or this one is rematerializable then
2385 willCS = willCauseSpill (sym->nRegs, sym->regType);
2387 /* explicit turn off register spilling */
2390 spillable = computeSpillable (ic);
2392 (willCS && bitVectIsZero (spillable)))
2400 /* If the live range preceeds the point of definition
2401 then ideally we must take into account registers that
2402 have been allocated after sym->liveFrom but freed
2403 before ic->seq. This is complicated, so spill this
2404 symbol instead and let fillGaps handle the allocation. */
2406 if (sym->liveFrom < ic->seq)
2412 /* if it has a spillocation & is used less than
2413 all other live ranges then spill this */
2415 if (sym->usl.spillLoc) {
2416 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2417 allLRs, ebbs[i], ic));
2418 if (leastUsed && leastUsed->used > sym->used) {
2423 /* if none of the liveRanges have a spillLocation then better
2424 to spill this one than anything else already assigned to registers */
2425 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2426 /* if this is local to this block then we might find a block spil */
2427 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2435 if (ic->op == RECEIVE)
2436 debugLog ("When I get clever, I'll optimize the receive logic\n");
2438 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2439 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2440 && (ic->next->op == IFX)
2441 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2443 /* skip register allocation since none will be used */
2444 for(j=0;j<sym->nRegs;j++)
2445 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2446 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2451 /* if we need ptr regs for the right side
2453 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2454 <= (unsigned) PTRSIZE)
2459 /* else we assign registers to it */
2460 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2463 bitVectDebugOn(_G.regAssigned, debugF);
2465 for (j = 0; j < sym->nRegs; j++)
2467 if (sym->regType == REG_PTR)
2468 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2470 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2472 /* if the allocation falied which means
2473 this was spilt then break */
2477 debugLog (" %d - \n", __LINE__);
2479 /* if it shares registers with operands make sure
2480 that they are in the same position */
2481 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2482 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2483 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2484 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2485 /* do the same for the right operand */
2486 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2487 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2488 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2489 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2491 debugLog (" %d - \n", __LINE__);
2494 debugLog (" %d - \n", __LINE__);
2503 /* Check for and fix any problems with uninitialized operands */
2504 for (i = 0; i < count; i++)
2508 if (ebbs[i]->noPath &&
2509 (ebbs[i]->entryLabel != entryLabel &&
2510 ebbs[i]->entryLabel != returnLabel))
2513 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2520 verifyRegsAssigned (IC_COND (ic), ic);
2524 if (ic->op == JUMPTABLE)
2526 verifyRegsAssigned (IC_JTCOND (ic), ic);
2530 verifyRegsAssigned (IC_RESULT (ic), ic);
2531 verifyRegsAssigned (IC_LEFT (ic), ic);
2532 verifyRegsAssigned (IC_RIGHT (ic), ic);
2538 /*-----------------------------------------------------------------*/
2539 /* rUmaskForOp :- returns register mask for an operand */
2540 /*-----------------------------------------------------------------*/
2542 rUmaskForOp (operand * op)
2548 debugLog ("%s\n", __FUNCTION__);
2549 /* only temporaries are assigned registers */
2553 sym = OP_SYMBOL (op);
2555 /* if spilt or no registers assigned to it
2557 if (sym->isspilt || !sym->nRegs)
2560 rumask = newBitVect (pic16_nRegs);
2562 for (j = 0; j < sym->nRegs; j++)
2564 rumask = bitVectSetBit (rumask,
2565 sym->regs[j]->rIdx);
2571 /*-----------------------------------------------------------------*/
2572 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2573 /*-----------------------------------------------------------------*/
2575 regsUsedIniCode (iCode * ic)
2577 bitVect *rmask = newBitVect (pic16_nRegs);
2579 debugLog ("%s\n", __FUNCTION__);
2580 /* do the special cases first */
2583 rmask = bitVectUnion (rmask,
2584 rUmaskForOp (IC_COND (ic)));
2588 /* for the jumptable */
2589 if (ic->op == JUMPTABLE)
2591 rmask = bitVectUnion (rmask,
2592 rUmaskForOp (IC_JTCOND (ic)));
2597 /* of all other cases */
2599 rmask = bitVectUnion (rmask,
2600 rUmaskForOp (IC_LEFT (ic)));
2604 rmask = bitVectUnion (rmask,
2605 rUmaskForOp (IC_RIGHT (ic)));
2608 rmask = bitVectUnion (rmask,
2609 rUmaskForOp (IC_RESULT (ic)));
2615 /*-----------------------------------------------------------------*/
2616 /* createRegMask - for each instruction will determine the regsUsed */
2617 /*-----------------------------------------------------------------*/
2619 createRegMask (eBBlock ** ebbs, int count)
2623 debugLog ("%s\n", __FUNCTION__);
2624 /* for all blocks */
2625 for (i = 0; i < count; i++)
2629 if (ebbs[i]->noPath &&
2630 (ebbs[i]->entryLabel != entryLabel &&
2631 ebbs[i]->entryLabel != returnLabel))
2634 /* for all instructions */
2635 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2640 if (SKIP_IC2 (ic) || !ic->rlive)
2643 /* first mark the registers used in this
2645 ic->rUsed = regsUsedIniCode (ic);
2646 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2648 /* now create the register mask for those
2649 registers that are in use : this is a
2650 super set of ic->rUsed */
2651 ic->rMask = newBitVect (pic16_nRegs + 1);
2653 /* for all live Ranges alive at this point */
2654 for (j = 1; j < ic->rlive->size; j++)
2659 /* if not alive then continue */
2660 if (!bitVectBitValue (ic->rlive, j))
2663 /* find the live range we are interested in */
2664 if (!(sym = hTabItemWithKey (liveRanges, j)))
2666 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2667 "createRegMask cannot find live range");
2671 /* if no register assigned to it */
2672 if (!sym->nRegs || sym->isspilt)
2675 /* for all the registers allocated to it */
2676 for (k = 0; k < sym->nRegs; k++)
2679 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2685 /*-----------------------------------------------------------------*/
2686 /* rematStr - returns the rematerialized string for a remat var */
2687 /*-----------------------------------------------------------------*/
2689 rematStr (symbol * sym)
2692 iCode *ic = sym->rematiCode;
2693 symbol *psym = NULL;
2695 debugLog ("%s\n", __FUNCTION__);
2697 //printf ("%s\n", s);
2699 /* if plus or minus print the right hand side */
2701 if (ic->op == '+' || ic->op == '-') {
2703 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2705 sprintf (s, "(%s %c 0x%04x)",
2706 OP_SYMBOL (IC_LEFT (ric))->rname,
2708 (int) operandLitValue (IC_RIGHT (ic)));
2711 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2713 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2714 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2719 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2720 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2722 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2727 /*-----------------------------------------------------------------*/
2728 /* rematStr - returns the rematerialized string for a remat var */
2729 /*-----------------------------------------------------------------*/
2731 rematStr (symbol * sym)
2734 iCode *ic = sym->rematiCode;
2736 debugLog ("%s\n", __FUNCTION__);
2741 /* if plus or minus print the right hand side */
2743 if (ic->op == '+' || ic->op == '-') {
2744 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2747 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2751 if (ic->op == '+' || ic->op == '-')
2753 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2754 sprintf (s, "(%s %c 0x%04x)",
2755 OP_SYMBOL (IC_LEFT (ric))->rname,
2757 (int) operandLitValue (IC_RIGHT (ic)));
2760 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2762 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2766 /* we reached the end */
2767 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2771 printf ("%s\n", buffer);
2776 /*-----------------------------------------------------------------*/
2777 /* regTypeNum - computes the type & number of registers required */
2778 /*-----------------------------------------------------------------*/
2786 debugLog ("%s\n", __FUNCTION__);
2787 /* for each live range do */
2788 for (sym = hTabFirstItem (liveRanges, &k); sym;
2789 sym = hTabNextItem (liveRanges, &k)) {
2791 debugLog (" %d - %s\n", __LINE__, sym->rname);
2792 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2794 /* if used zero times then no registers needed */
2795 if ((sym->liveTo - sym->liveFrom) == 0)
2799 /* if the live range is a temporary */
2802 debugLog (" %d - itemp register\n", __LINE__);
2804 /* if the type is marked as a conditional */
2805 if (sym->regType == REG_CND)
2808 /* if used in return only then we don't
2810 if (sym->ruonly || sym->accuse) {
2811 if (IS_AGGREGATE (sym->type) || sym->isptr)
2812 sym->type = aggrToPtr (sym->type, FALSE);
2813 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2817 /* if the symbol has only one definition &
2818 that definition is a get_pointer and the
2819 pointer we are getting is rematerializable and
2822 if (bitVectnBitsOn (sym->defs) == 1 &&
2823 (ic = hTabItemWithKey (iCodehTab,
2824 bitVectFirstBit (sym->defs))) &&
2826 !IS_BITVAR (sym->etype) &&
2827 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2829 // continue; /* FIXME -- VR */
2830 if (ptrPseudoSymSafe (sym, ic)) {
2834 debugLog (" %d - \n", __LINE__);
2836 /* create a psuedo symbol & force a spil */
2837 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2838 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2839 psym->type = sym->type;
2840 psym->etype = sym->etype;
2841 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2842 strcpy (psym->rname, psym->name);
2844 sym->usl.spillLoc = psym;
2848 /* if in data space or idata space then try to
2849 allocate pointer register */
2853 /* if not then we require registers */
2854 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2855 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2856 getSize (sym->type));
2860 if(IS_PTR_CONST (sym->type)) {
2862 if(IS_CODEPTR (sym->type)) {
2864 // what IS this ???? (HJD)
2865 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2866 sym->nRegs = 3; // patch 14
2869 if (sym->nRegs > 4) {
2870 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2871 printTypeChain (sym->type, stderr);
2872 fprintf (stderr, "\n");
2875 /* determine the type of register required */
2876 if (sym->nRegs == 1 &&
2877 IS_PTR (sym->type) &&
2879 sym->regType = REG_PTR;
2881 sym->regType = REG_GPR;
2884 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2888 /* for the first run we don't provide */
2889 /* registers for true symbols we will */
2890 /* see how things go */
2896 static DEFSETFUNC (markRegFree)
2898 ((regs *)item)->isFree = 1;
2899 // ((regs *)item)->wasUsed = 0;
2904 DEFSETFUNC (pic16_deallocReg)
2906 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2907 ((regs *)item)->isFree = 1;
2908 ((regs *)item)->wasUsed = 0;
2912 /*-----------------------------------------------------------------*/
2913 /* freeAllRegs - mark all registers as free */
2914 /*-----------------------------------------------------------------*/
2916 pic16_freeAllRegs ()
2918 debugLog ("%s\n", __FUNCTION__);
2920 applyToSet(pic16_dynAllocRegs,markRegFree);
2921 applyToSet(pic16_dynStackRegs,markRegFree);
2924 /*-----------------------------------------------------------------*/
2925 /*-----------------------------------------------------------------*/
2927 pic16_deallocateAllRegs ()
2929 debugLog ("%s\n", __FUNCTION__);
2931 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2935 /*-----------------------------------------------------------------*/
2936 /* deallocStackSpil - this will set the stack pointer back */
2937 /*-----------------------------------------------------------------*/
2939 DEFSETFUNC (deallocStackSpil)
2943 debugLog ("%s\n", __FUNCTION__);
2948 /*-----------------------------------------------------------------*/
2949 /* farSpacePackable - returns the packable icode for far variables */
2950 /*-----------------------------------------------------------------*/
2952 farSpacePackable (iCode * ic)
2956 debugLog ("%s\n", __FUNCTION__);
2957 /* go thru till we find a definition for the
2958 symbol on the right */
2959 for (dic = ic->prev; dic; dic = dic->prev)
2962 /* if the definition is a call then no */
2963 if ((dic->op == CALL || dic->op == PCALL) &&
2964 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2969 /* if shift by unknown amount then not */
2970 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2971 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2974 /* if pointer get and size > 1 */
2975 if (POINTER_GET (dic) &&
2976 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2979 if (POINTER_SET (dic) &&
2980 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2983 /* if any three is a true symbol in far space */
2984 if (IC_RESULT (dic) &&
2985 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2986 isOperandInFarSpace (IC_RESULT (dic)))
2989 if (IC_RIGHT (dic) &&
2990 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2991 isOperandInFarSpace (IC_RIGHT (dic)) &&
2992 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2995 if (IC_LEFT (dic) &&
2996 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2997 isOperandInFarSpace (IC_LEFT (dic)) &&
2998 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
3001 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
3003 if ((dic->op == LEFT_OP ||
3004 dic->op == RIGHT_OP ||
3006 IS_OP_LITERAL (IC_RIGHT (dic)))
3017 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
3021 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3022 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3023 debugAopGet (" result:", IC_RESULT (ic));
3024 debugAopGet (" left:", IC_LEFT (ic));
3025 debugAopGet (" right:", IC_RIGHT (ic));
3034 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3036 /*-----------------------------------------------------------------*/
3037 /* packRegsForAssign - register reduction for assignment */
3038 /*-----------------------------------------------------------------*/
3040 packRegsForAssign (iCode * ic, eBBlock * ebp)
3044 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3045 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3046 debugAopGet (" result:", IC_RESULT (ic));
3047 debugAopGet (" left:", IC_LEFT (ic));
3048 debugAopGet (" right:", IC_RIGHT (ic));
3050 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3052 debugLog(" %d - actuall processing\n", __LINE__ );
3054 if (!IS_ITEMP (IC_RESULT (ic))) {
3055 pic16_allocDirReg(IC_RESULT (ic));
3056 debugLog (" %d - result is not temp\n", __LINE__);
3059 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3061 /* See BUGLOG0001 - VR */
3063 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3064 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3065 pic16_allocDirReg(IC_RIGHT (ic));
3070 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3071 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3073 debugLog (" %d - not packing - right side fails \n", __LINE__);
3077 /* if the true symbol is defined in far space or on stack
3078 then we should not since this will increase register pressure */
3079 if (isOperandInFarSpace (IC_RESULT (ic)))
3081 if ((dic = farSpacePackable (ic)))
3088 /* find the definition of iTempNN scanning backwards if we find a
3089 a use of the true symbol before we find the definition then
3091 for (dic = ic->prev; dic; dic = dic->prev)
3094 /* if there is a function call and this is
3095 a parameter & not my parameter then don't pack it */
3096 if ((dic->op == CALL || dic->op == PCALL) &&
3097 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3098 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3100 debugLog (" %d - \n", __LINE__);
3109 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3111 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3112 IS_OP_VOLATILE (IC_RESULT (dic)))
3114 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3120 if( IS_SYMOP( IC_RESULT(dic)) &&
3121 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3123 debugLog (" %d - result is bitfield\n", __LINE__);
3129 if (IS_SYMOP (IC_RESULT (dic)) &&
3130 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3132 /* A previous result was assigned to the same register - we'll our definition */
3133 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3134 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3135 if (POINTER_SET (dic))
3141 if (IS_SYMOP (IC_RIGHT (dic)) &&
3142 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3143 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3145 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3150 if (IS_SYMOP (IC_LEFT (dic)) &&
3151 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3152 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3154 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3159 if (POINTER_SET (dic) &&
3160 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3162 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3170 return 0; /* did not find */
3173 /* This code is taken from the hc08 port. Do not know
3174 * if it fits for pic16, but I leave it here just in case */
3176 /* if assignment then check that right is not a bit */
3177 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3178 sym_link *etype = operandType (IC_RIGHT (dic));
3180 if (IS_BITFIELD (etype)) {
3181 /* if result is a bit too then it's ok */
3182 etype = operandType (IC_RESULT (dic));
3183 if (!IS_BITFIELD (etype)) {
3184 debugLog(" %d bitfields\n");
3191 /* if the result is on stack or iaccess then it must be
3192 the same atleast one of the operands */
3193 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3194 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3196 /* the operation has only one symbol
3197 operator then we can pack */
3198 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3199 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3202 if (!((IC_LEFT (dic) &&
3203 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3205 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3209 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3210 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3211 /* found the definition */
3212 /* replace the result with the result of */
3213 /* this assignment and remove this assignment */
3216 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3217 IC_RESULT (dic) = IC_RESULT (ic);
3219 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3221 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3223 /* delete from liverange table also
3224 delete from all the points inbetween and the new
3226 for (sic = dic; sic != ic; sic = sic->next)
3228 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3229 if (IS_ITEMP (IC_RESULT (dic)))
3230 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3233 remiCodeFromeBBlock (ebp, ic);
3234 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3236 debugLog(" %d\n", __LINE__ );
3237 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3238 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3245 #define NO_packRegsForAccUse
3246 #define NO_packRegsForSupport
3247 #define NO_packRegsForOneuse
3248 #define NO_cast_peep
3253 #ifndef NO_packRegsForSupport
3254 /*-----------------------------------------------------------------*/
3255 /* findAssignToSym : scanning backwards looks for first assig found */
3256 /*-----------------------------------------------------------------*/
3258 findAssignToSym (operand * op, iCode * ic)
3262 debugLog ("%s\n", __FUNCTION__);
3263 for (dic = ic->prev; dic; dic = dic->prev)
3266 /* if definition by assignment */
3267 if (dic->op == '=' &&
3268 !POINTER_SET (dic) &&
3269 IC_RESULT (dic)->key == op->key
3270 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3274 /* we are interested only if defined in far space */
3275 /* or in stack space in case of + & - */
3277 /* if assigned to a non-symbol then return
3279 if (!IS_SYMOP (IC_RIGHT (dic)))
3282 /* if the symbol is in far space then
3284 if (isOperandInFarSpace (IC_RIGHT (dic)))
3287 /* for + & - operations make sure that
3288 if it is on the stack it is the same
3289 as one of the three operands */
3290 if ((ic->op == '+' || ic->op == '-') &&
3291 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3293 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3294 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3295 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3303 /* if we find an usage then we cannot delete it */
3304 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3307 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3310 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3314 /* now make sure that the right side of dic
3315 is not defined between ic & dic */
3318 iCode *sic = dic->next;
3320 for (; sic != ic; sic = sic->next)
3321 if (IC_RESULT (sic) &&
3322 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3333 #ifndef NO_packRegsForSupport
3334 /*-----------------------------------------------------------------*/
3335 /* packRegsForSupport :- reduce some registers for support calls */
3336 /*-----------------------------------------------------------------*/
3338 packRegsForSupport (iCode * ic, eBBlock * ebp)
3342 debugLog ("%s\n", __FUNCTION__);
3343 /* for the left & right operand :- look to see if the
3344 left was assigned a true symbol in far space in that
3345 case replace them */
3346 if (IS_ITEMP (IC_LEFT (ic)) &&
3347 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3349 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3355 debugAopGet ("removing left:", IC_LEFT (ic));
3357 /* found it we need to remove it from the
3359 for (sic = dic; sic != ic; sic = sic->next)
3360 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3362 IC_LEFT (ic)->operand.symOperand =
3363 IC_RIGHT (dic)->operand.symOperand;
3364 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3365 remiCodeFromeBBlock (ebp, dic);
3366 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3367 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3371 /* do the same for the right operand */
3374 IS_ITEMP (IC_RIGHT (ic)) &&
3375 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3377 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3383 /* if this is a subtraction & the result
3384 is a true symbol in far space then don't pack */
3385 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3387 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3388 if (IN_FARSPACE (SPEC_OCLS (etype)))
3392 debugAopGet ("removing right:", IC_RIGHT (ic));
3394 /* found it we need to remove it from the
3396 for (sic = dic; sic != ic; sic = sic->next)
3397 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3399 IC_RIGHT (ic)->operand.symOperand =
3400 IC_RIGHT (dic)->operand.symOperand;
3401 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3403 remiCodeFromeBBlock (ebp, dic);
3404 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3405 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3414 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3416 #ifndef NO_packRegsForOneuse
3417 /*-----------------------------------------------------------------*/
3418 /* packRegsForOneuse : - will reduce some registers for single Use */
3419 /*-----------------------------------------------------------------*/
3421 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3428 debugLog ("%s\n", __FUNCTION__);
3429 /* if returning a literal then do nothing */
3433 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3436 /* only upto 2 bytes since we cannot predict
3437 the usage of b, & acc */
3438 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3446 /* this routine will mark the a symbol as used in one
3447 instruction use only && if the definition is local
3448 (ie. within the basic block) && has only one definition &&
3449 that definition is either a return value from a
3450 function or does not contain any variables in
3454 uses = bitVectCopy (OP_USES (op));
3455 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3456 if (!bitVectIsZero (uses)) /* has other uses */
3461 if (bitVectnBitsOn (OP_USES (op)) > 1)
3465 /* if it has only one defintion */
3466 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3467 return NULL; /* has more than one definition */
3469 /* get that definition */
3471 hTabItemWithKey (iCodehTab,
3472 bitVectFirstBit (OP_DEFS (op)))))
3475 /* found the definition now check if it is local */
3476 if (dic->seq < ebp->fSeq ||
3477 dic->seq > ebp->lSeq)
3478 return NULL; /* non-local */
3480 /* now check if it is the return from
3482 if (dic->op == CALL || dic->op == PCALL)
3484 if (ic->op != SEND && ic->op != RETURN &&
3485 !POINTER_SET(ic) && !POINTER_GET(ic))
3487 OP_SYMBOL (op)->ruonly = 1;
3496 /* otherwise check that the definition does
3497 not contain any symbols in far space */
3498 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3499 isOperandInFarSpace (IC_RIGHT (dic)) ||
3500 IS_OP_RUONLY (IC_LEFT (ic)) ||
3501 IS_OP_RUONLY (IC_RIGHT (ic)))
3506 /* if pointer set then make sure the pointer
3508 if (POINTER_SET (dic) &&
3509 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3512 if (POINTER_GET (dic) &&
3513 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3519 /* also make sure the intervenening instructions
3520 don't have any thing in far space */
3521 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3524 /* if there is an intervening function call then no */
3525 if (dic->op == CALL || dic->op == PCALL)
3527 /* if pointer set then make sure the pointer
3529 if (POINTER_SET (dic) &&
3530 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3533 if (POINTER_GET (dic) &&
3534 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3537 /* if address of & the result is remat then okay */
3538 if (dic->op == ADDRESS_OF &&
3539 OP_SYMBOL (IC_RESULT (dic))->remat)
3542 /* if operand has size of three or more & this
3543 operation is a '*','/' or '%' then 'b' may
3545 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3546 getSize (operandType (op)) >= 2)
3549 /* if left or right or result is in far space */
3550 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3551 isOperandInFarSpace (IC_RIGHT (dic)) ||
3552 isOperandInFarSpace (IC_RESULT (dic)) ||
3553 IS_OP_RUONLY (IC_LEFT (dic)) ||
3554 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3555 IS_OP_RUONLY (IC_RESULT (dic)))
3561 OP_SYMBOL (op)->ruonly = 1;
3568 /*-----------------------------------------------------------------*/
3569 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3570 /*-----------------------------------------------------------------*/
3572 isBitwiseOptimizable (iCode * ic)
3574 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3575 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3577 debugLog ("%s\n", __FUNCTION__);
3578 /* bitwise operations are considered optimizable
3579 under the following conditions (Jean-Louis VERN)
3591 if (IS_LITERAL (rtype) ||
3592 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3599 #ifndef NO_packRegsForAccUse
3601 /*-----------------------------------------------------------------*/
3602 /* packRegsForAccUse - pack registers for acc use */
3603 /*-----------------------------------------------------------------*/
3605 packRegsForAccUse (iCode * ic)
3609 debugLog ("%s\n", __FUNCTION__);
3611 /* if this is an aggregate, e.g. a one byte char array */
3612 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3615 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3617 /* if + or - then it has to be one byte result */
3618 if ((ic->op == '+' || ic->op == '-')
3619 && getSize (operandType (IC_RESULT (ic))) > 1)
3622 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3623 /* if shift operation make sure right side is not a literal */
3624 if (ic->op == RIGHT_OP &&
3625 (isOperandLiteral (IC_RIGHT (ic)) ||
3626 getSize (operandType (IC_RESULT (ic))) > 1))
3629 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3630 if (ic->op == LEFT_OP &&
3631 (isOperandLiteral (IC_RIGHT (ic)) ||
3632 getSize (operandType (IC_RESULT (ic))) > 1))
3635 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3636 if (IS_BITWISE_OP (ic) &&
3637 getSize (operandType (IC_RESULT (ic))) > 1)
3641 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3642 /* has only one definition */
3643 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3646 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3647 /* has only one use */
3648 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3651 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3652 /* and the usage immediately follows this iCode */
3653 if (!(uic = hTabItemWithKey (iCodehTab,
3654 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3657 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3658 if (ic->next != uic)
3661 /* if it is a conditional branch then we definitely can */
3665 if (uic->op == JUMPTABLE)
3668 /* if the usage is not is an assignment
3669 or an arithmetic / bitwise / shift operation then not */
3670 if (POINTER_SET (uic) &&
3671 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3674 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3675 if (uic->op != '=' &&
3676 !IS_ARITHMETIC_OP (uic) &&
3677 !IS_BITWISE_OP (uic) &&
3678 uic->op != LEFT_OP &&
3679 uic->op != RIGHT_OP)
3682 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3683 /* if used in ^ operation then make sure right is not a
3685 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3688 /* if shift operation make sure right side is not a literal */
3689 if (uic->op == RIGHT_OP &&
3690 (isOperandLiteral (IC_RIGHT (uic)) ||
3691 getSize (operandType (IC_RESULT (uic))) > 1))
3694 if (uic->op == LEFT_OP &&
3695 (isOperandLiteral (IC_RIGHT (uic)) ||
3696 getSize (operandType (IC_RESULT (uic))) > 1))
3699 /* make sure that the result of this icode is not on the
3700 stack, since acc is used to compute stack offset */
3701 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3702 OP_SYMBOL (IC_RESULT (uic))->onStack)
3705 /* if either one of them in far space then we cannot */
3706 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3707 isOperandInFarSpace (IC_LEFT (uic))) ||
3708 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3709 isOperandInFarSpace (IC_RIGHT (uic))))
3712 /* if the usage has only one operand then we can */
3713 if (IC_LEFT (uic) == NULL ||
3714 IC_RIGHT (uic) == NULL)
3717 /* make sure this is on the left side if not
3718 a '+' since '+' is commutative */
3719 if (ic->op != '+' &&
3720 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3724 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3725 /* if one of them is a literal then we can */
3726 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3727 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3728 (getSize (operandType (IC_RESULT (uic))) <= 1))
3730 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3735 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3736 /* if the other one is not on stack then we can */
3737 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3738 (IS_ITEMP (IC_RIGHT (uic)) ||
3739 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3740 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3743 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3744 (IS_ITEMP (IC_LEFT (uic)) ||
3745 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3746 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3752 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3753 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3760 /*-----------------------------------------------------------------*/
3761 /* packForPush - hueristics to reduce iCode for pushing */
3762 /*-----------------------------------------------------------------*/
3764 packForReceive (iCode * ic, eBBlock * ebp)
3768 debugLog ("%s\n", __FUNCTION__);
3769 debugAopGet (" result:", IC_RESULT (ic));
3770 debugAopGet (" left:", IC_LEFT (ic));
3771 debugAopGet (" right:", IC_RIGHT (ic));
3776 for (dic = ic->next; dic; dic = dic->next)
3778 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3779 debugLog (" used on left\n");
3780 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3781 debugLog (" used on right\n");
3782 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3783 debugLog (" used on result\n");
3785 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3786 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3790 debugLog (" hey we can remove this unnecessary assign\n");
3792 /*-----------------------------------------------------------------*/
3793 /* packForPush - hueristics to reduce iCode for pushing */
3794 /*-----------------------------------------------------------------*/
3796 packForPush (iCode * ic, eBBlock * ebp)
3800 debugLog ("%s\n", __FUNCTION__);
3801 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3808 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3809 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3810 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3811 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3815 /* must have only definition & one usage */
3816 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3817 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3820 /* find the definition */
3821 if (!(dic = hTabItemWithKey (iCodehTab,
3822 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3825 /* if definition is not assignment,
3826 * or is not pointer (because pointer might have changed) */
3827 if (dic->op != '=' || POINTER_SET (dic))
3830 /* we must ensure that we can use the delete the assignment,
3831 * because the source might have been modified in between.
3832 * Until I know how to fix this, I'll use the adhoc fix
3833 * to check the liveranges */
3834 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3836 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3840 /* we now we know that it has one & only one def & use
3841 and the that the definition is an assignment */
3842 IC_LEFT (ic) = IC_RIGHT (dic);
3844 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3846 remiCodeFromeBBlock (ebp, dic);
3847 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3848 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3851 static void printSymType(char * str, sym_link *sl)
3853 if(!pic16_ralloc_debug)return;
3855 debugLog (" %s Symbol type: ",str);
3856 printTypeChain( sl, debugF);
3860 /*-----------------------------------------------------------------*/
3861 /* some debug code to print the symbol S_TYPE. Note that
3862 * the function checkSClass in src/SDCCsymt.c dinks with
3863 * the S_TYPE in ways the PIC port doesn't fully like...*/
3864 /*-----------------------------------------------------------------*/
3865 static void isData(sym_link *sl)
3869 if(!pic16_ralloc_debug)return;
3876 for ( ; sl; sl=sl->next) {
3878 switch (SPEC_SCLS(sl)) {
3879 case S_DATA: fprintf (of, "data "); break;
3880 case S_XDATA: fprintf (of, "xdata "); break;
3881 case S_SFR: fprintf (of, "sfr "); break;
3882 case S_SBIT: fprintf (of, "sbit "); break;
3883 case S_CODE: fprintf (of, "code "); break;
3884 case S_IDATA: fprintf (of, "idata "); break;
3885 case S_PDATA: fprintf (of, "pdata "); break;
3886 case S_LITERAL: fprintf (of, "literal "); break;
3887 case S_STACK: fprintf (of, "stack "); break;
3888 case S_XSTACK: fprintf (of, "xstack "); break;
3889 case S_BIT: fprintf (of, "bit "); break;
3890 case S_EEPROM: fprintf (of, "eeprom "); break;
3898 /*--------------------------------------------------------------------*/
3899 /* pic16_packRegisters - does some transformations to reduce */
3900 /* register pressure */
3902 /*--------------------------------------------------------------------*/
3904 pic16_packRegisters (eBBlock * ebp)
3909 debugLog ("%s\n", __FUNCTION__);
3915 /* look for assignments of the form */
3916 /* iTempNN = TRueSym (someoperation) SomeOperand */
3918 /* TrueSym := iTempNN:1 */
3919 for (ic = ebp->sch; ic; ic = ic->next)
3921 // debugLog("%d\n", __LINE__);
3922 /* find assignment of the form TrueSym := iTempNN:1 */
3923 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3924 change += packRegsForAssign (ic, ebp);
3928 if (POINTER_SET (ic))
3929 debugLog ("pointer is set\n");
3930 debugAopGet (" result:", IC_RESULT (ic));
3931 debugAopGet (" left:", IC_LEFT (ic));
3932 debugAopGet (" right:", IC_RIGHT (ic));
3941 for (ic = ebp->sch; ic; ic = ic->next) {
3943 if(IS_SYMOP ( IC_LEFT(ic))) {
3944 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3946 debugAopGet ("x left:", IC_LEFT (ic));
3948 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3950 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3952 debugLog (" is a pointer\n");
3954 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3955 debugLog (" is a ptr\n");
3957 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3958 debugLog (" is volatile\n");
3962 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3963 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3964 pic16_allocDirReg(IC_LEFT (ic));
3967 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3970 if(IS_SYMOP ( IC_RIGHT(ic))) {
3971 debugAopGet (" right:", IC_RIGHT (ic));
3972 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3975 if(IS_SYMOP ( IC_RESULT(ic))) {
3976 debugAopGet (" result:", IC_RESULT (ic));
3977 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3980 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3981 debugAopGet (" right:", IC_RIGHT (ic));
3982 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3983 // pic16_allocDirReg(IC_RIGHT(ic));
3986 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3987 debugAopGet (" result:", IC_RESULT (ic));
3988 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3989 // pic16_allocDirReg(IC_RESULT(ic));
3993 if (POINTER_SET (ic))
3994 debugLog (" %d - Pointer set\n", __LINE__);
3996 /* Look for two subsequent iCodes with */
3998 /* _c = iTemp & op; */
3999 /* and replace them by */
4002 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
4004 && ic->prev->op == '='
4005 && IS_ITEMP (IC_LEFT (ic))
4006 && IC_LEFT (ic) == IC_RESULT (ic->prev)
4007 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
4009 iCode* ic_prev = ic->prev;
4010 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
4012 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
4013 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
4014 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
4015 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
4016 prev_result_sym->liveTo == ic->seq)
4018 prev_result_sym->liveTo = ic_prev->seq;
4021 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
4023 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
4025 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
4026 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
4027 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
4028 remiCodeFromeBBlock (ebp, ic_prev);
4029 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
4033 /* if this is an itemp & result of a address of a true sym
4034 then mark this as rematerialisable */
4035 if (ic->op == ADDRESS_OF &&
4036 IS_ITEMP (IC_RESULT (ic)) &&
4037 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4038 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4039 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4042 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
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;
4050 /* if straight assignment then carry remat flag if
4051 this is the only definition */
4052 if (ic->op == '=' &&
4053 !POINTER_SET (ic) &&
4054 IS_SYMOP (IC_RIGHT (ic)) &&
4055 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4056 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4058 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4060 OP_SYMBOL (IC_RESULT (ic))->remat =
4061 OP_SYMBOL (IC_RIGHT (ic))->remat;
4062 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4063 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4066 /* if this is a +/- operation with a rematerizable
4067 then mark this as rematerializable as well */
4068 if ((ic->op == '+' || ic->op == '-') &&
4069 (IS_SYMOP (IC_LEFT (ic)) &&
4070 IS_ITEMP (IC_RESULT (ic)) &&
4071 OP_SYMBOL (IC_LEFT (ic))->remat &&
4072 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4073 IS_OP_LITERAL (IC_RIGHT (ic))))
4075 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4077 operandLitValue (IC_RIGHT (ic));
4078 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4079 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4080 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4085 /* try to optimize FSR0 usage when reading data memory pointers */
4087 if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4088 static int fsr0usage=0;
4091 if(POINTER_GET(ic) /* this is a memory read */
4092 && ic->loop /* this is in a loop */
4094 fprintf(stderr, "might optimize FSR0 usage\n");
4099 /* mark the pointer usages */
4100 if (POINTER_SET (ic))
4102 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4103 debugLog (" marking as a pointer (set) =>");
4104 debugAopGet (" result:", IC_RESULT (ic));
4108 if (POINTER_GET (ic))
4110 if(IS_SYMOP(IC_LEFT(ic))) {
4111 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4112 debugLog (" marking as a pointer (get) =>");
4113 debugAopGet (" left:", IC_LEFT (ic));
4116 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4117 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4118 iCode *dic = ic->prev;
4120 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4122 if(dic && dic->op == '='
4123 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4125 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4128 /* replace prev->left with ic->left */
4129 IC_LEFT(ic) = IC_RIGHT(dic);
4130 IC_RIGHT(ic->prev) = NULL;
4132 /* remove ic->prev iCode (assignment) */
4133 remiCodeFromeBBlock (ebp, dic);
4134 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4137 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4143 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4147 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4148 /* if we are using a symbol on the stack
4149 then we should say pic16_ptrRegReq */
4150 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4151 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4152 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4153 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4154 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4155 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4159 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4160 if (IS_SYMOP (IC_LEFT (ic)))
4161 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4162 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4163 if (IS_SYMOP (IC_RIGHT (ic)))
4164 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4165 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4166 if (IS_SYMOP (IC_RESULT (ic)))
4167 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4168 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4171 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4175 /* if the condition of an if instruction
4176 is defined in the previous instruction then
4177 mark the itemp as a conditional */
4178 if ((IS_CONDITIONAL (ic) ||
4179 ((ic->op == BITWISEAND ||
4182 isBitwiseOptimizable (ic))) &&
4183 ic->next && ic->next->op == IFX &&
4184 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4185 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4188 debugLog (" %d\n", __LINE__);
4189 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4193 debugLog(" %d\n", __LINE__);
4195 #ifndef NO_packRegsForSupport
4196 /* reduce for support function calls */
4197 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4198 packRegsForSupport (ic, ebp);
4201 /* if a parameter is passed, it's in W, so we may not
4202 need to place a copy in a register */
4203 if (ic->op == RECEIVE)
4204 packForReceive (ic, ebp);
4206 #ifndef NO_packRegsForOneuse
4207 /* some cases the redundant moves can
4208 can be eliminated for return statements */
4209 if ((ic->op == RETURN || ic->op == SEND) &&
4210 !isOperandInFarSpace (IC_LEFT (ic)) &&
4212 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4215 #ifndef NO_packRegsForOneuse
4216 /* if pointer set & left has a size more than
4217 one and right is not in far space */
4218 if (POINTER_SET (ic) &&
4219 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4220 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4221 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4222 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4224 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4227 #ifndef NO_packRegsForOneuse
4228 /* if pointer get */
4229 if (POINTER_GET (ic) &&
4230 !isOperandInFarSpace (IC_RESULT (ic)) &&
4231 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4232 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4233 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4235 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4236 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4239 #ifndef NO_cast_peep
4240 /* if this is cast for intergral promotion then
4241 check if only use of the definition of the
4242 operand being casted/ if yes then replace
4243 the result of that arithmetic operation with
4244 this result and get rid of the cast */
4245 if (ic->op == CAST) {
4247 sym_link *fromType = operandType (IC_RIGHT (ic));
4248 sym_link *toType = operandType (IC_LEFT (ic));
4250 debugLog (" %d - casting\n", __LINE__);
4252 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4253 getSize (fromType) != getSize (toType)) {
4256 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4259 if (IS_ARITHMETIC_OP (dic)) {
4260 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4262 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4263 IC_RESULT (dic) = IC_RESULT (ic);
4264 remiCodeFromeBBlock (ebp, ic);
4265 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4266 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4267 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4271 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4275 /* if the type from and type to are the same
4276 then if this is the only use then packit */
4277 if (compareType (operandType (IC_RIGHT (ic)),
4278 operandType (IC_LEFT (ic))) == 1) {
4280 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4283 debugLog(" %d\n", __LINE__);
4285 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4286 IC_RESULT (dic) = IC_RESULT (ic);
4287 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4288 remiCodeFromeBBlock (ebp, ic);
4289 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4290 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4299 /* there are some problems with packing variables
4300 * it seems that the live range estimator doesn't
4301 * estimate correctly the liveranges of some symbols */
4304 iTempNN := (some variable in farspace) V1
4309 if (ic->op == IPUSH)
4311 packForPush (ic, ebp);
4315 #ifndef NO_packRegsForAccUse
4316 /* pack registers for accumulator use, when the
4317 result of an arithmetic or bit wise operation
4318 has only one use, that use is immediately following
4319 the defintion and the using iCode has only one
4320 operand or has two operands but one is literal &
4321 the result of that operation is not on stack then
4322 we can leave the result of this operation in acc:b
4324 if ((IS_ARITHMETIC_OP (ic)
4326 || IS_BITWISE_OP (ic)
4328 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4331 IS_ITEMP (IC_RESULT (ic)) &&
4332 getSize (operandType (IC_RESULT (ic))) <= 1)
4334 packRegsForAccUse (ic);
4341 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4345 if (!pic16_ralloc_debug || !debugF)
4348 for (i = 0; i < count; i++)
4350 fprintf (debugF, "\n----------------------------------------------------------------\n");
4351 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4352 ebbs[i]->entryLabel->name,
4355 ebbs[i]->isLastInLoop);
4356 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4361 fprintf (debugF, "visited %d : hasFcall = %d\n",
4365 fprintf (debugF, "\ndefines bitVector :");
4366 bitVectDebugOn (ebbs[i]->defSet, debugF);
4367 fprintf (debugF, "\nlocal defines bitVector :");
4368 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4369 fprintf (debugF, "\npointers Set bitvector :");
4370 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4371 fprintf (debugF, "\nin pointers Set bitvector :");
4372 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4373 fprintf (debugF, "\ninDefs Set bitvector :");
4374 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4375 fprintf (debugF, "\noutDefs Set bitvector :");
4376 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4377 fprintf (debugF, "\nusesDefs Set bitvector :");
4378 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4379 fprintf (debugF, "\n----------------------------------------------------------------\n");
4380 printiCChain (ebbs[i]->sch, debugF);
4384 void dbg_dumpregusage(void);
4386 /*-----------------------------------------------------------------*/
4387 /* pic16_assignRegisters - assigns registers to each live range as need */
4388 /*-----------------------------------------------------------------*/
4390 pic16_assignRegisters (ebbIndex * ebbi)
4392 eBBlock ** ebbs = ebbi->bbOrder;
4393 int count = ebbi->count;
4397 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4398 debugLog ("\nebbs before optimizing:\n");
4399 dumpEbbsToDebug (ebbs, count);
4401 _inRegAllocator = 1;
4403 pic16_freeAllRegs();
4406 /* clear whats left over from peephole parser */
4407 pic16_dynAllocRegs= newSet(); //NULL;
4408 // pic16_dynStackRegs= newSet(); //NULL;
4409 // pic16_dynProcessorRegs=newSet(); //NULL;
4410 // pic16_dynDirectRegs=newSet(); //NULL;
4411 // pic16_dynDirectBitRegs=newSet(); //NULL;
4412 // pic16_dynInternalRegs=newSet(); //NULL;
4413 // pic16_dynAccessRegs=newSet(); //NULL;
4415 // dynDirectRegNames=NULL;
4416 dynAllocRegNames=NULL;
4417 // dynProcRegNames=NULL;
4418 // dynAccessRegNames=NULL;
4421 setToNull ((void *) &_G.funcrUsed);
4422 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4425 /* change assignments this will remove some
4426 live ranges reducing some register pressure */
4427 for (i = 0; i < count; i++)
4428 pic16_packRegisters (ebbs[i]);
4435 debugLog("dir registers allocated so far:\n");
4436 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4440 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4441 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4442 reg = hTabNextItem(dynDirectRegNames, &hkey);
4448 /* liveranges probably changed by register packing
4449 so we compute them again */
4450 recomputeLiveRanges (ebbs, count);
4452 if (options.dump_pack)
4453 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4455 /* first determine for each live range the number of
4456 registers & the type of registers required for each */
4459 /* start counting function temporary registers from zero */
4462 /* and serially allocate registers */
4463 serialRegAssign (ebbs, count);
4466 debugLog ("ebbs after serialRegAssign:\n");
4467 dumpEbbsToDebug (ebbs, count);
4470 //pic16_freeAllRegs();
4472 /* if stack was extended then tell the user */
4475 /* werror(W_TOOMANY_SPILS,"stack", */
4476 /* _G.stackExtend,currFunc->name,""); */
4482 /* werror(W_TOOMANY_SPILS,"data space", */
4483 /* _G.dataExtend,currFunc->name,""); */
4487 /* after that create the register mask
4488 for each of the instruction */
4489 createRegMask (ebbs, count);
4491 /* redo that offsets for stacked automatic variables */
4492 redoStackOffsets ();
4494 if (options.dump_rassgn)
4495 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4497 // dumpLR(ebbs, count);
4499 /* now get back the chain */
4500 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4502 debugLog ("ebbs after optimizing:\n");
4503 dumpEbbsToDebug (ebbs, count);
4506 _inRegAllocator = 0;
4510 /* free up any _G.stackSpil locations allocated */
4511 applyToSet (_G.stackSpil, deallocStackSpil);
4513 setToNull ((void *) &_G.stackSpil);
4514 setToNull ((void *) &_G.spiltSet);
4515 /* mark all registers as free */
4516 pic16_freeAllRegs ();
4519 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");