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);
156 //fprintf (stderr, "%s", buffer);
158 while (isspace((unsigned char)*bufferP)) bufferP++;
160 if (bufferP && *bufferP)
161 lineCurr = (lineCurr ?
162 connectLine(lineCurr,newLineNode(lb)) :
163 (lineHead = newLineNode(lb)));
164 lineCurr->isInline = _G.inLine;
165 lineCurr->isDebug = _G.debugLine;
174 if(!pic16_ralloc_debug)return;
177 fputc ('\n', debugF);
179 /*-----------------------------------------------------------------*/
180 /* debugLogClose - closes the debug log file (if opened) */
181 /*-----------------------------------------------------------------*/
191 #define AOP(op) op->aop
194 debugAopGet (char *str, operand * op)
196 if(!pic16_ralloc_debug)return NULL;
201 printOperand (op, debugF);
208 pic16_decodeOp (unsigned int op)
210 if (op < 128 && op > ' ') {
211 buffer[0] = (op & 0xff);
217 case IDENTIFIER: return "IDENTIFIER";
218 case TYPE_NAME: return "TYPE_NAME";
219 case CONSTANT: return "CONSTANT";
220 case STRING_LITERAL: return "STRING_LITERAL";
221 case SIZEOF: return "SIZEOF";
222 case PTR_OP: return "PTR_OP";
223 case INC_OP: return "INC_OP";
224 case DEC_OP: return "DEC_OP";
225 case LEFT_OP: return "LEFT_OP";
226 case RIGHT_OP: return "RIGHT_OP";
227 case LE_OP: return "LE_OP";
228 case GE_OP: return "GE_OP";
229 case EQ_OP: return "EQ_OP";
230 case NE_OP: return "NE_OP";
231 case AND_OP: return "AND_OP";
232 case OR_OP: return "OR_OP";
233 case MUL_ASSIGN: return "MUL_ASSIGN";
234 case DIV_ASSIGN: return "DIV_ASSIGN";
235 case MOD_ASSIGN: return "MOD_ASSIGN";
236 case ADD_ASSIGN: return "ADD_ASSIGN";
237 case SUB_ASSIGN: return "SUB_ASSIGN";
238 case LEFT_ASSIGN: return "LEFT_ASSIGN";
239 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
240 case AND_ASSIGN: return "AND_ASSIGN";
241 case XOR_ASSIGN: return "XOR_ASSIGN";
242 case OR_ASSIGN: return "OR_ASSIGN";
243 case TYPEDEF: return "TYPEDEF";
244 case EXTERN: return "EXTERN";
245 case STATIC: return "STATIC";
246 case AUTO: return "AUTO";
247 case REGISTER: return "REGISTER";
248 case CODE: return "CODE";
249 case EEPROM: return "EEPROM";
250 case INTERRUPT: return "INTERRUPT";
251 case SFR: return "SFR";
252 case AT: return "AT";
253 case SBIT: return "SBIT";
254 case REENTRANT: return "REENTRANT";
255 case USING: return "USING";
256 case XDATA: return "XDATA";
257 case DATA: return "DATA";
258 case IDATA: return "IDATA";
259 case PDATA: return "PDATA";
260 case VAR_ARGS: return "VAR_ARGS";
261 case CRITICAL: return "CRITICAL";
262 case NONBANKED: return "NONBANKED";
263 case BANKED: return "BANKED";
264 case CHAR: return "CHAR";
265 case SHORT: return "SHORT";
266 case INT: return "INT";
267 case LONG: return "LONG";
268 case SIGNED: return "SIGNED";
269 case UNSIGNED: return "UNSIGNED";
270 case FLOAT: return "FLOAT";
271 case DOUBLE: return "DOUBLE";
272 case CONST: return "CONST";
273 case VOLATILE: return "VOLATILE";
274 case VOID: return "VOID";
275 case BIT: return "BIT";
276 case STRUCT: return "STRUCT";
277 case UNION: return "UNION";
278 case ENUM: return "ENUM";
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(int type, short pc_type, int rIdx, char *name, unsigned 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(dReg->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);
586 addSet(&pic16_dynAllocRegs, reg);
587 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
588 // fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs);
592 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
595 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
596 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
600 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
601 reg->isLocal = 1; /* this is a local frame register */
606 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
607 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
610 return (reg); // addSet(&pic16_dynAllocRegs,reg);
615 /*-----------------------------------------------------------------*/
616 /* pic16_dirregWithName - search for register by name */
617 /*-----------------------------------------------------------------*/
619 pic16_dirregWithName (char *name)
627 /* hash the name to get a key */
629 hkey = regname2key(name);
631 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
633 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
637 if(STRCASECMP(reg->name, name) == 0) {
638 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
642 reg = hTabNextItemWK (dynDirectRegNames);
646 return NULL; // name wasn't found in the hash table
649 /*-----------------------------------------------------------------*/
650 /* pic16_allocregWithName - search for register by name */
651 /*-----------------------------------------------------------------*/
653 pic16_allocregWithName (char *name)
661 /* hash the name to get a key */
663 hkey = regname2key(name);
665 //fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
667 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
671 if(STRCASECMP(reg->name, name) == 0) {
675 reg = hTabNextItemWK (dynAllocRegNames);
679 return NULL; // name wasn't found in the hash table
684 /*-----------------------------------------------------------------*/
685 /* pic16_procregWithName - search for register by name */
686 /*-----------------------------------------------------------------*/
688 pic16_procregWithName (char *name)
696 /* hash the name to get a key */
698 hkey = regname2key(name);
700 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
702 reg = hTabFirstItemWK(dynProcRegNames, hkey);
706 if(STRCASECMP(reg->name, name) == 0) {
710 reg = hTabNextItemWK (dynProcRegNames);
714 return NULL; // name wasn't found in the hash table
718 /*-----------------------------------------------------------------*/
719 /* pic16_accessregWithName - search for register by name */
720 /*-----------------------------------------------------------------*/
722 pic16_accessregWithName (char *name)
730 /* hash the name to get a key */
732 hkey = regname2key(name);
734 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
736 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
740 if(STRCASECMP(reg->name, name) == 0) {
744 reg = hTabNextItemWK (dynAccessRegNames);
748 return NULL; // name wasn't found in the hash table
752 regs *pic16_regWithName(char *name)
756 reg = pic16_dirregWithName( name );
759 reg = pic16_procregWithName( name );
762 reg = pic16_allocregWithName( name );
765 reg = pic16_accessregWithName( name );
772 /*-----------------------------------------------------------------*/
773 /* pic16_allocDirReg - allocates register of given type */
774 /*-----------------------------------------------------------------*/
776 pic16_allocDirReg (operand *op )
782 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
783 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
787 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
790 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
792 if(pic16_debug_verbose)
794 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
795 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
801 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
802 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
805 if(pic16_debug_verbose) {
806 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
807 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
808 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
809 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
810 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
811 IN_STACK( OP_SYM_ETYPE(op)),
812 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
813 IS_REGPARM(OP_SYM_ETYPE(op)),
816 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
817 OP_SYMBOL(op)->name);
825 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
826 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
830 if(IS_ITEMP(op))return NULL;
832 // if(IS_STATIC(OP_SYM_ETYPE(op)))return NULL;
834 if(IN_STACK(OP_SYM_ETYPE(op)))return NULL;
836 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
837 // fprintf(stderr, "%s symbol name %s\tSTATIC:%d\n", __FUNCTION__,name, IS_STATIC(OP_SYM_ETYPE(op)));
840 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
841 debugLog(" %d const char\n",__LINE__);
842 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
843 // fprintf(stderr, " %d const char\n",__LINE__);
844 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
848 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
849 if (IS_CODE ( OP_SYM_ETYPE(op)) )
850 debugLog(" %d code space\n",__LINE__);
852 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
853 debugLog(" %d integral\n",__LINE__);
855 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
856 debugLog(" %d literal\n",__LINE__);
858 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
859 debugLog(" %d specifier\n",__LINE__);
861 debugAopGet(NULL, op);
865 reg = pic16_dirregWithName(name);
869 int regtype = REG_GPR;
871 /* if this is at an absolute address, then get the address. */
872 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
873 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
874 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
877 /* Register wasn't found in hash, so let's create
878 * a new one and put it in the hash table AND in the
879 * dynDirectRegNames set */
880 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
881 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
887 if(OP_SYMBOL(op)->onStack) {
888 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
889 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
893 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
894 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
897 if(pic16_debug_verbose)
899 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
900 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
901 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
902 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
903 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
904 IN_STACK( OP_SYM_ETYPE(op)),
905 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
907 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
908 OP_SYMBOL(op)->name);
913 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
914 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
916 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
917 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
921 checkAddReg(&pic16_dynAccessRegs, reg);
922 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
928 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
929 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
930 // reg->type = REG_SFR;
933 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
934 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
935 addSet(&pic16_dynDirectBitRegs, reg);
938 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
939 // addSet(&pic16_dynDirectRegs, reg);
942 if(!(IS_STATIC(OP_SYM_ETYPE(op))
943 && OP_SYMBOL(op)->ival
946 checkAddReg(&pic16_dynDirectRegs, reg);
950 // debugLog (" -- %s is declared at address 0x30000x\n",name);
951 return (reg); /* This was NULL before, but since we found it
952 * why not just return it?! */
955 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
957 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
959 /* work around for user defined registers in access bank */
960 if((reg->address>= 0x00 && reg->address < pic16->acsSplitOfs)
961 || (reg->address >= (0xf00 + pic16->acsSplitOfs) && reg->address <= 0xfff))
964 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
970 /*-----------------------------------------------------------------*/
971 /* pic16_allocRegByName - allocates register of given type */
972 /*-----------------------------------------------------------------*/
974 pic16_allocRegByName (char *name, int size, operand *op)
980 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
984 /* First, search the hash table to see if there is a register with this name */
985 reg = pic16_dirregWithName(name);
989 /* Register wasn't found in hash, so let's create
990 * a new one and put it in the hash table AND in the
991 * dynDirectRegNames set */
993 //fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
995 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
997 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
998 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
1000 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
1001 addSet(&pic16_dynDirectRegs, reg);
1007 /*-----------------------------------------------------------------*/
1008 /* RegWithIdx - returns pointer to register with index number */
1009 /*-----------------------------------------------------------------*/
1010 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
1015 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
1016 // fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type));
1021 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
1023 debugLog ("Found a Dynamic Register!\n");
1026 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
1027 debugLog ("Found a Direct Register!\n");
1031 if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) {
1032 debugLog ("Found an Internal Register!\n");
1038 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
1039 debugLog ("Found a Stack Register!\n");
1044 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
1045 debugLog ("Found a Processor Register!\n");
1059 /*-----------------------------------------------------------------*/
1060 /* pic16_regWithIdx - returns pointer to register with index number*/
1061 /*-----------------------------------------------------------------*/
1063 pic16_regWithIdx (int idx)
1067 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1070 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1074 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1081 /*-----------------------------------------------------------------*/
1082 /* pic16_regWithIdx - returns pointer to register with index number */
1083 /*-----------------------------------------------------------------*/
1085 pic16_allocWithIdx (int idx)
1090 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1091 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1093 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1095 debugLog ("Found a Dynamic Register!\n");
1096 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1097 debugLog ("Found a Stack Register!\n");
1098 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1099 debugLog ("Found a Processor Register!\n");
1100 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1101 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1102 debugLog ("Found an Internal Register!\n");
1105 debugLog ("Dynamic Register not found\n");
1108 dReg = newReg(REG_GPR, PO_GPR_TEMP, idx, NULL, 1, 0, NULL);
1109 addSet(&pic16_dynAllocRegs, dReg);
1110 hTabAddItem(&dynAllocRegNames, regname2key(dReg->name), dReg);
1115 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1116 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1117 "allocWithIdx not found");
1127 /*-----------------------------------------------------------------*/
1128 /*-----------------------------------------------------------------*/
1130 pic16_findFreeReg(short type)
1137 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1139 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1140 return allocReg( REG_GPR );
1144 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1158 pic16_findFreeRegNext(short type, regs *creg)
1165 if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL)
1167 // return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)));
1168 return (allocReg( REG_GPR ) );
1172 if((dReg = regFindFreeNext(pic16_dynStackRegs, creg)) != NULL)
1184 /*-----------------------------------------------------------------*/
1185 /* freeReg - frees a register */
1186 /*-----------------------------------------------------------------*/
1188 freeReg (regs * reg)
1190 debugLog ("%s\n", __FUNCTION__);
1191 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1196 /*-----------------------------------------------------------------*/
1197 /* nFreeRegs - returns number of free registers */
1198 /*-----------------------------------------------------------------*/
1200 nFreeRegs (int type)
1206 /* although I fixed the register allocation/freeing scheme
1207 * the for loop below doesn't give valid results. I do not
1208 * know why yet. -- VR 10-Jan-2003 */
1213 /* dynamically allocate as many as we need and worry about
1214 * fitting them into a PIC later */
1216 debugLog ("%s\n", __FUNCTION__);
1218 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1219 if((reg->type == type) && reg->isFree)nfr++;
1221 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1225 /*-----------------------------------------------------------------*/
1226 /* nfreeRegsType - free registers with type */
1227 /*-----------------------------------------------------------------*/
1229 nfreeRegsType (int type)
1232 debugLog ("%s\n", __FUNCTION__);
1233 if (type == REG_PTR)
1235 if ((nfr = nFreeRegs (type)) == 0)
1236 return nFreeRegs (REG_GPR);
1239 return nFreeRegs (type);
1242 static void writeSetUsedRegs(FILE *of, set *dRegs)
1247 for (dReg = setFirstItem(dRegs) ; dReg ;
1248 dReg = setNextItem(dRegs)) {
1251 fprintf (of, "\t%s\n",dReg->name);
1257 extern void pic16_groupRegistersInSection(set *regset);
1259 extern void pic16_dump_equates(FILE *of, set *equs);
1260 extern void pic16_dump_access(FILE *of, set *section);
1261 //extern void pic16_dump_map(void);
1262 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1263 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1264 extern void pic16_dump_int_registers(FILE *of, set *section);
1265 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1267 extern void pic16_dump_gsection(FILE *of, set *sections);
1269 static void packBits(set *bregs)
1273 regs *bitfield=NULL;
1274 regs *relocbitfield=NULL;
1280 for (regset = bregs ; regset ;
1281 regset = regset->next) {
1283 breg = regset->item;
1284 breg->isBitField = 1;
1285 //fprintf(stderr,"bit reg: %s\n",breg->name);
1288 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1290 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1291 breg->rIdx = breg->address & 7;
1292 breg->address >>= 3;
1295 sprintf (buffer, "fbitfield%02x", breg->address);
1296 //fprintf(stderr,"new bit field\n");
1297 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1298 bitfield->isBitField = 1;
1299 bitfield->isFixed = 1;
1300 bitfield->address = breg->address;
1301 addSet(&pic16_dynDirectRegs,bitfield);
1302 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1304 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1307 breg->reg_alias = bitfield;
1311 if(!relocbitfield || bit_no >7) {
1314 sprintf (buffer, "bitfield%d", byte_no);
1315 //fprintf(stderr,"new relocatable bit field\n");
1316 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1317 relocbitfield->isBitField = 1;
1318 addSet(&pic16_dynDirectRegs,relocbitfield);
1319 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1323 breg->reg_alias = relocbitfield;
1324 breg->address = rDirectIdx; /* byte_no; */
1325 breg->rIdx = bit_no++;
1331 void pic16_writeUsedRegs(FILE *of)
1333 packBits(pic16_dynDirectBitRegs);
1335 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1336 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1337 pic16_groupRegistersInSection(pic16_dynStackRegs);
1338 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1339 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1340 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1341 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1344 pic16_dump_equates(of, pic16_equ_data);
1346 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1347 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1349 /* dump access bank symbols */
1350 pic16_dump_access(of, pic16_acs_udata);
1352 /* dump initialised data */
1353 pic16_dump_isection(of, rel_idataSymSet, 0);
1354 pic16_dump_isection(of, fix_idataSymSet, 1);
1357 /* dump internal registers */
1358 pic16_dump_int_registers(of, pic16_int_regs);
1361 /* dump generic section variables */
1362 pic16_dump_gsection(of, sectNames);
1364 /* dump other variables */
1365 pic16_dump_usection(of, pic16_rel_udata, 0);
1366 pic16_dump_usection(of, pic16_fix_udata, 1);
1370 /*-----------------------------------------------------------------*/
1371 /* computeSpillable - given a point find the spillable live ranges */
1372 /*-----------------------------------------------------------------*/
1374 computeSpillable (iCode * ic)
1378 debugLog ("%s\n", __FUNCTION__);
1379 /* spillable live ranges are those that are live at this
1380 point . the following categories need to be subtracted
1382 a) - those that are already spilt
1383 b) - if being used by this one
1384 c) - defined by this one */
1386 spillable = bitVectCopy (ic->rlive);
1388 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1390 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1391 bitVectUnSetBit (spillable, ic->defKey);
1392 spillable = bitVectIntersect (spillable, _G.regAssigned);
1397 /*-----------------------------------------------------------------*/
1398 /* noSpilLoc - return true if a variable has no spil location */
1399 /*-----------------------------------------------------------------*/
1401 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1403 debugLog ("%s\n", __FUNCTION__);
1404 return (sym->usl.spillLoc ? 0 : 1);
1407 /*-----------------------------------------------------------------*/
1408 /* hasSpilLoc - will return 1 if the symbol has spil location */
1409 /*-----------------------------------------------------------------*/
1411 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1413 debugLog ("%s\n", __FUNCTION__);
1414 return (sym->usl.spillLoc ? 1 : 0);
1417 /*-----------------------------------------------------------------*/
1418 /* directSpilLoc - will return 1 if the splilocation is in direct */
1419 /*-----------------------------------------------------------------*/
1421 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1423 debugLog ("%s\n", __FUNCTION__);
1424 if (sym->usl.spillLoc &&
1425 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1431 /*-----------------------------------------------------------------*/
1432 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1433 /* but is not used as a pointer */
1434 /*-----------------------------------------------------------------*/
1436 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1438 debugLog ("%s\n", __FUNCTION__);
1439 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1442 /*-----------------------------------------------------------------*/
1443 /* rematable - will return 1 if the remat flag is set */
1444 /*-----------------------------------------------------------------*/
1446 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1448 debugLog ("%s\n", __FUNCTION__);
1452 /*-----------------------------------------------------------------*/
1453 /* notUsedInRemaining - not used or defined in remain of the block */
1454 /*-----------------------------------------------------------------*/
1456 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1458 debugLog ("%s\n", __FUNCTION__);
1459 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1460 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1463 /*-----------------------------------------------------------------*/
1464 /* allLRs - return true for all */
1465 /*-----------------------------------------------------------------*/
1467 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1469 debugLog ("%s\n", __FUNCTION__);
1473 /*-----------------------------------------------------------------*/
1474 /* liveRangesWith - applies function to a given set of live range */
1475 /*-----------------------------------------------------------------*/
1477 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1478 eBBlock * ebp, iCode * ic)
1483 debugLog ("%s\n", __FUNCTION__);
1484 if (!lrs || !lrs->size)
1487 for (i = 1; i < lrs->size; i++)
1490 if (!bitVectBitValue (lrs, i))
1493 /* if we don't find it in the live range
1494 hash table we are in serious trouble */
1495 if (!(sym = hTabItemWithKey (liveRanges, i)))
1497 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1498 "liveRangesWith could not find liveRange");
1502 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1503 addSetHead (&rset, sym);
1510 /*-----------------------------------------------------------------*/
1511 /* leastUsedLR - given a set determines which is the least used */
1512 /*-----------------------------------------------------------------*/
1514 leastUsedLR (set * sset)
1516 symbol *sym = NULL, *lsym = NULL;
1518 debugLog ("%s\n", __FUNCTION__);
1519 sym = lsym = setFirstItem (sset);
1524 for (; lsym; lsym = setNextItem (sset))
1527 /* if usage is the same then prefer
1528 the spill the smaller of the two */
1529 if (lsym->used == sym->used)
1530 if (getSize (lsym->type) < getSize (sym->type))
1534 if (lsym->used < sym->used)
1539 setToNull ((void *) &sset);
1544 /*-----------------------------------------------------------------*/
1545 /* noOverLap - will iterate through the list looking for over lap */
1546 /*-----------------------------------------------------------------*/
1548 noOverLap (set * itmpStack, symbol * fsym)
1551 debugLog ("%s\n", __FUNCTION__);
1554 for (sym = setFirstItem (itmpStack); sym;
1555 sym = setNextItem (itmpStack))
1557 if (sym->liveTo > fsym->liveFrom)
1565 /*-----------------------------------------------------------------*/
1566 /* isFree - will return 1 if the a free spil location is found */
1567 /*-----------------------------------------------------------------*/
1572 V_ARG (symbol **, sloc);
1573 V_ARG (symbol *, fsym);
1575 debugLog ("%s\n", __FUNCTION__);
1576 /* if already found */
1580 /* if it is free && and the itmp assigned to
1581 this does not have any overlapping live ranges
1582 with the one currently being assigned and
1583 the size can be accomodated */
1585 noOverLap (sym->usl.itmpStack, fsym) &&
1586 getSize (sym->type) >= getSize (fsym->type))
1595 /*-----------------------------------------------------------------*/
1596 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1597 /*-----------------------------------------------------------------*/
1599 spillLRWithPtrReg (symbol * forSym)
1605 debugLog ("%s\n", __FUNCTION__);
1606 if (!_G.regAssigned ||
1607 bitVectIsZero (_G.regAssigned))
1610 r0 = pic16_regWithIdx (R0_IDX);
1611 r1 = pic16_regWithIdx (R1_IDX);
1613 /* for all live ranges */
1614 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1615 lrsym = hTabNextItem (liveRanges, &k))
1619 /* if no registers assigned to it or
1621 /* if it does not overlap with this then
1622 not need to spill it */
1624 if (lrsym->isspilt || !lrsym->nRegs ||
1625 (lrsym->liveTo < forSym->liveFrom))
1628 /* go thru the registers : if it is either
1629 r0 or r1 then spil it */
1630 for (j = 0; j < lrsym->nRegs; j++)
1631 if (lrsym->regs[j] == r0 ||
1632 lrsym->regs[j] == r1)
1641 /*-----------------------------------------------------------------*/
1642 /* createStackSpil - create a location on the stack to spil */
1643 /*-----------------------------------------------------------------*/
1645 createStackSpil (symbol * sym)
1647 symbol *sloc = NULL;
1648 int useXstack, model, noOverlay;
1650 char slocBuffer[30];
1651 debugLog ("%s\n", __FUNCTION__);
1653 /* first go try and find a free one that is already
1654 existing on the stack */
1655 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1657 /* found a free one : just update & return */
1658 sym->usl.spillLoc = sloc;
1661 addSetHead (&sloc->usl.itmpStack, sym);
1665 /* could not then have to create one , this is the hard part
1666 we need to allocate this on the stack : this is really a
1667 hack!! but cannot think of anything better at this time */
1669 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1671 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1672 __FILE__, __LINE__);
1676 sloc = newiTemp (slocBuffer);
1678 /* set the type to the spilling symbol */
1679 sloc->type = copyLinkChain (sym->type);
1680 sloc->etype = getSpec (sloc->type);
1681 SPEC_SCLS (sloc->etype) = S_DATA;
1682 SPEC_EXTR (sloc->etype) = 0;
1683 SPEC_STAT (sloc->etype) = 0;
1685 /* we don't allow it to be allocated`
1686 onto the external stack since : so we
1687 temporarily turn it off ; we also
1688 turn off memory model to prevent
1689 the spil from going to the external storage
1690 and turn off overlaying
1693 useXstack = options.useXstack;
1694 model = options.model;
1695 noOverlay = options.noOverlay;
1696 options.noOverlay = 1;
1697 options.model = options.useXstack = 0;
1701 options.useXstack = useXstack;
1702 options.model = model;
1703 options.noOverlay = noOverlay;
1704 sloc->isref = 1; /* to prevent compiler warning */
1706 /* if it is on the stack then update the stack */
1707 if (IN_STACK (sloc->etype))
1709 currFunc->stack += getSize (sloc->type);
1710 _G.stackExtend += getSize (sloc->type);
1713 _G.dataExtend += getSize (sloc->type);
1715 /* add it to the _G.stackSpil set */
1716 addSetHead (&_G.stackSpil, sloc);
1717 sym->usl.spillLoc = sloc;
1720 /* add it to the set of itempStack set
1721 of the spill location */
1722 addSetHead (&sloc->usl.itmpStack, sym);
1726 /*-----------------------------------------------------------------*/
1727 /* isSpiltOnStack - returns true if the spil location is on stack */
1728 /*-----------------------------------------------------------------*/
1730 isSpiltOnStack (symbol * sym)
1734 debugLog ("%s\n", __FUNCTION__);
1741 /* if (sym->_G.stackSpil) */
1744 if (!sym->usl.spillLoc)
1747 etype = getSpec (sym->usl.spillLoc->type);
1748 if (IN_STACK (etype))
1754 /*-----------------------------------------------------------------*/
1755 /* spillThis - spils a specific operand */
1756 /*-----------------------------------------------------------------*/
1758 spillThis (symbol * sym)
1761 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1763 /* if this is rematerializable or has a spillLocation
1764 we are okay, else we need to create a spillLocation
1766 if (!(sym->remat || sym->usl.spillLoc))
1767 createStackSpil (sym);
1770 /* mark it has spilt & put it in the spilt set */
1772 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1774 bitVectUnSetBit (_G.regAssigned, sym->key);
1776 for (i = 0; i < sym->nRegs; i++)
1780 freeReg (sym->regs[i]);
1781 sym->regs[i] = NULL;
1784 /* if spilt on stack then free up r0 & r1
1785 if they could have been assigned to some
1787 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1790 spillLRWithPtrReg (sym);
1793 if (sym->usl.spillLoc && !sym->remat)
1794 sym->usl.spillLoc->allocreq = 1;
1798 /*-----------------------------------------------------------------*/
1799 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1800 /*-----------------------------------------------------------------*/
1802 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1804 bitVect *lrcs = NULL;
1808 debugLog ("%s\n", __FUNCTION__);
1809 /* get the spillable live ranges */
1810 lrcs = computeSpillable (ic);
1812 /* get all live ranges that are rematerizable */
1813 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1816 /* return the least used of these */
1817 return leastUsedLR (selectS);
1820 /* get live ranges with spillLocations in direct space */
1821 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1823 sym = leastUsedLR (selectS);
1824 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1825 sym->usl.spillLoc->rname :
1826 sym->usl.spillLoc->name));
1828 /* mark it as allocation required */
1829 sym->usl.spillLoc->allocreq = 1;
1833 /* if the symbol is local to the block then */
1834 if (forSym->liveTo < ebp->lSeq)
1837 /* check if there are any live ranges allocated
1838 to registers that are not used in this block */
1839 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1841 sym = leastUsedLR (selectS);
1842 /* if this is not rematerializable */
1851 /* check if there are any live ranges that not
1852 used in the remainder of the block */
1853 if (!_G.blockSpil &&
1854 !isiCodeInFunctionCall (ic) &&
1855 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1857 sym = leastUsedLR (selectS);
1860 sym->remainSpil = 1;
1867 /* find live ranges with spillocation && not used as pointers */
1868 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1871 sym = leastUsedLR (selectS);
1872 /* mark this as allocation required */
1873 sym->usl.spillLoc->allocreq = 1;
1877 /* find live ranges with spillocation */
1878 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1881 sym = leastUsedLR (selectS);
1882 sym->usl.spillLoc->allocreq = 1;
1886 /* couldn't find then we need to create a spil
1887 location on the stack , for which one? the least
1889 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1892 /* return a created spil location */
1893 sym = createStackSpil (leastUsedLR (selectS));
1894 sym->usl.spillLoc->allocreq = 1;
1898 /* this is an extreme situation we will spill
1899 this one : happens very rarely but it does happen */
1905 /*-----------------------------------------------------------------*/
1906 /* spilSomething - spil some variable & mark registers as free */
1907 /*-----------------------------------------------------------------*/
1909 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1914 debugLog ("%s\n", __FUNCTION__);
1915 /* get something we can spil */
1916 ssym = selectSpil (ic, ebp, forSym);
1918 /* mark it as spilt */
1920 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1922 /* mark it as not register assigned &
1923 take it away from the set */
1924 bitVectUnSetBit (_G.regAssigned, ssym->key);
1926 /* mark the registers as free */
1927 for (i = 0; i < ssym->nRegs; i++)
1929 freeReg (ssym->regs[i]);
1931 /* if spilt on stack then free up r0 & r1
1932 if they could have been assigned to as gprs */
1933 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1936 spillLRWithPtrReg (ssym);
1939 /* if this was a block level spil then insert push & pop
1940 at the start & end of block respectively */
1941 if (ssym->blockSpil)
1943 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1944 /* add push to the start of the block */
1945 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1946 ebp->sch->next : ebp->sch));
1947 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1948 /* add pop to the end of the block */
1949 addiCodeToeBBlock (ebp, nic, NULL);
1952 /* if spilt because not used in the remainder of the
1953 block then add a push before this instruction and
1954 a pop at the end of the block */
1955 if (ssym->remainSpil)
1958 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1959 /* add push just before this instruction */
1960 addiCodeToeBBlock (ebp, nic, ic);
1962 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1963 /* add pop to the end of the block */
1964 addiCodeToeBBlock (ebp, nic, NULL);
1973 /*-----------------------------------------------------------------*/
1974 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1975 /*-----------------------------------------------------------------*/
1977 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1982 debugLog ("%s\n", __FUNCTION__);
1984 /* try for a ptr type */
1985 if ((reg = allocReg (REG_PTR)))
1988 /* try for gpr type */
1989 if ((reg = allocReg (REG_GPR)))
1992 /* we have to spil */
1993 if (!spilSomething (ic, ebp, sym))
1996 /* make sure partially assigned registers aren't reused */
1997 for (j=0; j<=sym->nRegs; j++)
1999 sym->regs[j]->isFree = 0;
2001 /* this looks like an infinite loop but
2002 in really selectSpil will abort */
2006 /*-----------------------------------------------------------------*/
2007 /* getRegGpr - will try for GPR if not spil */
2008 /*-----------------------------------------------------------------*/
2010 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
2015 debugLog ("%s\n", __FUNCTION__);
2017 /* try for gpr type */
2018 if ((reg = allocReg (REG_GPR)))
2021 if (!pic16_ptrRegReq)
2022 if ((reg = allocReg (REG_PTR)))
2025 /* we have to spil */
2026 if (!spilSomething (ic, ebp, sym))
2029 /* make sure partially assigned registers aren't reused */
2030 for (j=0; j<=sym->nRegs; j++)
2032 sym->regs[j]->isFree = 0;
2034 /* this looks like an infinite loop but
2035 in really selectSpil will abort */
2039 /*-----------------------------------------------------------------*/
2040 /* symHasReg - symbol has a given register */
2041 /*-----------------------------------------------------------------*/
2043 symHasReg (symbol * sym, regs * reg)
2047 debugLog ("%s\n", __FUNCTION__);
2048 for (i = 0; i < sym->nRegs; i++)
2049 if (sym->regs[i] == reg)
2055 /*-----------------------------------------------------------------*/
2056 /* deassignLRs - check the live to and if they have registers & are */
2057 /* not spilt then free up the registers */
2058 /*-----------------------------------------------------------------*/
2060 deassignLRs (iCode * ic, eBBlock * ebp)
2066 debugLog ("%s\n", __FUNCTION__);
2067 for (sym = hTabFirstItem (liveRanges, &k); sym;
2068 sym = hTabNextItem (liveRanges, &k))
2071 symbol *psym = NULL;
2072 /* if it does not end here */
2073 if (sym->liveTo > ic->seq)
2076 /* if it was spilt on stack then we can
2077 mark the stack spil location as free */
2082 sym->usl.spillLoc->isFree = 1;
2088 if (!bitVectBitValue (_G.regAssigned, sym->key))
2091 /* special case for shifting: there is a case where shift count
2092 * can be allocated in the same register as the result, so do not
2093 * free right registers if same as result registers, cause genShiftLeft
2094 * will fail -- VR */
2095 if(ic->op == LEFT_OP)
2098 /* special case check if this is an IFX &
2099 the privious one was a pop and the
2100 previous one was not spilt then keep track
2102 if (ic->op == IFX && ic->prev &&
2103 ic->prev->op == IPOP &&
2104 !ic->prev->parmPush &&
2105 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2106 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2112 bitVectUnSetBit (_G.regAssigned, sym->key);
2114 /* if the result of this one needs registers
2115 and does not have it then assign it right
2117 if (IC_RESULT (ic) &&
2118 !(SKIP_IC2 (ic) || /* not a special icode */
2119 ic->op == JUMPTABLE ||
2124 POINTER_SET (ic)) &&
2125 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2126 result->liveTo > ic->seq && /* and will live beyond this */
2127 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2128 result->liveFrom == ic->seq && /* does not start before here */
2129 result->regType == sym->regType && /* same register types */
2130 result->nRegs && /* which needs registers */
2131 !result->isspilt && /* and does not already have them */
2133 !bitVectBitValue (_G.regAssigned, result->key) &&
2134 /* the number of free regs + number of regs in this LR
2135 can accomodate the what result Needs */
2136 ((nfreeRegsType (result->regType) +
2137 sym->nRegs) >= result->nRegs)
2142 // for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2143 /* the above does not free the unsued registers in sym,
2144 * leaving them marked as used, and increasing register usage
2145 * until the end of the function - VR 23/11/05 */
2147 for (i = 0; i < result->nRegs; i++)
2149 result->regs[i] = sym->regs[i];
2151 result->regs[i] = getRegGpr (ic, ebp, result);
2153 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2156 /* free the remaining */
2157 for (; i < sym->nRegs; i++)
2161 if (!symHasReg (psym, sym->regs[i]))
2162 freeReg (sym->regs[i]);
2165 freeReg (sym->regs[i]);
2172 /*-----------------------------------------------------------------*/
2173 /* reassignLR - reassign this to registers */
2174 /*-----------------------------------------------------------------*/
2176 reassignLR (operand * op)
2178 symbol *sym = OP_SYMBOL (op);
2181 debugLog ("%s\n", __FUNCTION__);
2182 /* not spilt any more */
2183 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2184 bitVectUnSetBit (_G.spiltSet, sym->key);
2186 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2190 for (i = 0; i < sym->nRegs; i++)
2191 sym->regs[i]->isFree = 0;
2194 /*-----------------------------------------------------------------*/
2195 /* willCauseSpill - determines if allocating will cause a spill */
2196 /*-----------------------------------------------------------------*/
2198 willCauseSpill (int nr, int rt)
2200 debugLog ("%s\n", __FUNCTION__);
2201 /* first check if there are any avlb registers
2202 of te type required */
2205 /* special case for pointer type
2206 if pointer type not avlb then
2207 check for type gpr */
2208 if (nFreeRegs (rt) >= nr)
2210 if (nFreeRegs (REG_GPR) >= nr)
2215 if (pic16_ptrRegReq)
2217 if (nFreeRegs (rt) >= nr)
2222 if (nFreeRegs (REG_PTR) +
2223 nFreeRegs (REG_GPR) >= nr)
2228 debugLog (" ... yep it will (cause a spill)\n");
2229 /* it will cause a spil */
2233 /*-----------------------------------------------------------------*/
2234 /* positionRegs - the allocator can allocate same registers to res- */
2235 /* ult and operand, if this happens make sure they are in the same */
2236 /* position as the operand otherwise chaos results */
2237 /*-----------------------------------------------------------------*/
2239 positionRegs (symbol * result, symbol * opsym, int lineno)
2241 int count = min (result->nRegs, opsym->nRegs);
2242 int i, j = 0, shared = 0;
2244 debugLog ("%s\n", __FUNCTION__);
2245 /* if the result has been spilt then cannot share */
2250 /* first make sure that they actually share */
2251 for (i = 0; i < count; i++)
2253 for (j = 0; j < count; j++)
2255 if (result->regs[i] == opsym->regs[j] && i != j)
2265 regs *tmp = result->regs[i];
2266 result->regs[i] = result->regs[j];
2267 result->regs[j] = tmp;
2272 /*------------------------------------------------------------------*/
2273 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2274 /* it should either have registers or have beed spilled. Otherwise, */
2275 /* there was an uninitialized variable, so just spill this to get */
2276 /* the operand in a valid state. */
2277 /*------------------------------------------------------------------*/
2279 verifyRegsAssigned (operand *op, iCode * ic)
2284 if (!IS_ITEMP (op)) return;
2286 sym = OP_SYMBOL (op);
2287 if (sym->isspilt) return;
2288 if (!sym->nRegs) return;
2289 if (sym->regs[0]) return;
2291 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2292 sym->prereqv ? sym->prereqv->name : sym->name);
2297 /*-----------------------------------------------------------------*/
2298 /* serialRegAssign - serially allocate registers to the variables */
2299 /*-----------------------------------------------------------------*/
2301 serialRegAssign (eBBlock ** ebbs, int count)
2306 debugLog ("%s\n", __FUNCTION__);
2307 /* for all blocks */
2308 for (i = 0; i < count; i++)
2310 if (ebbs[i]->noPath &&
2311 (ebbs[i]->entryLabel != entryLabel &&
2312 ebbs[i]->entryLabel != returnLabel))
2315 /* of all instructions do */
2316 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2319 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2321 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2322 pic16_allocDirReg(IC_RESULT(ic));
2324 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2325 pic16_allocDirReg(IC_LEFT(ic));
2327 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2328 pic16_allocDirReg(IC_RIGHT(ic));
2330 /* if this is an ipop that means some live
2331 range will have to be assigned again */
2333 reassignLR (IC_LEFT (ic));
2335 /* if result is present && is a true symbol */
2336 if (IC_RESULT (ic) && ic->op != IFX &&
2337 IS_TRUE_SYMOP (IC_RESULT (ic)))
2338 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2340 /* take away registers from live
2341 ranges that end at this instruction */
2342 deassignLRs (ic, ebbs[i]);
2344 /* some don't need registers */
2345 if (SKIP_IC2 (ic) ||
2346 ic->op == JUMPTABLE ||
2350 (IC_RESULT (ic) && POINTER_SET (ic)))
2353 /* now we need to allocate registers
2354 only for the result */
2357 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2363 /* Make sure any spill location is definately allocated */
2364 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2365 !sym->usl.spillLoc->allocreq)
2367 sym->usl.spillLoc->allocreq++;
2370 /* if it does not need or is spilt
2371 or is already assigned to registers
2372 or will not live beyond this instructions */
2375 bitVectBitValue (_G.regAssigned, sym->key) ||
2376 sym->liveTo <= ic->seq)
2379 /* if some liverange has been spilt at the block level
2380 and this one live beyond this block then spil this
2382 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2387 /* if trying to allocate this will cause
2388 a spill and there is nothing to spill
2389 or this one is rematerializable then
2391 willCS = willCauseSpill (sym->nRegs, sym->regType);
2393 /* explicit turn off register spilling */
2396 spillable = computeSpillable (ic);
2398 (willCS && bitVectIsZero (spillable)))
2406 /* If the live range preceeds the point of definition
2407 then ideally we must take into account registers that
2408 have been allocated after sym->liveFrom but freed
2409 before ic->seq. This is complicated, so spill this
2410 symbol instead and let fillGaps handle the allocation. */
2412 if (sym->liveFrom < ic->seq)
2418 /* if it has a spillocation & is used less than
2419 all other live ranges then spill this */
2421 if (sym->usl.spillLoc) {
2422 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2423 allLRs, ebbs[i], ic));
2424 if (leastUsed && leastUsed->used > sym->used) {
2429 /* if none of the liveRanges have a spillLocation then better
2430 to spill this one than anything else already assigned to registers */
2431 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2432 /* if this is local to this block then we might find a block spil */
2433 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2441 if (ic->op == RECEIVE)
2442 debugLog ("When I get clever, I'll optimize the receive logic\n");
2444 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2445 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2446 && (ic->next->op == IFX)
2447 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2449 /* skip register allocation since none will be used */
2450 for(j=0;j<sym->nRegs;j++)
2451 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2452 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2457 /* if we need ptr regs for the right side
2459 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2460 <= (unsigned) PTRSIZE)
2465 /* else we assign registers to it */
2466 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2469 bitVectDebugOn(_G.regAssigned, debugF);
2471 for (j = 0; j < sym->nRegs; j++)
2473 if (sym->regType == REG_PTR)
2474 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2476 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2478 /* if the allocation falied which means
2479 this was spilt then break */
2483 debugLog (" %d - \n", __LINE__);
2485 /* if it shares registers with operands make sure
2486 that they are in the same position */
2487 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2488 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2489 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2490 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2491 /* do the same for the right operand */
2492 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2493 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2494 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2495 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2497 debugLog (" %d - \n", __LINE__);
2500 debugLog (" %d - \n", __LINE__);
2509 /* Check for and fix any problems with uninitialized operands */
2510 for (i = 0; i < count; i++)
2514 if (ebbs[i]->noPath &&
2515 (ebbs[i]->entryLabel != entryLabel &&
2516 ebbs[i]->entryLabel != returnLabel))
2519 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2526 verifyRegsAssigned (IC_COND (ic), ic);
2530 if (ic->op == JUMPTABLE)
2532 verifyRegsAssigned (IC_JTCOND (ic), ic);
2536 verifyRegsAssigned (IC_RESULT (ic), ic);
2537 verifyRegsAssigned (IC_LEFT (ic), ic);
2538 verifyRegsAssigned (IC_RIGHT (ic), ic);
2544 /*-----------------------------------------------------------------*/
2545 /* rUmaskForOp :- returns register mask for an operand */
2546 /*-----------------------------------------------------------------*/
2548 rUmaskForOp (operand * op)
2554 debugLog ("%s\n", __FUNCTION__);
2555 /* only temporaries are assigned registers */
2559 sym = OP_SYMBOL (op);
2561 /* if spilt or no registers assigned to it
2563 if (sym->isspilt || !sym->nRegs)
2566 rumask = newBitVect (pic16_nRegs);
2568 for (j = 0; j < sym->nRegs; j++)
2570 rumask = bitVectSetBit (rumask,
2571 sym->regs[j]->rIdx);
2577 /*-----------------------------------------------------------------*/
2578 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2579 /*-----------------------------------------------------------------*/
2581 regsUsedIniCode (iCode * ic)
2583 bitVect *rmask = newBitVect (pic16_nRegs);
2585 debugLog ("%s\n", __FUNCTION__);
2586 /* do the special cases first */
2589 rmask = bitVectUnion (rmask,
2590 rUmaskForOp (IC_COND (ic)));
2594 /* for the jumptable */
2595 if (ic->op == JUMPTABLE)
2597 rmask = bitVectUnion (rmask,
2598 rUmaskForOp (IC_JTCOND (ic)));
2603 /* of all other cases */
2605 rmask = bitVectUnion (rmask,
2606 rUmaskForOp (IC_LEFT (ic)));
2610 rmask = bitVectUnion (rmask,
2611 rUmaskForOp (IC_RIGHT (ic)));
2614 rmask = bitVectUnion (rmask,
2615 rUmaskForOp (IC_RESULT (ic)));
2621 /*-----------------------------------------------------------------*/
2622 /* createRegMask - for each instruction will determine the regsUsed */
2623 /*-----------------------------------------------------------------*/
2625 createRegMask (eBBlock ** ebbs, int count)
2629 debugLog ("%s\n", __FUNCTION__);
2630 /* for all blocks */
2631 for (i = 0; i < count; i++)
2635 if (ebbs[i]->noPath &&
2636 (ebbs[i]->entryLabel != entryLabel &&
2637 ebbs[i]->entryLabel != returnLabel))
2640 /* for all instructions */
2641 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2646 if (SKIP_IC2 (ic) || !ic->rlive)
2649 /* first mark the registers used in this
2651 ic->rUsed = regsUsedIniCode (ic);
2652 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2654 /* now create the register mask for those
2655 registers that are in use : this is a
2656 super set of ic->rUsed */
2657 ic->rMask = newBitVect (pic16_nRegs + 1);
2659 /* for all live Ranges alive at this point */
2660 for (j = 1; j < ic->rlive->size; j++)
2665 /* if not alive then continue */
2666 if (!bitVectBitValue (ic->rlive, j))
2669 /* find the live range we are interested in */
2670 if (!(sym = hTabItemWithKey (liveRanges, j)))
2672 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2673 "createRegMask cannot find live range");
2677 /* if no register assigned to it */
2678 if (!sym->nRegs || sym->isspilt)
2681 /* for all the registers allocated to it */
2682 for (k = 0; k < sym->nRegs; k++)
2685 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2691 /*-----------------------------------------------------------------*/
2692 /* rematStr - returns the rematerialized string for a remat var */
2693 /*-----------------------------------------------------------------*/
2695 rematStr (symbol * sym)
2698 iCode *ic = sym->rematiCode;
2699 symbol *psym = NULL;
2701 debugLog ("%s\n", __FUNCTION__);
2703 //printf ("%s\n", s);
2705 /* if plus or minus print the right hand side */
2707 if (ic->op == '+' || ic->op == '-') {
2709 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2711 sprintf (s, "(%s %c 0x%04x)",
2712 OP_SYMBOL (IC_LEFT (ric))->rname,
2714 (int) operandLitValue (IC_RIGHT (ic)));
2717 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2719 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2720 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2725 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2726 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2728 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2733 /*-----------------------------------------------------------------*/
2734 /* rematStr - returns the rematerialized string for a remat var */
2735 /*-----------------------------------------------------------------*/
2737 rematStr (symbol * sym)
2740 iCode *ic = sym->rematiCode;
2742 debugLog ("%s\n", __FUNCTION__);
2747 /* if plus or minus print the right hand side */
2749 if (ic->op == '+' || ic->op == '-') {
2750 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2753 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2757 if (ic->op == '+' || ic->op == '-')
2759 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2760 sprintf (s, "(%s %c 0x%04x)",
2761 OP_SYMBOL (IC_LEFT (ric))->rname,
2763 (int) operandLitValue (IC_RIGHT (ic)));
2766 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2768 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2772 /* we reached the end */
2773 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2777 printf ("%s\n", buffer);
2782 /*-----------------------------------------------------------------*/
2783 /* regTypeNum - computes the type & number of registers required */
2784 /*-----------------------------------------------------------------*/
2792 debugLog ("%s\n", __FUNCTION__);
2793 /* for each live range do */
2794 for (sym = hTabFirstItem (liveRanges, &k); sym;
2795 sym = hTabNextItem (liveRanges, &k)) {
2797 debugLog (" %d - %s\n", __LINE__, sym->rname);
2798 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2800 /* if used zero times then no registers needed */
2801 if ((sym->liveTo - sym->liveFrom) == 0)
2805 /* if the live range is a temporary */
2808 debugLog (" %d - itemp register\n", __LINE__);
2810 /* if the type is marked as a conditional */
2811 if (sym->regType == REG_CND)
2814 /* if used in return only then we don't
2816 if (sym->ruonly || sym->accuse) {
2817 if (IS_AGGREGATE (sym->type) || sym->isptr)
2818 sym->type = aggrToPtr (sym->type, FALSE);
2819 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2823 /* if the symbol has only one definition &
2824 that definition is a get_pointer and the
2825 pointer we are getting is rematerializable and
2828 if (bitVectnBitsOn (sym->defs) == 1 &&
2829 (ic = hTabItemWithKey (iCodehTab,
2830 bitVectFirstBit (sym->defs))) &&
2832 !IS_BITVAR (sym->etype) &&
2833 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2835 // continue; /* FIXME -- VR */
2836 if (ptrPseudoSymSafe (sym, ic)) {
2840 debugLog (" %d - \n", __LINE__);
2842 /* create a psuedo symbol & force a spil */
2843 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2844 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2845 psym->type = sym->type;
2846 psym->etype = sym->etype;
2847 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2848 strcpy (psym->rname, psym->name);
2850 sym->usl.spillLoc = psym;
2854 /* if in data space or idata space then try to
2855 allocate pointer register */
2859 /* if not then we require registers */
2860 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2861 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2862 getSize (sym->type));
2866 if(IS_PTR_CONST (sym->type)) {
2868 if(IS_CODEPTR (sym->type)) {
2870 // what IS this ???? (HJD)
2871 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2872 sym->nRegs = 3; // patch 14
2875 if (sym->nRegs > 4) {
2876 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2877 printTypeChain (sym->type, stderr);
2878 fprintf (stderr, "\n");
2881 /* determine the type of register required */
2882 if (sym->nRegs == 1 &&
2883 IS_PTR (sym->type) &&
2885 sym->regType = REG_PTR;
2887 sym->regType = REG_GPR;
2890 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2894 /* for the first run we don't provide */
2895 /* registers for true symbols we will */
2896 /* see how things go */
2902 static DEFSETFUNC (markRegFree)
2904 ((regs *)item)->isFree = 1;
2905 // ((regs *)item)->wasUsed = 0;
2910 DEFSETFUNC (pic16_deallocReg)
2912 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2913 ((regs *)item)->isFree = 1;
2914 ((regs *)item)->wasUsed = 0;
2918 /*-----------------------------------------------------------------*/
2919 /* freeAllRegs - mark all registers as free */
2920 /*-----------------------------------------------------------------*/
2922 pic16_freeAllRegs ()
2924 debugLog ("%s\n", __FUNCTION__);
2926 applyToSet(pic16_dynAllocRegs,markRegFree);
2927 applyToSet(pic16_dynStackRegs,markRegFree);
2930 /*-----------------------------------------------------------------*/
2931 /*-----------------------------------------------------------------*/
2933 pic16_deallocateAllRegs ()
2935 debugLog ("%s\n", __FUNCTION__);
2937 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2941 /*-----------------------------------------------------------------*/
2942 /* deallocStackSpil - this will set the stack pointer back */
2943 /*-----------------------------------------------------------------*/
2945 DEFSETFUNC (deallocStackSpil)
2949 debugLog ("%s\n", __FUNCTION__);
2954 /*-----------------------------------------------------------------*/
2955 /* farSpacePackable - returns the packable icode for far variables */
2956 /*-----------------------------------------------------------------*/
2958 farSpacePackable (iCode * ic)
2962 debugLog ("%s\n", __FUNCTION__);
2963 /* go thru till we find a definition for the
2964 symbol on the right */
2965 for (dic = ic->prev; dic; dic = dic->prev)
2968 /* if the definition is a call then no */
2969 if ((dic->op == CALL || dic->op == PCALL) &&
2970 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2975 /* if shift by unknown amount then not */
2976 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2977 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2980 /* if pointer get and size > 1 */
2981 if (POINTER_GET (dic) &&
2982 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2985 if (POINTER_SET (dic) &&
2986 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2989 /* if any three is a true symbol in far space */
2990 if (IC_RESULT (dic) &&
2991 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2992 isOperandInFarSpace (IC_RESULT (dic)))
2995 if (IC_RIGHT (dic) &&
2996 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2997 isOperandInFarSpace (IC_RIGHT (dic)) &&
2998 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
3001 if (IC_LEFT (dic) &&
3002 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
3003 isOperandInFarSpace (IC_LEFT (dic)) &&
3004 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
3007 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
3009 if ((dic->op == LEFT_OP ||
3010 dic->op == RIGHT_OP ||
3012 IS_OP_LITERAL (IC_RIGHT (dic)))
3023 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
3027 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3028 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3029 debugAopGet (" result:", IC_RESULT (ic));
3030 debugAopGet (" left:", IC_LEFT (ic));
3031 debugAopGet (" right:", IC_RIGHT (ic));
3040 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3042 /*-----------------------------------------------------------------*/
3043 /* packRegsForAssign - register reduction for assignment */
3044 /*-----------------------------------------------------------------*/
3046 packRegsForAssign (iCode * ic, eBBlock * ebp)
3050 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3051 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3052 debugAopGet (" result:", IC_RESULT (ic));
3053 debugAopGet (" left:", IC_LEFT (ic));
3054 debugAopGet (" right:", IC_RIGHT (ic));
3056 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3058 debugLog(" %d - actuall processing\n", __LINE__ );
3060 if (!IS_ITEMP (IC_RESULT (ic))) {
3061 pic16_allocDirReg(IC_RESULT (ic));
3062 debugLog (" %d - result is not temp\n", __LINE__);
3065 // if(IS_VALOP(IC_RIGHT(ic)))return 0;
3067 /* See BUGLOG0001 - VR */
3069 if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3070 debugLog (" %d - not packing - right is not temp\n", __LINE__);
3071 pic16_allocDirReg(IC_RIGHT (ic));
3076 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3077 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3079 debugLog (" %d - not packing - right side fails \n", __LINE__);
3083 /* if the true symbol is defined in far space or on stack
3084 then we should not since this will increase register pressure */
3085 if (isOperandInFarSpace (IC_RESULT (ic)))
3087 if ((dic = farSpacePackable (ic)))
3094 /* find the definition of iTempNN scanning backwards if we find a
3095 a use of the true symbol before we find the definition then
3097 for (dic = ic->prev; dic; dic = dic->prev)
3100 /* if there is a function call and this is
3101 a parameter & not my parameter then don't pack it */
3102 if ((dic->op == CALL || dic->op == PCALL) &&
3103 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3104 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3106 debugLog (" %d - \n", __LINE__);
3115 debugLog("%d\tSearching for iTempNN\n", __LINE__);
3117 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3118 IS_OP_VOLATILE (IC_RESULT (dic)))
3120 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3126 if( IS_SYMOP( IC_RESULT(dic)) &&
3127 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3129 debugLog (" %d - result is bitfield\n", __LINE__);
3135 if (IS_SYMOP (IC_RESULT (dic)) &&
3136 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3138 /* A previous result was assigned to the same register - we'll our definition */
3139 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3140 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3141 if (POINTER_SET (dic))
3147 if (IS_SYMOP (IC_RIGHT (dic)) &&
3148 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3149 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3151 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3156 if (IS_SYMOP (IC_LEFT (dic)) &&
3157 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3158 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3160 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3165 if (POINTER_SET (dic) &&
3166 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3168 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3176 return 0; /* did not find */
3179 /* This code is taken from the hc08 port. Do not know
3180 * if it fits for pic16, but I leave it here just in case */
3182 /* if assignment then check that right is not a bit */
3183 if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
3184 sym_link *etype = operandType (IC_RESULT (dic));
3186 if (IS_BITFIELD (etype)) {
3187 /* if result is a bit too then it's ok */
3188 etype = operandType (IC_RESULT (ic));
3189 if (!IS_BITFIELD (etype)) {
3190 debugLog(" %d bitfields\n");
3197 /* if the result is on stack or iaccess then it must be
3198 the same atleast one of the operands */
3199 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3200 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3202 /* the operation has only one symbol
3203 operator then we can pack */
3204 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3205 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3208 if (!((IC_LEFT (dic) &&
3209 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3211 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3215 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3216 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3217 /* found the definition */
3218 /* replace the result with the result of */
3219 /* this assignment and remove this assignment */
3222 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3223 IC_RESULT (dic) = IC_RESULT (ic);
3225 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3227 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3229 /* delete from liverange table also
3230 delete from all the points inbetween and the new
3232 for (sic = dic; sic != ic; sic = sic->next)
3234 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3235 if (IS_ITEMP (IC_RESULT (dic)))
3236 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3239 remiCodeFromeBBlock (ebp, ic);
3240 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3242 debugLog(" %d\n", __LINE__ );
3243 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3244 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3251 #define NO_packRegsForAccUse
3252 #define NO_packRegsForSupport
3253 #define NO_packRegsForOneuse
3254 #define NO_cast_peep
3259 #ifndef NO_packRegsForSupport
3260 /*-----------------------------------------------------------------*/
3261 /* findAssignToSym : scanning backwards looks for first assig found */
3262 /*-----------------------------------------------------------------*/
3264 findAssignToSym (operand * op, iCode * ic)
3268 debugLog ("%s\n", __FUNCTION__);
3269 for (dic = ic->prev; dic; dic = dic->prev)
3272 /* if definition by assignment */
3273 if (dic->op == '=' &&
3274 !POINTER_SET (dic) &&
3275 IC_RESULT (dic)->key == op->key
3276 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3280 /* we are interested only if defined in far space */
3281 /* or in stack space in case of + & - */
3283 /* if assigned to a non-symbol then return
3285 if (!IS_SYMOP (IC_RIGHT (dic)))
3288 /* if the symbol is in far space then
3290 if (isOperandInFarSpace (IC_RIGHT (dic)))
3293 /* for + & - operations make sure that
3294 if it is on the stack it is the same
3295 as one of the three operands */
3296 if ((ic->op == '+' || ic->op == '-') &&
3297 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3299 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3300 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3301 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3309 /* if we find an usage then we cannot delete it */
3310 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3313 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3316 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3320 /* now make sure that the right side of dic
3321 is not defined between ic & dic */
3324 iCode *sic = dic->next;
3326 for (; sic != ic; sic = sic->next)
3327 if (IC_RESULT (sic) &&
3328 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3339 #ifndef NO_packRegsForSupport
3340 /*-----------------------------------------------------------------*/
3341 /* packRegsForSupport :- reduce some registers for support calls */
3342 /*-----------------------------------------------------------------*/
3344 packRegsForSupport (iCode * ic, eBBlock * ebp)
3348 debugLog ("%s\n", __FUNCTION__);
3349 /* for the left & right operand :- look to see if the
3350 left was assigned a true symbol in far space in that
3351 case replace them */
3352 if (IS_ITEMP (IC_LEFT (ic)) &&
3353 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3355 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3361 debugAopGet ("removing left:", IC_LEFT (ic));
3363 /* found it we need to remove it from the
3365 for (sic = dic; sic != ic; sic = sic->next)
3366 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3368 IC_LEFT (ic)->operand.symOperand =
3369 IC_RIGHT (dic)->operand.symOperand;
3370 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3371 remiCodeFromeBBlock (ebp, dic);
3372 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3373 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3377 /* do the same for the right operand */
3380 IS_ITEMP (IC_RIGHT (ic)) &&
3381 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3383 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3389 /* if this is a subtraction & the result
3390 is a true symbol in far space then don't pack */
3391 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3393 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3394 if (IN_FARSPACE (SPEC_OCLS (etype)))
3398 debugAopGet ("removing right:", IC_RIGHT (ic));
3400 /* found it we need to remove it from the
3402 for (sic = dic; sic != ic; sic = sic->next)
3403 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3405 IC_RIGHT (ic)->operand.symOperand =
3406 IC_RIGHT (dic)->operand.symOperand;
3407 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3409 remiCodeFromeBBlock (ebp, dic);
3410 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3411 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3420 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3422 #ifndef NO_packRegsForOneuse
3423 /*-----------------------------------------------------------------*/
3424 /* packRegsForOneuse : - will reduce some registers for single Use */
3425 /*-----------------------------------------------------------------*/
3427 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3434 debugLog ("%s\n", __FUNCTION__);
3435 /* if returning a literal then do nothing */
3439 if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3442 /* only upto 2 bytes since we cannot predict
3443 the usage of b, & acc */
3444 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3452 /* this routine will mark the a symbol as used in one
3453 instruction use only && if the definition is local
3454 (ie. within the basic block) && has only one definition &&
3455 that definition is either a return value from a
3456 function or does not contain any variables in
3460 uses = bitVectCopy (OP_USES (op));
3461 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3462 if (!bitVectIsZero (uses)) /* has other uses */
3467 if (bitVectnBitsOn (OP_USES (op)) > 1)
3471 /* if it has only one defintion */
3472 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3473 return NULL; /* has more than one definition */
3475 /* get that definition */
3477 hTabItemWithKey (iCodehTab,
3478 bitVectFirstBit (OP_DEFS (op)))))
3481 /* found the definition now check if it is local */
3482 if (dic->seq < ebp->fSeq ||
3483 dic->seq > ebp->lSeq)
3484 return NULL; /* non-local */
3486 /* now check if it is the return from
3488 if (dic->op == CALL || dic->op == PCALL)
3490 if (ic->op != SEND && ic->op != RETURN &&
3491 !POINTER_SET(ic) && !POINTER_GET(ic))
3493 OP_SYMBOL (op)->ruonly = 1;
3502 /* otherwise check that the definition does
3503 not contain any symbols in far space */
3504 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3505 isOperandInFarSpace (IC_RIGHT (dic)) ||
3506 IS_OP_RUONLY (IC_LEFT (ic)) ||
3507 IS_OP_RUONLY (IC_RIGHT (ic)))
3512 /* if pointer set then make sure the pointer
3514 if (POINTER_SET (dic) &&
3515 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3518 if (POINTER_GET (dic) &&
3519 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3525 /* also make sure the intervenening instructions
3526 don't have any thing in far space */
3527 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3530 /* if there is an intervening function call then no */
3531 if (dic->op == CALL || dic->op == PCALL)
3533 /* if pointer set then make sure the pointer
3535 if (POINTER_SET (dic) &&
3536 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3539 if (POINTER_GET (dic) &&
3540 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3543 /* if address of & the result is remat then okay */
3544 if (dic->op == ADDRESS_OF &&
3545 OP_SYMBOL (IC_RESULT (dic))->remat)
3548 /* if operand has size of three or more & this
3549 operation is a '*','/' or '%' then 'b' may
3551 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3552 getSize (operandType (op)) >= 2)
3555 /* if left or right or result is in far space */
3556 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3557 isOperandInFarSpace (IC_RIGHT (dic)) ||
3558 isOperandInFarSpace (IC_RESULT (dic)) ||
3559 IS_OP_RUONLY (IC_LEFT (dic)) ||
3560 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3561 IS_OP_RUONLY (IC_RESULT (dic)))
3567 OP_SYMBOL (op)->ruonly = 1;
3574 /*-----------------------------------------------------------------*/
3575 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3576 /*-----------------------------------------------------------------*/
3578 isBitwiseOptimizable (iCode * ic)
3580 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3581 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3583 debugLog ("%s\n", __FUNCTION__);
3584 /* bitwise operations are considered optimizable
3585 under the following conditions (Jean-Louis VERN)
3597 if (IS_LITERAL (rtype) ||
3598 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3605 #ifndef NO_packRegsForAccUse
3607 /*-----------------------------------------------------------------*/
3608 /* packRegsForAccUse - pack registers for acc use */
3609 /*-----------------------------------------------------------------*/
3611 packRegsForAccUse (iCode * ic)
3615 debugLog ("%s\n", __FUNCTION__);
3617 /* if this is an aggregate, e.g. a one byte char array */
3618 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3621 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3623 /* if + or - then it has to be one byte result */
3624 if ((ic->op == '+' || ic->op == '-')
3625 && getSize (operandType (IC_RESULT (ic))) > 1)
3628 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3629 /* if shift operation make sure right side is not a literal */
3630 if (ic->op == RIGHT_OP &&
3631 (isOperandLiteral (IC_RIGHT (ic)) ||
3632 getSize (operandType (IC_RESULT (ic))) > 1))
3635 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3636 if (ic->op == LEFT_OP &&
3637 (isOperandLiteral (IC_RIGHT (ic)) ||
3638 getSize (operandType (IC_RESULT (ic))) > 1))
3641 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3642 if (IS_BITWISE_OP (ic) &&
3643 getSize (operandType (IC_RESULT (ic))) > 1)
3647 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3648 /* has only one definition */
3649 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3652 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3653 /* has only one use */
3654 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3657 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3658 /* and the usage immediately follows this iCode */
3659 if (!(uic = hTabItemWithKey (iCodehTab,
3660 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3663 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3664 if (ic->next != uic)
3667 /* if it is a conditional branch then we definitely can */
3671 if (uic->op == JUMPTABLE)
3674 /* if the usage is not is an assignment
3675 or an arithmetic / bitwise / shift operation then not */
3676 if (POINTER_SET (uic) &&
3677 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3680 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3681 if (uic->op != '=' &&
3682 !IS_ARITHMETIC_OP (uic) &&
3683 !IS_BITWISE_OP (uic) &&
3684 uic->op != LEFT_OP &&
3685 uic->op != RIGHT_OP)
3688 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3689 /* if used in ^ operation then make sure right is not a
3691 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3694 /* if shift operation make sure right side is not a literal */
3695 if (uic->op == RIGHT_OP &&
3696 (isOperandLiteral (IC_RIGHT (uic)) ||
3697 getSize (operandType (IC_RESULT (uic))) > 1))
3700 if (uic->op == LEFT_OP &&
3701 (isOperandLiteral (IC_RIGHT (uic)) ||
3702 getSize (operandType (IC_RESULT (uic))) > 1))
3705 /* make sure that the result of this icode is not on the
3706 stack, since acc is used to compute stack offset */
3707 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3708 OP_SYMBOL (IC_RESULT (uic))->onStack)
3711 /* if either one of them in far space then we cannot */
3712 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3713 isOperandInFarSpace (IC_LEFT (uic))) ||
3714 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3715 isOperandInFarSpace (IC_RIGHT (uic))))
3718 /* if the usage has only one operand then we can */
3719 if (IC_LEFT (uic) == NULL ||
3720 IC_RIGHT (uic) == NULL)
3723 /* make sure this is on the left side if not
3724 a '+' since '+' is commutative */
3725 if (ic->op != '+' &&
3726 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3730 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3731 /* if one of them is a literal then we can */
3732 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3733 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3734 (getSize (operandType (IC_RESULT (uic))) <= 1))
3736 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3741 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3742 /* if the other one is not on stack then we can */
3743 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3744 (IS_ITEMP (IC_RIGHT (uic)) ||
3745 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3746 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3749 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3750 (IS_ITEMP (IC_LEFT (uic)) ||
3751 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3752 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3758 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3759 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3766 /*-----------------------------------------------------------------*/
3767 /* packForPush - hueristics to reduce iCode for pushing */
3768 /*-----------------------------------------------------------------*/
3770 packForReceive (iCode * ic, eBBlock * ebp)
3774 debugLog ("%s\n", __FUNCTION__);
3775 debugAopGet (" result:", IC_RESULT (ic));
3776 debugAopGet (" left:", IC_LEFT (ic));
3777 debugAopGet (" right:", IC_RIGHT (ic));
3782 for (dic = ic->next; dic; dic = dic->next)
3784 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3785 debugLog (" used on left\n");
3786 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3787 debugLog (" used on right\n");
3788 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3789 debugLog (" used on result\n");
3791 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3792 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3796 debugLog (" hey we can remove this unnecessary assign\n");
3798 /*-----------------------------------------------------------------*/
3799 /* packForPush - hueristics to reduce iCode for pushing */
3800 /*-----------------------------------------------------------------*/
3802 packForPush (iCode * ic, eBBlock * ebp)
3807 debugLog ("%s\n", __FUNCTION__);
3808 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3816 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3817 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3818 iLine = printILine(ic);
3819 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3821 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3825 /* must have only definition & one usage */
3826 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3827 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3830 /* find the definition */
3831 if (!(dic = hTabItemWithKey (iCodehTab,
3832 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3835 /* if definition is not assignment,
3836 * or is not pointer (because pointer might have changed) */
3837 if (dic->op != '=' || POINTER_SET (dic))
3840 /* we must ensure that we can use the delete the assignment,
3841 * because the source might have been modified in between.
3842 * Until I know how to fix this, I'll use the adhoc fix
3843 * to check the liveranges */
3844 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3846 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3850 /* we now we know that it has one & only one def & use
3851 and the that the definition is an assignment */
3852 IC_LEFT (ic) = IC_RIGHT (dic);
3854 iLine = printILine(dic);
3855 debugf("remiCodeFromeBBlock: %s\n", iLine);
3858 remiCodeFromeBBlock (ebp, dic);
3859 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3860 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3863 static void printSymType(char * str, sym_link *sl)
3865 if(!pic16_ralloc_debug)return;
3867 debugLog (" %s Symbol type: ",str);
3868 printTypeChain (sl, debugF);
3872 /*-----------------------------------------------------------------*/
3873 /* some debug code to print the symbol S_TYPE. Note that
3874 * the function checkSClass in src/SDCCsymt.c dinks with
3875 * the S_TYPE in ways the PIC port doesn't fully like...*/
3876 /*-----------------------------------------------------------------*/
3877 static void isData(sym_link *sl)
3881 if(!pic16_ralloc_debug)return;
3888 for ( ; sl; sl=sl->next) {
3890 switch (SPEC_SCLS(sl)) {
3891 case S_DATA: fprintf (of, "data "); break;
3892 case S_XDATA: fprintf (of, "xdata "); break;
3893 case S_SFR: fprintf (of, "sfr "); break;
3894 case S_SBIT: fprintf (of, "sbit "); break;
3895 case S_CODE: fprintf (of, "code "); break;
3896 case S_IDATA: fprintf (of, "idata "); break;
3897 case S_PDATA: fprintf (of, "pdata "); break;
3898 case S_LITERAL: fprintf (of, "literal "); break;
3899 case S_STACK: fprintf (of, "stack "); break;
3900 case S_XSTACK: fprintf (of, "xstack "); break;
3901 case S_BIT: fprintf (of, "bit "); break;
3902 case S_EEPROM: fprintf (of, "eeprom "); break;
3910 /*--------------------------------------------------------------------*/
3911 /* pic16_packRegisters - does some transformations to reduce */
3912 /* register pressure */
3914 /*--------------------------------------------------------------------*/
3916 pic16_packRegisters (eBBlock * ebp)
3921 debugLog ("%s\n", __FUNCTION__);
3927 /* look for assignments of the form */
3928 /* iTempNN = TRueSym (someoperation) SomeOperand */
3930 /* TrueSym := iTempNN:1 */
3931 for (ic = ebp->sch; ic; ic = ic->next)
3933 // debugLog("%d\n", __LINE__);
3934 /* find assignment of the form TrueSym := iTempNN:1 */
3935 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3936 change += packRegsForAssign (ic, ebp);
3940 if (POINTER_SET (ic))
3941 debugLog ("pointer is set\n");
3942 debugAopGet (" result:", IC_RESULT (ic));
3943 debugAopGet (" left:", IC_LEFT (ic));
3944 debugAopGet (" right:", IC_RIGHT (ic));
3953 for (ic = ebp->sch; ic; ic = ic->next) {
3955 if(IS_SYMOP ( IC_LEFT(ic))) {
3956 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3958 debugAopGet ("x left:", IC_LEFT (ic));
3960 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3962 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3964 debugLog (" is a pointer\n");
3966 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3967 debugLog (" is a ptr\n");
3969 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3970 debugLog (" is volatile\n");
3974 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3975 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3976 pic16_allocDirReg(IC_LEFT (ic));
3979 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3982 if(IS_SYMOP ( IC_RIGHT(ic))) {
3983 debugAopGet (" right:", IC_RIGHT (ic));
3984 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3987 if(IS_SYMOP ( IC_RESULT(ic))) {
3988 debugAopGet (" result:", IC_RESULT (ic));
3989 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3992 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3993 debugAopGet (" right:", IC_RIGHT (ic));
3994 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3995 // pic16_allocDirReg(IC_RIGHT(ic));
3998 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3999 debugAopGet (" result:", IC_RESULT (ic));
4000 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
4001 // pic16_allocDirReg(IC_RESULT(ic));
4005 if (POINTER_SET (ic))
4006 debugLog (" %d - Pointer set\n", __LINE__);
4008 /* Look for two subsequent iCodes with */
4010 /* _c = iTemp & op; */
4011 /* and replace them by */
4014 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
4016 && ic->prev->op == '='
4017 && IS_ITEMP (IC_LEFT (ic))
4018 && IC_LEFT (ic) == IC_RESULT (ic->prev)
4019 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
4021 iCode* ic_prev = ic->prev;
4022 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
4024 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
4025 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
4026 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
4027 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
4028 prev_result_sym->liveTo == ic->seq)
4030 prev_result_sym->liveTo = ic_prev->seq;
4033 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
4035 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
4037 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
4038 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
4039 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
4040 remiCodeFromeBBlock (ebp, ic_prev);
4041 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
4045 /* if this is an itemp & result of a address of a true sym
4046 then mark this as rematerialisable */
4047 if (ic->op == ADDRESS_OF &&
4048 IS_ITEMP (IC_RESULT (ic)) &&
4049 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4050 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4051 !OP_SYMBOL (IC_LEFT (ic))->onStack)
4054 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4056 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4057 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4058 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4062 /* if straight assignment then carry remat flag if
4063 this is the only definition */
4064 if (ic->op == '=' &&
4065 !POINTER_SET (ic) &&
4066 IS_SYMOP (IC_RIGHT (ic)) &&
4067 OP_SYMBOL (IC_RIGHT (ic))->remat &&
4068 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4070 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4072 OP_SYMBOL (IC_RESULT (ic))->remat =
4073 OP_SYMBOL (IC_RIGHT (ic))->remat;
4074 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4075 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4078 /* if this is a +/- operation with a rematerizable
4079 then mark this as rematerializable as well */
4080 if ((ic->op == '+' || ic->op == '-') &&
4081 (IS_SYMOP (IC_LEFT (ic)) &&
4082 IS_ITEMP (IC_RESULT (ic)) &&
4083 OP_SYMBOL (IC_LEFT (ic))->remat &&
4084 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4085 IS_OP_LITERAL (IC_RIGHT (ic))))
4087 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4089 operandLitValue (IC_RIGHT (ic));
4090 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4091 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4092 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4097 /* try to optimize FSR0 usage when reading data memory pointers */
4099 if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4100 static int fsr0usage=0;
4103 if(POINTER_GET(ic) /* this is a memory read */
4104 && ic->loop /* this is in a loop */
4106 fprintf(stderr, "might optimize FSR0 usage\n");
4111 /* mark the pointer usages */
4112 if (POINTER_SET (ic))
4114 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4115 debugLog (" marking as a pointer (set) =>");
4116 debugAopGet (" result:", IC_RESULT (ic));
4120 if (POINTER_GET (ic))
4122 if(IS_SYMOP(IC_LEFT(ic))) {
4123 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4124 debugLog (" marking as a pointer (get) =>");
4125 debugAopGet (" left:", IC_LEFT (ic));
4128 if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4129 if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4130 iCode *dic = ic->prev;
4132 fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4134 if(dic && dic->op == '='
4135 && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4137 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4140 /* replace prev->left with ic->left */
4141 IC_LEFT(ic) = IC_RIGHT(dic);
4142 IC_RIGHT(ic->prev) = NULL;
4144 /* remove ic->prev iCode (assignment) */
4145 remiCodeFromeBBlock (ebp, dic);
4146 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4149 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4155 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
4159 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4160 /* if we are using a symbol on the stack
4161 then we should say pic16_ptrRegReq */
4162 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4163 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4164 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4165 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4166 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4167 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4171 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4172 if (IS_SYMOP (IC_LEFT (ic)))
4173 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4174 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4175 if (IS_SYMOP (IC_RIGHT (ic)))
4176 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4177 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4178 if (IS_SYMOP (IC_RESULT (ic)))
4179 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4180 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4183 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4187 /* if the condition of an if instruction
4188 is defined in the previous instruction then
4189 mark the itemp as a conditional */
4190 if ((IS_CONDITIONAL (ic) ||
4191 ((ic->op == BITWISEAND ||
4194 isBitwiseOptimizable (ic))) &&
4195 ic->next && ic->next->op == IFX &&
4196 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4197 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4200 debugLog (" %d\n", __LINE__);
4201 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4205 debugLog(" %d\n", __LINE__);
4207 #ifndef NO_packRegsForSupport
4208 /* reduce for support function calls */
4209 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4210 packRegsForSupport (ic, ebp);
4213 /* if a parameter is passed, it's in W, so we may not
4214 need to place a copy in a register */
4215 if (ic->op == RECEIVE)
4216 packForReceive (ic, ebp);
4218 #ifndef NO_packRegsForOneuse
4219 /* some cases the redundant moves can
4220 can be eliminated for return statements */
4221 if ((ic->op == RETURN || ic->op == SEND) &&
4222 !isOperandInFarSpace (IC_LEFT (ic)) &&
4224 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4227 #ifndef NO_packRegsForOneuse
4228 /* if pointer set & left has a size more than
4229 one and right is not in far space */
4230 if (POINTER_SET (ic) &&
4231 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4232 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4233 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4234 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4236 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4239 #ifndef NO_packRegsForOneuse
4240 /* if pointer get */
4241 if (POINTER_GET (ic) &&
4242 !isOperandInFarSpace (IC_RESULT (ic)) &&
4243 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4244 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4245 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4247 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4248 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4251 #ifndef NO_cast_peep
4252 /* if this is cast for intergral promotion then
4253 check if only use of the definition of the
4254 operand being casted/ if yes then replace
4255 the result of that arithmetic operation with
4256 this result and get rid of the cast */
4257 if (ic->op == CAST) {
4259 sym_link *fromType = operandType (IC_RIGHT (ic));
4260 sym_link *toType = operandType (IC_LEFT (ic));
4262 debugLog (" %d - casting\n", __LINE__);
4264 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4265 getSize (fromType) != getSize (toType)) {
4268 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4271 if (IS_ARITHMETIC_OP (dic)) {
4272 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4274 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4275 IC_RESULT (dic) = IC_RESULT (ic);
4276 remiCodeFromeBBlock (ebp, ic);
4277 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4278 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4279 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4283 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4287 /* if the type from and type to are the same
4288 then if this is the only use then packit */
4289 if (compareType (operandType (IC_RIGHT (ic)),
4290 operandType (IC_LEFT (ic))) == 1) {
4292 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4295 debugLog(" %d\n", __LINE__);
4297 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4298 IC_RESULT (dic) = IC_RESULT (ic);
4299 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4300 remiCodeFromeBBlock (ebp, ic);
4301 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4302 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4311 /* there are some problems with packing variables
4312 * it seems that the live range estimator doesn't
4313 * estimate correctly the liveranges of some symbols */
4316 iTempNN := (some variable in farspace) V1
4321 if (ic->op == IPUSH)
4323 packForPush (ic, ebp);
4327 #ifndef NO_packRegsForAccUse
4328 /* pack registers for accumulator use, when the
4329 result of an arithmetic or bit wise operation
4330 has only one use, that use is immediately following
4331 the defintion and the using iCode has only one
4332 operand or has two operands but one is literal &
4333 the result of that operation is not on stack then
4334 we can leave the result of this operation in acc:b
4336 if ((IS_ARITHMETIC_OP (ic)
4338 || IS_BITWISE_OP (ic)
4340 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4343 IS_ITEMP (IC_RESULT (ic)) &&
4344 getSize (operandType (IC_RESULT (ic))) <= 1)
4346 packRegsForAccUse (ic);
4353 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4357 if (!pic16_ralloc_debug || !debugF)
4360 for (i = 0; i < count; i++)
4362 fprintf (debugF, "\n----------------------------------------------------------------\n");
4363 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4364 ebbs[i]->entryLabel->name,
4367 ebbs[i]->isLastInLoop);
4368 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4373 fprintf (debugF, "visited %d : hasFcall = %d\n",
4377 fprintf (debugF, "\ndefines bitVector :");
4378 bitVectDebugOn (ebbs[i]->defSet, debugF);
4379 fprintf (debugF, "\nlocal defines bitVector :");
4380 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4381 fprintf (debugF, "\npointers Set bitvector :");
4382 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4383 fprintf (debugF, "\nin pointers Set bitvector :");
4384 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4385 fprintf (debugF, "\ninDefs Set bitvector :");
4386 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4387 fprintf (debugF, "\noutDefs Set bitvector :");
4388 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4389 fprintf (debugF, "\nusesDefs Set bitvector :");
4390 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4391 fprintf (debugF, "\n----------------------------------------------------------------\n");
4392 printiCChain (ebbs[i]->sch, debugF);
4396 void dbg_dumpregusage(void);
4398 /*-----------------------------------------------------------------*/
4399 /* pic16_assignRegisters - assigns registers to each live range as need */
4400 /*-----------------------------------------------------------------*/
4402 pic16_assignRegisters (ebbIndex * ebbi)
4404 eBBlock ** ebbs = ebbi->bbOrder;
4405 int count = ebbi->count;
4409 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4410 debugLog ("\nebbs before optimizing:\n");
4411 dumpEbbsToDebug (ebbs, count);
4413 _inRegAllocator = 1;
4415 pic16_freeAllRegs();
4418 /* clear whats left over from peephole parser */
4419 pic16_dynAllocRegs= newSet(); //NULL;
4420 // pic16_dynStackRegs= newSet(); //NULL;
4421 // pic16_dynProcessorRegs=newSet(); //NULL;
4422 // pic16_dynDirectRegs=newSet(); //NULL;
4423 // pic16_dynDirectBitRegs=newSet(); //NULL;
4424 // pic16_dynInternalRegs=newSet(); //NULL;
4425 // pic16_dynAccessRegs=newSet(); //NULL;
4427 // dynDirectRegNames=NULL;
4428 dynAllocRegNames=NULL;
4429 // dynProcRegNames=NULL;
4430 // dynAccessRegNames=NULL;
4433 setToNull ((void *) &_G.funcrUsed);
4434 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4437 /* change assignments this will remove some
4438 live ranges reducing some register pressure */
4439 for (i = 0; i < count; i++)
4440 pic16_packRegisters (ebbs[i]);
4447 debugLog("dir registers allocated so far:\n");
4448 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4452 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4453 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4454 reg = hTabNextItem(dynDirectRegNames, &hkey);
4460 /* liveranges probably changed by register packing
4461 so we compute them again */
4462 recomputeLiveRanges (ebbs, count);
4464 if (options.dump_pack)
4465 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4467 /* first determine for each live range the number of
4468 registers & the type of registers required for each */
4471 /* start counting function temporary registers from zero */
4472 /* XXX: Resetting dynrIdx breaks register allocation,
4473 * see #1489055, #1483693 (?), and #1445850! */
4476 /* and serially allocate registers */
4477 serialRegAssign (ebbs, count);
4480 debugLog ("ebbs after serialRegAssign:\n");
4481 dumpEbbsToDebug (ebbs, count);
4484 //pic16_freeAllRegs();
4486 /* if stack was extended then tell the user */
4489 /* werror(W_TOOMANY_SPILS,"stack", */
4490 /* _G.stackExtend,currFunc->name,""); */
4496 /* werror(W_TOOMANY_SPILS,"data space", */
4497 /* _G.dataExtend,currFunc->name,""); */
4501 /* after that create the register mask
4502 for each of the instruction */
4503 createRegMask (ebbs, count);
4505 /* redo that offsets for stacked automatic variables */
4506 redoStackOffsets ();
4508 if (options.dump_rassgn)
4509 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4511 // dumpLR(ebbs, count);
4513 /* now get back the chain */
4514 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4516 debugLog ("ebbs after optimizing:\n");
4517 dumpEbbsToDebug (ebbs, count);
4520 _inRegAllocator = 0;
4524 /* free up any _G.stackSpil locations allocated */
4525 applyToSet (_G.stackSpil, deallocStackSpil);
4527 setToNull ((void *) &_G.stackSpil);
4528 setToNull ((void *) &_G.spiltSet);
4529 /* mark all registers as free */
4530 pic16_freeAllRegs ();
4533 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");