1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
37 #define STRCASECMP strcasecmp
41 #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest)
43 void _debugf(char *f, int l, char *frm, ...);
45 #define NEWREG_DEBUG 0
49 /*-----------------------------------------------------------------*/
50 /* At this point we start getting processor specific although */
51 /* some routines are non-processor specific & can be reused when */
52 /* targetting other processors. The decision for this will have */
53 /* to be made on a routine by routine basis */
54 /* routines used to pack registers are most definitely not reusable */
55 /* since the pack the registers depending strictly on the MCU */
56 /*-----------------------------------------------------------------*/
58 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
59 extern void genpic16Code (iCode *);
69 bitVect *funcrUsed; /* registers used in a function */
75 /* Shared with gen.c */
76 int pic16_ptrRegReq; /* one byte pointer register required */
79 set *pic16_dynAllocRegs=NULL;
80 set *pic16_dynStackRegs=NULL;
81 set *pic16_dynProcessorRegs=NULL;
82 set *pic16_dynDirectRegs=NULL;
83 set *pic16_dynDirectBitRegs=NULL;
84 set *pic16_dynInternalRegs=NULL;
85 set *pic16_dynAccessRegs=NULL;
87 static hTab *dynDirectRegNames=NULL;
88 static hTab *dynAllocRegNames=NULL;
89 static hTab *dynProcRegNames=NULL;
90 static hTab *dynAccessRegNames=NULL;
91 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
93 extern set *sectNames;
95 set *pic16_rel_udata=NULL; /* relocatable uninitialized registers */
96 set *pic16_fix_udata=NULL; /* absolute uninitialized registers */
97 set *pic16_equ_data=NULL; /* registers used by equates */
98 set *pic16_int_regs=NULL; /* internal registers placed in access bank 0 to 0x7f */
99 set *pic16_acs_udata=NULL; /* access bank variables */
101 set *pic16_builtin_functions=NULL;
103 static int dynrIdx=0x00; //0x20; // starting temporary register rIdx
104 static int rDirectIdx=0;
106 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
108 int pic16_Gstack_base_addr=0; /* The starting address of registers that
109 * are used to pass and return parameters */
112 int _inRegAllocator=0; /* flag that marks whther allocReg happens while
113 * inside the register allocator function */
116 static void spillThis (symbol *);
117 int pic16_ralloc_debug = 0;
118 static FILE *debugF = NULL;
119 /*-----------------------------------------------------------------*/
120 /* debugLog - open a file for debugging information */
121 /*-----------------------------------------------------------------*/
122 //static void debugLog(char *inst,char *fmt, ...)
124 debugLog (char *fmt,...)
126 static int append = 0; // First time through, open the file without append.
129 //char *bufferP=buffer;
132 if (!pic16_ralloc_debug || !dstFileName)
138 /* create the file name */
139 strcpy (buffer, dstFileName);
140 strcat (buffer, ".d");
142 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
144 werror (E_FILE_OPEN_ERR, buffer);
147 append = 1; // Next time debubLog is called, we'll append the debug info
153 vsprintf (buffer, fmt, ap);
155 fprintf (debugF, "%s", buffer);
157 while (isspace(*bufferP)) bufferP++;
159 if (bufferP && *bufferP)
160 lineCurr = (lineCurr ?
161 connectLine(lineCurr,newLineNode(lb)) :
162 (lineHead = newLineNode(lb)));
163 lineCurr->isInline = _G.inLine;
164 lineCurr->isDebug = _G.debugLine;
173 if(!pic16_ralloc_debug)return;
176 fputc ('\n', debugF);
178 /*-----------------------------------------------------------------*/
179 /* debugLogClose - closes the debug log file (if opened) */
180 /*-----------------------------------------------------------------*/
190 #define AOP(op) op->aop
193 debugAopGet (char *str, operand * op)
195 if(!pic16_ralloc_debug)return NULL;
200 printOperand (op, debugF);
207 pic16_decodeOp (unsigned int op)
209 if (op < 128 && op > ' ') {
210 buffer[0] = (op & 0xff);
216 case IDENTIFIER: return "IDENTIFIER";
217 case TYPE_NAME: return "TYPE_NAME";
218 case CONSTANT: return "CONSTANT";
219 case STRING_LITERAL: return "STRING_LITERAL";
220 case SIZEOF: return "SIZEOF";
221 case PTR_OP: return "PTR_OP";
222 case INC_OP: return "INC_OP";
223 case DEC_OP: return "DEC_OP";
224 case LEFT_OP: return "LEFT_OP";
225 case RIGHT_OP: return "RIGHT_OP";
226 case LE_OP: return "LE_OP";
227 case GE_OP: return "GE_OP";
228 case EQ_OP: return "EQ_OP";
229 case NE_OP: return "NE_OP";
230 case AND_OP: return "AND_OP";
231 case OR_OP: return "OR_OP";
232 case MUL_ASSIGN: return "MUL_ASSIGN";
233 case DIV_ASSIGN: return "DIV_ASSIGN";
234 case MOD_ASSIGN: return "MOD_ASSIGN";
235 case ADD_ASSIGN: return "ADD_ASSIGN";
236 case SUB_ASSIGN: return "SUB_ASSIGN";
237 case LEFT_ASSIGN: return "LEFT_ASSIGN";
238 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
239 case AND_ASSIGN: return "AND_ASSIGN";
240 case XOR_ASSIGN: return "XOR_ASSIGN";
241 case OR_ASSIGN: return "OR_ASSIGN";
242 case TYPEDEF: return "TYPEDEF";
243 case EXTERN: return "EXTERN";
244 case STATIC: return "STATIC";
245 case AUTO: return "AUTO";
246 case REGISTER: return "REGISTER";
247 case CODE: return "CODE";
248 case EEPROM: return "EEPROM";
249 case INTERRUPT: return "INTERRUPT";
250 case SFR: return "SFR";
251 case AT: return "AT";
252 case SBIT: return "SBIT";
253 case REENTRANT: return "REENTRANT";
254 case USING: return "USING";
255 case XDATA: return "XDATA";
256 case DATA: return "DATA";
257 case IDATA: return "IDATA";
258 case PDATA: return "PDATA";
259 case VAR_ARGS: return "VAR_ARGS";
260 case CRITICAL: return "CRITICAL";
261 case NONBANKED: return "NONBANKED";
262 case BANKED: return "BANKED";
263 case CHAR: return "CHAR";
264 case SHORT: return "SHORT";
265 case INT: return "INT";
266 case LONG: return "LONG";
267 case SIGNED: return "SIGNED";
268 case UNSIGNED: return "UNSIGNED";
269 case FLOAT: return "FLOAT";
270 case DOUBLE: return "DOUBLE";
271 case CONST: return "CONST";
272 case VOLATILE: return "VOLATILE";
273 case VOID: return "VOID";
274 case BIT: return "BIT";
275 case STRUCT: return "STRUCT";
276 case UNION: return "UNION";
277 case ENUM: return "ENUM";
278 case ELIPSIS: return "ELIPSIS";
279 case RANGE: return "RANGE";
280 case FAR: return "FAR";
281 case CASE: return "CASE";
282 case DEFAULT: return "DEFAULT";
283 case IF: return "IF";
284 case ELSE: return "ELSE";
285 case SWITCH: return "SWITCH";
286 case WHILE: return "WHILE";
287 case DO: return "DO";
288 case FOR: return "FOR";
289 case GOTO: return "GOTO";
290 case CONTINUE: return "CONTINUE";
291 case BREAK: return "BREAK";
292 case RETURN: return "RETURN";
293 case INLINEASM: return "INLINEASM";
294 case IFX: return "IFX";
295 case ADDRESS_OF: return "ADDRESS_OF";
296 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
297 case SPIL: return "SPIL";
298 case UNSPIL: return "UNSPIL";
299 case GETHBIT: return "GETHBIT";
300 case BITWISEAND: return "BITWISEAND";
301 case UNARYMINUS: return "UNARYMINUS";
302 case IPUSH: return "IPUSH";
303 case IPOP: return "IPOP";
304 case PCALL: return "PCALL";
305 case ENDFUNCTION: return "ENDFUNCTION";
306 case JUMPTABLE: return "JUMPTABLE";
307 case RRC: return "RRC";
308 case RLC: return "RLC";
309 case CAST: return "CAST";
310 case CALL: return "CALL";
311 case PARAM: return "PARAM ";
312 case NULLOP: return "NULLOP";
313 case BLOCK: return "BLOCK";
314 case LABEL: return "LABEL";
315 case RECEIVE: return "RECEIVE";
316 case SEND: return "SEND";
318 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
322 /*-----------------------------------------------------------------*/
323 /*-----------------------------------------------------------------*/
325 debugLogRegType (short type)
327 if(!pic16_ralloc_debug)return NULL;
329 case REG_GPR: return "REG_GPR";
330 case REG_PTR: return "REG_PTR";
331 case REG_CND: return "REG_CND";
333 sprintf (buffer, "unknown reg type %d", type);
338 /*-----------------------------------------------------------------*/
339 /*-----------------------------------------------------------------*/
340 static int regname2key(char const *name)
349 key += (*name++) + 1;
353 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
357 /*-----------------------------------------------------------------*/
358 /* newReg - allocate and init memory for a new register */
359 /*-----------------------------------------------------------------*/
360 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
365 dReg = Safe_calloc(1,sizeof(regs));
367 dReg->pc_type = pc_type;
370 dReg->name = Safe_strdup(name);
372 sprintf(buffer,"r0x%02X", dReg->rIdx);
375 dReg->name = Safe_strdup(buffer);
383 if(type == REG_SFR) {
385 dReg->address = rIdx;
386 dReg->accessBank = 1;
390 dReg->accessBank = 0;
394 fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
398 dReg->reg_alias = NULL;
399 dReg->reglives.usedpFlows = newSet();
400 dReg->reglives.assignedpFlows = newSet();
403 if(!(type == REG_SFR && alias == 0x80))
404 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
409 /*-----------------------------------------------------------------*/
410 /* regWithIdx - Search through a set of registers that matches idx */
411 /*-----------------------------------------------------------------*/
413 regWithIdx (set *dRegs, int idx, unsigned fixed)
417 for (dReg = setFirstItem(dRegs) ; dReg ;
418 dReg = setNextItem(dRegs)) {
420 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
428 /*-----------------------------------------------------------------*/
429 /* regFindFree - Search for a free register in a set of registers */
430 /*-----------------------------------------------------------------*/
432 regFindFree (set *dRegs)
436 for (dReg = setFirstItem(dRegs) ; dReg ;
437 dReg = setNextItem(dRegs)) {
439 // fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
440 // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
449 /*-----------------------------------------------------------------*/
450 /* pic16_initStack - allocate registers for a pseudo stack */
451 /*-----------------------------------------------------------------*/
452 void pic16_initStack(int base_address, int size)
457 pic16_Gstack_base_addr = base_address;
458 //fprintf(stderr,"initStack");
460 for(i = 0; i<size; i++)
461 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
464 /*-----------------------------------------------------------------*
465 *-----------------------------------------------------------------*/
467 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
469 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
471 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
473 reg->wasUsed = 0; // we do not know if they are going to be used at all
474 reg->accessBank = 1; // implicit add access Bank
476 hTabAddItem(&dynProcRegNames, regname2key(reg->name), reg);
478 return addSet(&pic16_dynProcessorRegs, reg);
481 /*-----------------------------------------------------------------*
482 *-----------------------------------------------------------------*/
485 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
487 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
489 // fprintf(stderr,"%s:%d: %s %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
493 return addSet(&pic16_dynInternalRegs,reg);
500 /*-----------------------------------------------------------------*/
501 /* allocReg - allocates register of given type */
502 /*-----------------------------------------------------------------*/
504 allocReg (short type)
508 #define MAX_P16_NREGS 6
512 if(dynrIdx > pic16_nRegs)
516 /* try to reuse some unused registers */
517 reg = regFindFree( pic16_dynAllocRegs );
520 // fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
524 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
525 // fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx);
528 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) {
529 // debugf("allocating more registers than available\n", 0);
534 // addSet(&pic16_dynAllocRegs, reg);
537 addSet(&pic16_dynAllocRegs, reg);
538 hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg);
542 debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1);
545 fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
546 __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
549 reg->accessBank = 1; /* this is a temporary register alloc in accessBank */
550 reg->isLocal = 1; /* this is a local frame register */
555 // fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
556 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
559 return (reg); // addSet(&pic16_dynAllocRegs,reg);
564 /*-----------------------------------------------------------------*/
565 /* pic16_dirregWithName - search for register by name */
566 /*-----------------------------------------------------------------*/
568 pic16_dirregWithName (char *name)
576 /* hash the name to get a key */
578 hkey = regname2key(name);
580 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
582 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
586 if(STRCASECMP(reg->name, name) == 0) {
587 // fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey);
591 reg = hTabNextItemWK (dynDirectRegNames);
595 return NULL; // name wasn't found in the hash table
598 /*-----------------------------------------------------------------*/
599 /* pic16_allocregWithName - search for register by name */
600 /*-----------------------------------------------------------------*/
602 pic16_allocregWithName (char *name)
610 /* hash the name to get a key */
612 hkey = regname2key(name);
614 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
616 reg = hTabFirstItemWK(dynAllocRegNames, hkey);
620 if(STRCASECMP(reg->name, name) == 0) {
624 reg = hTabNextItemWK (dynAllocRegNames);
628 return NULL; // name wasn't found in the hash table
633 /*-----------------------------------------------------------------*/
634 /* pic16_procregWithName - search for register by name */
635 /*-----------------------------------------------------------------*/
637 pic16_procregWithName (char *name)
645 /* hash the name to get a key */
647 hkey = regname2key(name);
649 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
651 reg = hTabFirstItemWK(dynProcRegNames, hkey);
655 if(STRCASECMP(reg->name, name) == 0) {
659 reg = hTabNextItemWK (dynProcRegNames);
663 return NULL; // name wasn't found in the hash table
667 /*-----------------------------------------------------------------*/
668 /* pic16_accessregWithName - search for register by name */
669 /*-----------------------------------------------------------------*/
671 pic16_accessregWithName (char *name)
679 /* hash the name to get a key */
681 hkey = regname2key(name);
683 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
685 reg = hTabFirstItemWK(dynAccessRegNames, hkey);
689 if(STRCASECMP(reg->name, name) == 0) {
693 reg = hTabNextItemWK (dynAccessRegNames);
697 return NULL; // name wasn't found in the hash table
701 regs *pic16_regWithName(char *name)
705 reg = pic16_dirregWithName( name );
708 reg = pic16_procregWithName( name );
711 reg = pic16_allocregWithName( name );
714 reg = pic16_accessregWithName( name );
721 /*-----------------------------------------------------------------*/
722 /* pic16_allocDirReg - allocates register of given type */
723 /*-----------------------------------------------------------------*/
725 pic16_allocDirReg (operand *op )
731 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
732 // fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
736 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
739 if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
741 if(pic16_debug_verbose)
743 fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
744 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);
750 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
751 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
754 if(pic16_debug_verbose) {
755 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d regparm: %d isparm: %d\n",
756 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
757 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
758 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
759 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
760 IN_STACK( OP_SYM_ETYPE(op)),
761 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom,
762 IS_REGPARM(OP_SYM_ETYPE(op)),
765 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
766 OP_SYMBOL(op)->name);
774 if (IS_CODE ( OP_SYM_ETYPE(op)) ) {
775 // fprintf(stderr, "%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
779 if(IS_ITEMP(op))return NULL;
781 debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
782 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
785 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
786 debugLog(" %d const char\n",__LINE__);
787 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
788 // fprintf(stderr, " %d const char\n",__LINE__);
789 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
793 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
794 if (IS_CODE ( OP_SYM_ETYPE(op)) )
795 debugLog(" %d code space\n",__LINE__);
797 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
798 debugLog(" %d integral\n",__LINE__);
800 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
801 debugLog(" %d literal\n",__LINE__);
803 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
804 debugLog(" %d specifier\n",__LINE__);
806 debugAopGet(NULL, op);
810 reg = pic16_dirregWithName(name);
814 int regtype = REG_GPR;
816 /* if this is at an absolute address, then get the address. */
817 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
818 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
819 // fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
822 /* Register wasn't found in hash, so let's create
823 * a new one and put it in the hash table AND in the
824 * dynDirectRegNames set */
825 if(IS_CODE(OP_SYM_ETYPE(op)) || IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
826 debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
832 if(OP_SYMBOL(op)->onStack) {
833 fprintf(stderr, "%s:%d onStack %s offset: %d\n", __FILE__, __LINE__,
834 OP_SYMBOL(op)->name, OP_SYMBOL(op)->stack);
838 if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
839 || !IN_FARSPACE(SPEC_OCLS( OP_SYM_ETYPE(op))) ) {
842 if(pic16_debug_verbose)
844 fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d eeprom: %d\n",
845 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
846 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
847 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
848 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
849 IN_STACK( OP_SYM_ETYPE(op)),
850 SPEC_OCLS(OP_SYM_ETYPE(op)) == eeprom);
852 fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,
853 OP_SYMBOL(op)->name);
858 reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
859 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
861 if( SPEC_SCLS( OP_SYM_ETYPE( op ) ) == S_REGISTER ) {
862 fprintf(stderr, "%s:%d symbol %s is declared as register\n", __FILE__, __LINE__,
866 checkAddReg(&pic16_dynAccessRegs, reg);
867 hTabAddItem(&dynAccessRegNames, regname2key(name), reg);
873 // if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
874 // fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
875 // reg->type = REG_SFR;
878 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
879 // fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
880 addSet(&pic16_dynDirectBitRegs, reg);
883 // fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
884 // addSet(&pic16_dynDirectRegs, reg);
887 if(!(IS_STATIC(OP_SYM_ETYPE(op))
888 && OP_SYMBOL(op)->ival
891 checkAddReg(&pic16_dynDirectRegs, reg);
895 // debugLog (" -- %s is declared at address 0x30000x\n",name);
896 return (reg); /* This was NULL before, but since we found it
897 * why not just return it?! */
900 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
902 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
904 /* work around for user defined registers in access bank */
905 if((reg->address>= 0x00 && reg->address < 0x80)
906 || (reg->address >= 0xf80 && reg->address <= 0xfff))
909 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
915 /*-----------------------------------------------------------------*/
916 /* pic16_allocRegByName - allocates register of given type */
917 /*-----------------------------------------------------------------*/
919 pic16_allocRegByName (char *name, int size, operand *op)
925 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
929 /* First, search the hash table to see if there is a register with this name */
930 reg = pic16_dirregWithName(name);
934 /* Register wasn't found in hash, so let's create
935 * a new one and put it in the hash table AND in the
936 * dynDirectRegNames set */
938 fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
940 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
942 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
943 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
945 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
946 addSet(&pic16_dynDirectRegs, reg);
952 /*-----------------------------------------------------------------*/
953 /* RegWithIdx - returns pointer to register with index number */
954 /*-----------------------------------------------------------------*/
955 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
960 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
961 // fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
966 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
968 debugLog ("Found a Dynamic Register!\n");
971 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
972 debugLog ("Found a Direct Register!\n");
978 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
979 debugLog ("Found a Stack Register!\n");
984 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, 1)) != NULL ) {
985 debugLog ("Found a Processor Register!\n");
999 /*-----------------------------------------------------------------*/
1000 /* pic16_regWithIdx - returns pointer to register with index number*/
1001 /*-----------------------------------------------------------------*/
1003 pic16_regWithIdx (int idx)
1007 if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1010 if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1014 if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
1021 /*-----------------------------------------------------------------*/
1022 /* pic16_regWithIdx - returns pointer to register with index number */
1023 /*-----------------------------------------------------------------*/
1025 pic16_allocWithIdx (int idx)
1030 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1031 // fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1033 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
1035 debugLog ("Found a Dynamic Register!\n");
1036 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
1037 debugLog ("Found a Stack Register!\n");
1038 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,1)) != NULL ) {
1039 debugLog ("Found a Processor Register!\n");
1040 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
1041 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
1042 debugLog ("Found an Internal Register!\n");
1045 debugLog ("Dynamic Register not found\n");
1048 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1049 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1050 "regWithIdx not found");
1060 /*-----------------------------------------------------------------*/
1061 /*-----------------------------------------------------------------*/
1063 pic16_findFreeReg(short type)
1070 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
1072 return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
1076 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
1088 /*-----------------------------------------------------------------*/
1089 /* freeReg - frees a register */
1090 /*-----------------------------------------------------------------*/
1092 freeReg (regs * reg)
1094 debugLog ("%s\n", __FUNCTION__);
1095 // fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
1100 /*-----------------------------------------------------------------*/
1101 /* nFreeRegs - returns number of free registers */
1102 /*-----------------------------------------------------------------*/
1104 nFreeRegs (int type)
1110 /* although I fixed the register allocation/freeing scheme
1111 * the for loop below doesn't give valid results. I do not
1112 * know why yet. -- VR 10-Jan-2003 */
1117 /* dynamically allocate as many as we need and worry about
1118 * fitting them into a PIC later */
1120 debugLog ("%s\n", __FUNCTION__);
1122 for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
1123 if((reg->type == type) && reg->isFree)nfr++;
1125 fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
1129 /*-----------------------------------------------------------------*/
1130 /* nfreeRegsType - free registers with type */
1131 /*-----------------------------------------------------------------*/
1133 nfreeRegsType (int type)
1136 debugLog ("%s\n", __FUNCTION__);
1137 if (type == REG_PTR)
1139 if ((nfr = nFreeRegs (type)) == 0)
1140 return nFreeRegs (REG_GPR);
1143 return nFreeRegs (type);
1146 static void writeSetUsedRegs(FILE *of, set *dRegs)
1151 for (dReg = setFirstItem(dRegs) ; dReg ;
1152 dReg = setNextItem(dRegs)) {
1155 fprintf (of, "\t%s\n",dReg->name);
1161 extern void pic16_groupRegistersInSection(set *regset);
1163 extern void pic16_dump_equates(FILE *of, set *equs);
1164 extern void pic16_dump_access(FILE *of, set *section);
1165 //extern void pic16_dump_map(void);
1166 extern void pic16_dump_usection(FILE *of, set *section, int fix);
1167 extern void pic16_dump_isection(FILE *of, set *section, int fix);
1168 extern void pic16_dump_int_registers(FILE *of, set *section);
1169 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
1171 extern void pic16_dump_gsection(FILE *of, set *sections);
1173 static void packBits(set *bregs)
1177 regs *bitfield=NULL;
1178 regs *relocbitfield=NULL;
1184 for (regset = bregs ; regset ;
1185 regset = regset->next) {
1187 breg = regset->item;
1188 breg->isBitField = 1;
1189 //fprintf(stderr,"bit reg: %s\n",breg->name);
1192 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1194 bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1195 breg->rIdx = breg->address & 7;
1196 breg->address >>= 3;
1199 sprintf (buffer, "fbitfield%02x", breg->address);
1200 //fprintf(stderr,"new bit field\n");
1201 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1202 bitfield->isBitField = 1;
1203 bitfield->isFixed = 1;
1204 bitfield->address = breg->address;
1205 addSet(&pic16_dynDirectRegs,bitfield);
1206 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1208 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1211 breg->reg_alias = bitfield;
1215 if(!relocbitfield || bit_no >7) {
1218 sprintf (buffer, "bitfield%d", byte_no);
1219 //fprintf(stderr,"new relocatable bit field\n");
1220 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1221 relocbitfield->isBitField = 1;
1222 addSet(&pic16_dynDirectRegs,relocbitfield);
1223 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1227 breg->reg_alias = relocbitfield;
1228 breg->address = rDirectIdx; /* byte_no; */
1229 breg->rIdx = bit_no++;
1235 void pic16_writeUsedRegs(FILE *of)
1237 packBits(pic16_dynDirectBitRegs);
1239 // fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__);
1240 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1242 // fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__);
1243 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1245 // fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__);
1246 pic16_groupRegistersInSection(pic16_dynStackRegs);
1248 // fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__);
1249 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1251 // fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__);
1252 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1254 // fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__);
1255 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1257 // fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__);
1258 pic16_groupRegistersInSection(pic16_dynAccessRegs);
1261 pic16_dump_equates(of, pic16_equ_data);
1263 // pic16_dump_esection(of, pic16_rel_eedata, 0);
1264 // pic16_dump_esection(of, pic16_fix_eedata, 0);
1266 /* dump access bank symbols */
1267 pic16_dump_access(of, pic16_acs_udata);
1269 /* dump initialised data */
1270 pic16_dump_isection(of, rel_idataSymSet, 0);
1271 pic16_dump_isection(of, fix_idataSymSet, 1);
1273 /* dump internal registers */
1274 pic16_dump_int_registers(of, pic16_int_regs);
1276 /* dump generic section variables */
1277 pic16_dump_gsection(of, sectNames);
1279 /* dump other variables */
1280 pic16_dump_usection(of, pic16_rel_udata, 0);
1281 pic16_dump_usection(of, pic16_fix_udata, 1);
1286 /*-----------------------------------------------------------------*/
1287 /* computeSpillable - given a point find the spillable live ranges */
1288 /*-----------------------------------------------------------------*/
1290 computeSpillable (iCode * ic)
1294 debugLog ("%s\n", __FUNCTION__);
1295 /* spillable live ranges are those that are live at this
1296 point . the following categories need to be subtracted
1298 a) - those that are already spilt
1299 b) - if being used by this one
1300 c) - defined by this one */
1302 spillable = bitVectCopy (ic->rlive);
1304 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1306 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1307 bitVectUnSetBit (spillable, ic->defKey);
1308 spillable = bitVectIntersect (spillable, _G.regAssigned);
1313 /*-----------------------------------------------------------------*/
1314 /* noSpilLoc - return true if a variable has no spil location */
1315 /*-----------------------------------------------------------------*/
1317 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1319 debugLog ("%s\n", __FUNCTION__);
1320 return (sym->usl.spillLoc ? 0 : 1);
1323 /*-----------------------------------------------------------------*/
1324 /* hasSpilLoc - will return 1 if the symbol has spil location */
1325 /*-----------------------------------------------------------------*/
1327 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1329 debugLog ("%s\n", __FUNCTION__);
1330 return (sym->usl.spillLoc ? 1 : 0);
1333 /*-----------------------------------------------------------------*/
1334 /* directSpilLoc - will return 1 if the splilocation is in direct */
1335 /*-----------------------------------------------------------------*/
1337 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1339 debugLog ("%s\n", __FUNCTION__);
1340 if (sym->usl.spillLoc &&
1341 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1347 /*-----------------------------------------------------------------*/
1348 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1349 /* but is not used as a pointer */
1350 /*-----------------------------------------------------------------*/
1352 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1354 debugLog ("%s\n", __FUNCTION__);
1355 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1358 /*-----------------------------------------------------------------*/
1359 /* rematable - will return 1 if the remat flag is set */
1360 /*-----------------------------------------------------------------*/
1362 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1364 debugLog ("%s\n", __FUNCTION__);
1368 /*-----------------------------------------------------------------*/
1369 /* notUsedInRemaining - not used or defined in remain of the block */
1370 /*-----------------------------------------------------------------*/
1372 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1374 debugLog ("%s\n", __FUNCTION__);
1375 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1376 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1379 /*-----------------------------------------------------------------*/
1380 /* allLRs - return true for all */
1381 /*-----------------------------------------------------------------*/
1383 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1385 debugLog ("%s\n", __FUNCTION__);
1389 /*-----------------------------------------------------------------*/
1390 /* liveRangesWith - applies function to a given set of live range */
1391 /*-----------------------------------------------------------------*/
1393 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1394 eBBlock * ebp, iCode * ic)
1399 debugLog ("%s\n", __FUNCTION__);
1400 if (!lrs || !lrs->size)
1403 for (i = 1; i < lrs->size; i++)
1406 if (!bitVectBitValue (lrs, i))
1409 /* if we don't find it in the live range
1410 hash table we are in serious trouble */
1411 if (!(sym = hTabItemWithKey (liveRanges, i)))
1413 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1414 "liveRangesWith could not find liveRange");
1418 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1419 addSetHead (&rset, sym);
1426 /*-----------------------------------------------------------------*/
1427 /* leastUsedLR - given a set determines which is the least used */
1428 /*-----------------------------------------------------------------*/
1430 leastUsedLR (set * sset)
1432 symbol *sym = NULL, *lsym = NULL;
1434 debugLog ("%s\n", __FUNCTION__);
1435 sym = lsym = setFirstItem (sset);
1440 for (; lsym; lsym = setNextItem (sset))
1443 /* if usage is the same then prefer
1444 the spill the smaller of the two */
1445 if (lsym->used == sym->used)
1446 if (getSize (lsym->type) < getSize (sym->type))
1450 if (lsym->used < sym->used)
1455 setToNull ((void *) &sset);
1460 /*-----------------------------------------------------------------*/
1461 /* noOverLap - will iterate through the list looking for over lap */
1462 /*-----------------------------------------------------------------*/
1464 noOverLap (set * itmpStack, symbol * fsym)
1467 debugLog ("%s\n", __FUNCTION__);
1470 for (sym = setFirstItem (itmpStack); sym;
1471 sym = setNextItem (itmpStack))
1473 if (sym->liveTo > fsym->liveFrom)
1481 /*-----------------------------------------------------------------*/
1482 /* isFree - will return 1 if the a free spil location is found */
1483 /*-----------------------------------------------------------------*/
1488 V_ARG (symbol **, sloc);
1489 V_ARG (symbol *, fsym);
1491 debugLog ("%s\n", __FUNCTION__);
1492 /* if already found */
1496 /* if it is free && and the itmp assigned to
1497 this does not have any overlapping live ranges
1498 with the one currently being assigned and
1499 the size can be accomodated */
1501 noOverLap (sym->usl.itmpStack, fsym) &&
1502 getSize (sym->type) >= getSize (fsym->type))
1511 /*-----------------------------------------------------------------*/
1512 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1513 /*-----------------------------------------------------------------*/
1515 spillLRWithPtrReg (symbol * forSym)
1521 debugLog ("%s\n", __FUNCTION__);
1522 if (!_G.regAssigned ||
1523 bitVectIsZero (_G.regAssigned))
1526 r0 = pic16_regWithIdx (R0_IDX);
1527 r1 = pic16_regWithIdx (R1_IDX);
1529 /* for all live ranges */
1530 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1531 lrsym = hTabNextItem (liveRanges, &k))
1535 /* if no registers assigned to it or
1537 /* if it does not overlap with this then
1538 not need to spill it */
1540 if (lrsym->isspilt || !lrsym->nRegs ||
1541 (lrsym->liveTo < forSym->liveFrom))
1544 /* go thru the registers : if it is either
1545 r0 or r1 then spil it */
1546 for (j = 0; j < lrsym->nRegs; j++)
1547 if (lrsym->regs[j] == r0 ||
1548 lrsym->regs[j] == r1)
1557 /*-----------------------------------------------------------------*/
1558 /* createStackSpil - create a location on the stack to spil */
1559 /*-----------------------------------------------------------------*/
1561 createStackSpil (symbol * sym)
1563 symbol *sloc = NULL;
1564 int useXstack, model, noOverlay;
1566 char slocBuffer[30];
1567 debugLog ("%s\n", __FUNCTION__);
1569 /* first go try and find a free one that is already
1570 existing on the stack */
1571 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1573 /* found a free one : just update & return */
1574 sym->usl.spillLoc = sloc;
1577 addSetHead (&sloc->usl.itmpStack, sym);
1581 /* could not then have to create one , this is the hard part
1582 we need to allocate this on the stack : this is really a
1583 hack!! but cannot think of anything better at this time */
1585 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1587 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1588 __FILE__, __LINE__);
1592 sloc = newiTemp (slocBuffer);
1594 /* set the type to the spilling symbol */
1595 sloc->type = copyLinkChain (sym->type);
1596 sloc->etype = getSpec (sloc->type);
1597 SPEC_SCLS (sloc->etype) = S_DATA;
1598 SPEC_EXTR (sloc->etype) = 0;
1599 SPEC_STAT (sloc->etype) = 0;
1601 /* we don't allow it to be allocated`
1602 onto the external stack since : so we
1603 temporarily turn it off ; we also
1604 turn off memory model to prevent
1605 the spil from going to the external storage
1606 and turn off overlaying
1609 useXstack = options.useXstack;
1610 model = options.model;
1611 noOverlay = options.noOverlay;
1612 options.noOverlay = 1;
1613 options.model = options.useXstack = 0;
1617 options.useXstack = useXstack;
1618 options.model = model;
1619 options.noOverlay = noOverlay;
1620 sloc->isref = 1; /* to prevent compiler warning */
1622 /* if it is on the stack then update the stack */
1623 if (IN_STACK (sloc->etype))
1625 currFunc->stack += getSize (sloc->type);
1626 _G.stackExtend += getSize (sloc->type);
1629 _G.dataExtend += getSize (sloc->type);
1631 /* add it to the _G.stackSpil set */
1632 addSetHead (&_G.stackSpil, sloc);
1633 sym->usl.spillLoc = sloc;
1636 /* add it to the set of itempStack set
1637 of the spill location */
1638 addSetHead (&sloc->usl.itmpStack, sym);
1642 /*-----------------------------------------------------------------*/
1643 /* isSpiltOnStack - returns true if the spil location is on stack */
1644 /*-----------------------------------------------------------------*/
1646 isSpiltOnStack (symbol * sym)
1650 debugLog ("%s\n", __FUNCTION__);
1657 /* if (sym->_G.stackSpil) */
1660 if (!sym->usl.spillLoc)
1663 etype = getSpec (sym->usl.spillLoc->type);
1664 if (IN_STACK (etype))
1670 /*-----------------------------------------------------------------*/
1671 /* spillThis - spils a specific operand */
1672 /*-----------------------------------------------------------------*/
1674 spillThis (symbol * sym)
1677 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1679 /* if this is rematerializable or has a spillLocation
1680 we are okay, else we need to create a spillLocation
1682 if (!(sym->remat || sym->usl.spillLoc))
1683 createStackSpil (sym);
1686 /* mark it has spilt & put it in the spilt set */
1688 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1690 bitVectUnSetBit (_G.regAssigned, sym->key);
1692 for (i = 0; i < sym->nRegs; i++)
1696 freeReg (sym->regs[i]);
1697 sym->regs[i] = NULL;
1700 /* if spilt on stack then free up r0 & r1
1701 if they could have been assigned to some
1703 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1706 spillLRWithPtrReg (sym);
1709 if (sym->usl.spillLoc && !sym->remat)
1710 sym->usl.spillLoc->allocreq = 1;
1714 /*-----------------------------------------------------------------*/
1715 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1716 /*-----------------------------------------------------------------*/
1718 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1720 bitVect *lrcs = NULL;
1724 debugLog ("%s\n", __FUNCTION__);
1725 /* get the spillable live ranges */
1726 lrcs = computeSpillable (ic);
1728 /* get all live ranges that are rematerizable */
1729 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1732 /* return the least used of these */
1733 return leastUsedLR (selectS);
1736 /* get live ranges with spillLocations in direct space */
1737 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1739 sym = leastUsedLR (selectS);
1740 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1741 sym->usl.spillLoc->rname :
1742 sym->usl.spillLoc->name));
1744 /* mark it as allocation required */
1745 sym->usl.spillLoc->allocreq = 1;
1749 /* if the symbol is local to the block then */
1750 if (forSym->liveTo < ebp->lSeq)
1753 /* check if there are any live ranges allocated
1754 to registers that are not used in this block */
1755 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1757 sym = leastUsedLR (selectS);
1758 /* if this is not rematerializable */
1767 /* check if there are any live ranges that not
1768 used in the remainder of the block */
1769 if (!_G.blockSpil &&
1770 !isiCodeInFunctionCall (ic) &&
1771 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1773 sym = leastUsedLR (selectS);
1776 sym->remainSpil = 1;
1783 /* find live ranges with spillocation && not used as pointers */
1784 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1787 sym = leastUsedLR (selectS);
1788 /* mark this as allocation required */
1789 sym->usl.spillLoc->allocreq = 1;
1793 /* find live ranges with spillocation */
1794 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1797 sym = leastUsedLR (selectS);
1798 sym->usl.spillLoc->allocreq = 1;
1802 /* couldn't find then we need to create a spil
1803 location on the stack , for which one? the least
1805 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1808 /* return a created spil location */
1809 sym = createStackSpil (leastUsedLR (selectS));
1810 sym->usl.spillLoc->allocreq = 1;
1814 /* this is an extreme situation we will spill
1815 this one : happens very rarely but it does happen */
1821 /*-----------------------------------------------------------------*/
1822 /* spilSomething - spil some variable & mark registers as free */
1823 /*-----------------------------------------------------------------*/
1825 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1830 debugLog ("%s\n", __FUNCTION__);
1831 /* get something we can spil */
1832 ssym = selectSpil (ic, ebp, forSym);
1834 /* mark it as spilt */
1836 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1838 /* mark it as not register assigned &
1839 take it away from the set */
1840 bitVectUnSetBit (_G.regAssigned, ssym->key);
1842 /* mark the registers as free */
1843 for (i = 0; i < ssym->nRegs; i++)
1845 freeReg (ssym->regs[i]);
1847 /* if spilt on stack then free up r0 & r1
1848 if they could have been assigned to as gprs */
1849 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1852 spillLRWithPtrReg (ssym);
1855 /* if this was a block level spil then insert push & pop
1856 at the start & end of block respectively */
1857 if (ssym->blockSpil)
1859 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1860 /* add push to the start of the block */
1861 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1862 ebp->sch->next : ebp->sch));
1863 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1864 /* add pop to the end of the block */
1865 addiCodeToeBBlock (ebp, nic, NULL);
1868 /* if spilt because not used in the remainder of the
1869 block then add a push before this instruction and
1870 a pop at the end of the block */
1871 if (ssym->remainSpil)
1874 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1875 /* add push just before this instruction */
1876 addiCodeToeBBlock (ebp, nic, ic);
1878 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1879 /* add pop to the end of the block */
1880 addiCodeToeBBlock (ebp, nic, NULL);
1889 /*-----------------------------------------------------------------*/
1890 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1891 /*-----------------------------------------------------------------*/
1893 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1898 debugLog ("%s\n", __FUNCTION__);
1900 /* try for a ptr type */
1901 if ((reg = allocReg (REG_PTR)))
1904 /* try for gpr type */
1905 if ((reg = allocReg (REG_GPR)))
1908 /* we have to spil */
1909 if (!spilSomething (ic, ebp, sym))
1912 /* make sure partially assigned registers aren't reused */
1913 for (j=0; j<=sym->nRegs; j++)
1915 sym->regs[j]->isFree = 0;
1917 /* this looks like an infinite loop but
1918 in really selectSpil will abort */
1922 /*-----------------------------------------------------------------*/
1923 /* getRegGpr - will try for GPR if not spil */
1924 /*-----------------------------------------------------------------*/
1926 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1931 debugLog ("%s\n", __FUNCTION__);
1933 /* try for gpr type */
1934 if ((reg = allocReg (REG_GPR)))
1937 if (!pic16_ptrRegReq)
1938 if ((reg = allocReg (REG_PTR)))
1941 /* we have to spil */
1942 if (!spilSomething (ic, ebp, sym))
1945 /* make sure partially assigned registers aren't reused */
1946 for (j=0; j<=sym->nRegs; j++)
1948 sym->regs[j]->isFree = 0;
1950 /* this looks like an infinite loop but
1951 in really selectSpil will abort */
1955 /*-----------------------------------------------------------------*/
1956 /* symHasReg - symbol has a given register */
1957 /*-----------------------------------------------------------------*/
1959 symHasReg (symbol * sym, regs * reg)
1963 debugLog ("%s\n", __FUNCTION__);
1964 for (i = 0; i < sym->nRegs; i++)
1965 if (sym->regs[i] == reg)
1971 /*-----------------------------------------------------------------*/
1972 /* deassignLRs - check the live to and if they have registers & are */
1973 /* not spilt then free up the registers */
1974 /*-----------------------------------------------------------------*/
1976 deassignLRs (iCode * ic, eBBlock * ebp)
1982 debugLog ("%s\n", __FUNCTION__);
1983 for (sym = hTabFirstItem (liveRanges, &k); sym;
1984 sym = hTabNextItem (liveRanges, &k))
1987 symbol *psym = NULL;
1988 /* if it does not end here */
1989 if (sym->liveTo > ic->seq)
1992 /* if it was spilt on stack then we can
1993 mark the stack spil location as free */
1998 sym->usl.spillLoc->isFree = 1;
2004 if (!bitVectBitValue (_G.regAssigned, sym->key))
2007 /* special case for shifting: there is a case where shift count
2008 * can be allocated in the same register as the result, so do not
2009 * free right registers if same as result registers, cause genShiftLeft
2010 * will fail -- VR */
2011 if(ic->op == LEFT_OP)
2014 /* special case check if this is an IFX &
2015 the privious one was a pop and the
2016 previous one was not spilt then keep track
2018 if (ic->op == IFX && ic->prev &&
2019 ic->prev->op == IPOP &&
2020 !ic->prev->parmPush &&
2021 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2022 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2028 bitVectUnSetBit (_G.regAssigned, sym->key);
2030 /* if the result of this one needs registers
2031 and does not have it then assign it right
2033 if (IC_RESULT (ic) &&
2034 !(SKIP_IC2 (ic) || /* not a special icode */
2035 ic->op == JUMPTABLE ||
2040 POINTER_SET (ic)) &&
2041 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2042 result->liveTo > ic->seq && /* and will live beyond this */
2043 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2044 result->liveFrom == ic->seq && /* does not start before here */
2045 result->regType == sym->regType && /* same register types */
2046 result->nRegs && /* which needs registers */
2047 !result->isspilt && /* and does not already have them */
2049 !bitVectBitValue (_G.regAssigned, result->key) &&
2050 /* the number of free regs + number of regs in this LR
2051 can accomodate the what result Needs */
2052 ((nfreeRegsType (result->regType) +
2053 sym->nRegs) >= result->nRegs)
2057 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2059 result->regs[i] = sym->regs[i];
2061 result->regs[i] = getRegGpr (ic, ebp, result);
2063 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2067 /* free the remaining */
2068 for (; i < sym->nRegs; i++)
2072 if (!symHasReg (psym, sym->regs[i]))
2073 freeReg (sym->regs[i]);
2076 freeReg (sym->regs[i]);
2083 /*-----------------------------------------------------------------*/
2084 /* reassignLR - reassign this to registers */
2085 /*-----------------------------------------------------------------*/
2087 reassignLR (operand * op)
2089 symbol *sym = OP_SYMBOL (op);
2092 debugLog ("%s\n", __FUNCTION__);
2093 /* not spilt any more */
2094 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2095 bitVectUnSetBit (_G.spiltSet, sym->key);
2097 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2101 for (i = 0; i < sym->nRegs; i++)
2102 sym->regs[i]->isFree = 0;
2105 /*-----------------------------------------------------------------*/
2106 /* willCauseSpill - determines if allocating will cause a spill */
2107 /*-----------------------------------------------------------------*/
2109 willCauseSpill (int nr, int rt)
2111 debugLog ("%s\n", __FUNCTION__);
2112 /* first check if there are any avlb registers
2113 of te type required */
2116 /* special case for pointer type
2117 if pointer type not avlb then
2118 check for type gpr */
2119 if (nFreeRegs (rt) >= nr)
2121 if (nFreeRegs (REG_GPR) >= nr)
2126 if (pic16_ptrRegReq)
2128 if (nFreeRegs (rt) >= nr)
2133 if (nFreeRegs (REG_PTR) +
2134 nFreeRegs (REG_GPR) >= nr)
2139 debugLog (" ... yep it will (cause a spill)\n");
2140 /* it will cause a spil */
2144 /*-----------------------------------------------------------------*/
2145 /* positionRegs - the allocator can allocate same registers to res- */
2146 /* ult and operand, if this happens make sure they are in the same */
2147 /* position as the operand otherwise chaos results */
2148 /*-----------------------------------------------------------------*/
2150 positionRegs (symbol * result, symbol * opsym, int lineno)
2152 int count = min (result->nRegs, opsym->nRegs);
2153 int i, j = 0, shared = 0;
2155 debugLog ("%s\n", __FUNCTION__);
2156 /* if the result has been spilt then cannot share */
2161 /* first make sure that they actually share */
2162 for (i = 0; i < count; i++)
2164 for (j = 0; j < count; j++)
2166 if (result->regs[i] == opsym->regs[j] && i != j)
2176 regs *tmp = result->regs[i];
2177 result->regs[i] = result->regs[j];
2178 result->regs[j] = tmp;
2183 /*------------------------------------------------------------------*/
2184 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2185 /* it should either have registers or have beed spilled. Otherwise, */
2186 /* there was an uninitialized variable, so just spill this to get */
2187 /* the operand in a valid state. */
2188 /*------------------------------------------------------------------*/
2190 verifyRegsAssigned (operand *op, iCode * ic)
2195 if (!IS_ITEMP (op)) return;
2197 sym = OP_SYMBOL (op);
2198 if (sym->isspilt) return;
2199 if (!sym->nRegs) return;
2200 if (sym->regs[0]) return;
2202 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2203 sym->prereqv ? sym->prereqv->name : sym->name);
2208 /*-----------------------------------------------------------------*/
2209 /* serialRegAssign - serially allocate registers to the variables */
2210 /*-----------------------------------------------------------------*/
2212 serialRegAssign (eBBlock ** ebbs, int count)
2217 debugLog ("%s\n", __FUNCTION__);
2218 /* for all blocks */
2219 for (i = 0; i < count; i++)
2221 if (ebbs[i]->noPath &&
2222 (ebbs[i]->entryLabel != entryLabel &&
2223 ebbs[i]->entryLabel != returnLabel))
2226 /* of all instructions do */
2227 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2230 debugLog (" op: %s\n", pic16_decodeOp (ic->op));
2232 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2233 pic16_allocDirReg(IC_RESULT(ic));
2235 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2236 pic16_allocDirReg(IC_LEFT(ic));
2238 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2239 pic16_allocDirReg(IC_RIGHT(ic));
2241 /* if this is an ipop that means some live
2242 range will have to be assigned again */
2244 reassignLR (IC_LEFT (ic));
2246 /* if result is present && is a true symbol */
2247 if (IC_RESULT (ic) && ic->op != IFX &&
2248 IS_TRUE_SYMOP (IC_RESULT (ic)))
2249 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2251 /* take away registers from live
2252 ranges that end at this instruction */
2253 deassignLRs (ic, ebbs[i]);
2255 /* some don't need registers */
2256 if (SKIP_IC2 (ic) ||
2257 ic->op == JUMPTABLE ||
2261 (IC_RESULT (ic) && POINTER_SET (ic)))
2264 /* now we need to allocate registers
2265 only for the result */
2268 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2274 /* if it does not need or is spilt
2275 or is already assigned to registers
2276 or will not live beyond this instructions */
2279 bitVectBitValue (_G.regAssigned, sym->key) ||
2280 sym->liveTo <= ic->seq)
2283 /* if some liverange has been spilt at the block level
2284 and this one live beyond this block then spil this
2286 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2291 /* if trying to allocate this will cause
2292 a spill and there is nothing to spill
2293 or this one is rematerializable then
2295 willCS = willCauseSpill (sym->nRegs, sym->regType);
2296 spillable = computeSpillable (ic);
2298 (willCS && bitVectIsZero (spillable)))
2306 /* If the live range preceeds the point of definition
2307 then ideally we must take into account registers that
2308 have been allocated after sym->liveFrom but freed
2309 before ic->seq. This is complicated, so spill this
2310 symbol instead and let fillGaps handle the allocation. */
2311 if (sym->liveFrom < ic->seq)
2317 /* if it has a spillocation & is used less than
2318 all other live ranges then spill this */
2320 if (sym->usl.spillLoc) {
2321 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2322 allLRs, ebbs[i], ic));
2323 if (leastUsed && leastUsed->used > sym->used) {
2328 /* if none of the liveRanges have a spillLocation then better
2329 to spill this one than anything else already assigned to registers */
2330 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2331 /* if this is local to this block then we might find a block spil */
2332 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2340 if (ic->op == RECEIVE)
2341 debugLog ("When I get clever, I'll optimize the receive logic\n");
2343 if(POINTER_GET(ic) && IS_BITFIELD(getSpec(operandType(IC_RESULT(ic))))
2344 && (SPEC_BLEN(getSpec(operandType(IC_RESULT(ic))))==1)
2345 && (ic->next->op == IFX)
2346 && (OP_LIVETO(IC_RESULT(ic)) == ic->next->seq)) {
2348 /* skip register allocation since none will be used */
2349 for(j=0;j<sym->nRegs;j++)
2350 sym->regs[j] = newReg(REG_TMP, PO_GPR_TEMP, 0, "bad", 1, 0, NULL);
2351 // OP_SYMBOL(IC_RESULT(ic))->nRegs = 0;
2356 /* if we need ptr regs for the right side
2358 if (POINTER_GET (ic) && IS_SYMOP( IC_LEFT(ic) ) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2359 <= (unsigned) PTRSIZE)
2364 /* else we assign registers to it */
2365 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2368 bitVectDebugOn(_G.regAssigned, debugF);
2370 for (j = 0; j < sym->nRegs; j++)
2372 if (sym->regType == REG_PTR)
2373 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2375 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2377 /* if the allocation falied which means
2378 this was spilt then break */
2382 debugLog (" %d - \n", __LINE__);
2384 /* if it shares registers with operands make sure
2385 that they are in the same position */
2386 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2387 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2388 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2389 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2390 /* do the same for the right operand */
2391 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2392 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2393 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2394 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2396 debugLog (" %d - \n", __LINE__);
2399 debugLog (" %d - \n", __LINE__);
2408 /* Check for and fix any problems with uninitialized operands */
2409 for (i = 0; i < count; i++)
2413 if (ebbs[i]->noPath &&
2414 (ebbs[i]->entryLabel != entryLabel &&
2415 ebbs[i]->entryLabel != returnLabel))
2418 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2425 verifyRegsAssigned (IC_COND (ic), ic);
2429 if (ic->op == JUMPTABLE)
2431 verifyRegsAssigned (IC_JTCOND (ic), ic);
2435 verifyRegsAssigned (IC_RESULT (ic), ic);
2436 verifyRegsAssigned (IC_LEFT (ic), ic);
2437 verifyRegsAssigned (IC_RIGHT (ic), ic);
2443 /*-----------------------------------------------------------------*/
2444 /* rUmaskForOp :- returns register mask for an operand */
2445 /*-----------------------------------------------------------------*/
2447 rUmaskForOp (operand * op)
2453 debugLog ("%s\n", __FUNCTION__);
2454 /* only temporaries are assigned registers */
2458 sym = OP_SYMBOL (op);
2460 /* if spilt or no registers assigned to it
2462 if (sym->isspilt || !sym->nRegs)
2465 rumask = newBitVect (pic16_nRegs);
2467 for (j = 0; j < sym->nRegs; j++)
2469 rumask = bitVectSetBit (rumask,
2470 sym->regs[j]->rIdx);
2476 /*-----------------------------------------------------------------*/
2477 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2478 /*-----------------------------------------------------------------*/
2480 regsUsedIniCode (iCode * ic)
2482 bitVect *rmask = newBitVect (pic16_nRegs);
2484 debugLog ("%s\n", __FUNCTION__);
2485 /* do the special cases first */
2488 rmask = bitVectUnion (rmask,
2489 rUmaskForOp (IC_COND (ic)));
2493 /* for the jumptable */
2494 if (ic->op == JUMPTABLE)
2496 rmask = bitVectUnion (rmask,
2497 rUmaskForOp (IC_JTCOND (ic)));
2502 /* of all other cases */
2504 rmask = bitVectUnion (rmask,
2505 rUmaskForOp (IC_LEFT (ic)));
2509 rmask = bitVectUnion (rmask,
2510 rUmaskForOp (IC_RIGHT (ic)));
2513 rmask = bitVectUnion (rmask,
2514 rUmaskForOp (IC_RESULT (ic)));
2520 /*-----------------------------------------------------------------*/
2521 /* createRegMask - for each instruction will determine the regsUsed */
2522 /*-----------------------------------------------------------------*/
2524 createRegMask (eBBlock ** ebbs, int count)
2528 debugLog ("%s\n", __FUNCTION__);
2529 /* for all blocks */
2530 for (i = 0; i < count; i++)
2534 if (ebbs[i]->noPath &&
2535 (ebbs[i]->entryLabel != entryLabel &&
2536 ebbs[i]->entryLabel != returnLabel))
2539 /* for all instructions */
2540 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2545 if (SKIP_IC2 (ic) || !ic->rlive)
2548 /* first mark the registers used in this
2550 ic->rUsed = regsUsedIniCode (ic);
2551 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2553 /* now create the register mask for those
2554 registers that are in use : this is a
2555 super set of ic->rUsed */
2556 ic->rMask = newBitVect (pic16_nRegs + 1);
2558 /* for all live Ranges alive at this point */
2559 for (j = 1; j < ic->rlive->size; j++)
2564 /* if not alive then continue */
2565 if (!bitVectBitValue (ic->rlive, j))
2568 /* find the live range we are interested in */
2569 if (!(sym = hTabItemWithKey (liveRanges, j)))
2571 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2572 "createRegMask cannot find live range");
2576 /* if no register assigned to it */
2577 if (!sym->nRegs || sym->isspilt)
2580 /* for all the registers allocated to it */
2581 for (k = 0; k < sym->nRegs; k++)
2584 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2590 /*-----------------------------------------------------------------*/
2591 /* rematStr - returns the rematerialized string for a remat var */
2592 /*-----------------------------------------------------------------*/
2594 rematStr (symbol * sym)
2597 iCode *ic = sym->rematiCode;
2598 symbol *psym = NULL;
2600 debugLog ("%s\n", __FUNCTION__);
2602 //printf ("%s\n", s);
2604 /* if plus or minus print the right hand side */
2606 if (ic->op == '+' || ic->op == '-') {
2608 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2610 sprintf (s, "(%s %c 0x%04x)",
2611 OP_SYMBOL (IC_LEFT (ric))->rname,
2613 (int) operandLitValue (IC_RIGHT (ic)));
2616 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2618 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2619 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2624 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2625 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2627 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2632 /*-----------------------------------------------------------------*/
2633 /* rematStr - returns the rematerialized string for a remat var */
2634 /*-----------------------------------------------------------------*/
2636 rematStr (symbol * sym)
2639 iCode *ic = sym->rematiCode;
2641 debugLog ("%s\n", __FUNCTION__);
2646 /* if plus or minus print the right hand side */
2648 if (ic->op == '+' || ic->op == '-') {
2649 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2652 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2656 if (ic->op == '+' || ic->op == '-')
2658 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2659 sprintf (s, "(%s %c 0x%04x)",
2660 OP_SYMBOL (IC_LEFT (ric))->rname,
2662 (int) operandLitValue (IC_RIGHT (ic)));
2665 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2667 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2671 /* we reached the end */
2672 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2676 printf ("%s\n", buffer);
2681 /*-----------------------------------------------------------------*/
2682 /* regTypeNum - computes the type & number of registers required */
2683 /*-----------------------------------------------------------------*/
2691 debugLog ("%s\n", __FUNCTION__);
2692 /* for each live range do */
2693 for (sym = hTabFirstItem (liveRanges, &k); sym;
2694 sym = hTabNextItem (liveRanges, &k)) {
2696 debugLog (" %d - %s\n", __LINE__, sym->rname);
2697 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2699 /* if used zero times then no registers needed */
2700 if ((sym->liveTo - sym->liveFrom) == 0)
2704 /* if the live range is a temporary */
2707 debugLog (" %d - itemp register\n", __LINE__);
2709 /* if the type is marked as a conditional */
2710 if (sym->regType == REG_CND)
2713 /* if used in return only then we don't
2715 if (sym->ruonly || sym->accuse) {
2716 if (IS_AGGREGATE (sym->type) || sym->isptr)
2717 sym->type = aggrToPtr (sym->type, FALSE);
2718 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2722 /* if the symbol has only one definition &
2723 that definition is a get_pointer and the
2724 pointer we are getting is rematerializable and
2727 if (bitVectnBitsOn (sym->defs) == 1 &&
2728 (ic = hTabItemWithKey (iCodehTab,
2729 bitVectFirstBit (sym->defs))) &&
2731 !IS_BITVAR (sym->etype) &&
2732 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2734 if (ptrPseudoSymSafe (sym, ic)) {
2738 debugLog (" %d - \n", __LINE__);
2740 /* create a psuedo symbol & force a spil */
2741 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2742 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2743 psym->type = sym->type;
2744 psym->etype = sym->etype;
2745 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2746 strcpy (psym->rname, psym->name);
2748 sym->usl.spillLoc = psym;
2752 /* if in data space or idata space then try to
2753 allocate pointer register */
2757 /* if not then we require registers */
2758 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2759 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2760 getSize (sym->type));
2764 if(IS_PTR_CONST (sym->type)) {
2766 if(IS_CODEPTR (sym->type)) {
2768 // what IS this ???? (HJD)
2769 debugLog (" %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2770 sym->nRegs = 3; // patch 14
2773 if (sym->nRegs > 4) {
2774 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2775 printTypeChain (sym->type, stderr);
2776 fprintf (stderr, "\n");
2779 /* determine the type of register required */
2780 if (sym->nRegs == 1 &&
2781 IS_PTR (sym->type) &&
2783 sym->regType = REG_PTR;
2785 sym->regType = REG_GPR;
2788 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2792 /* for the first run we don't provide */
2793 /* registers for true symbols we will */
2794 /* see how things go */
2800 static DEFSETFUNC (markRegFree)
2802 ((regs *)item)->isFree = 1;
2807 DEFSETFUNC (pic16_deallocReg)
2809 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2810 ((regs *)item)->isFree = 1;
2811 ((regs *)item)->wasUsed = 0;
2815 /*-----------------------------------------------------------------*/
2816 /* freeAllRegs - mark all registers as free */
2817 /*-----------------------------------------------------------------*/
2819 pic16_freeAllRegs ()
2821 debugLog ("%s\n", __FUNCTION__);
2823 applyToSet(pic16_dynAllocRegs,markRegFree);
2824 applyToSet(pic16_dynStackRegs,markRegFree);
2827 /*-----------------------------------------------------------------*/
2828 /*-----------------------------------------------------------------*/
2830 pic16_deallocateAllRegs ()
2832 debugLog ("%s\n", __FUNCTION__);
2834 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2838 /*-----------------------------------------------------------------*/
2839 /* deallocStackSpil - this will set the stack pointer back */
2840 /*-----------------------------------------------------------------*/
2842 DEFSETFUNC (deallocStackSpil)
2846 debugLog ("%s\n", __FUNCTION__);
2851 /*-----------------------------------------------------------------*/
2852 /* farSpacePackable - returns the packable icode for far variables */
2853 /*-----------------------------------------------------------------*/
2855 farSpacePackable (iCode * ic)
2859 debugLog ("%s\n", __FUNCTION__);
2860 /* go thru till we find a definition for the
2861 symbol on the right */
2862 for (dic = ic->prev; dic; dic = dic->prev)
2865 /* if the definition is a call then no */
2866 if ((dic->op == CALL || dic->op == PCALL) &&
2867 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2872 /* if shift by unknown amount then not */
2873 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2874 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2877 /* if pointer get and size > 1 */
2878 if (POINTER_GET (dic) &&
2879 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2882 if (POINTER_SET (dic) &&
2883 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2886 /* if any three is a true symbol in far space */
2887 if (IC_RESULT (dic) &&
2888 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2889 isOperandInFarSpace (IC_RESULT (dic)))
2892 if (IC_RIGHT (dic) &&
2893 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2894 isOperandInFarSpace (IC_RIGHT (dic)) &&
2895 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2898 if (IC_LEFT (dic) &&
2899 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2900 isOperandInFarSpace (IC_LEFT (dic)) &&
2901 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2904 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2906 if ((dic->op == LEFT_OP ||
2907 dic->op == RIGHT_OP ||
2909 IS_OP_LITERAL (IC_RIGHT (dic)))
2919 /*-----------------------------------------------------------------*/
2920 /* packRegsForAssign - register reduction for assignment */
2921 /*-----------------------------------------------------------------*/
2923 packRegsForAssign (iCode * ic, eBBlock * ebp)
2928 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2929 debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
2930 debugAopGet (" result:", IC_RESULT (ic));
2931 debugAopGet (" left:", IC_LEFT (ic));
2932 debugAopGet (" right:", IC_RIGHT (ic));
2934 // fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2936 debugLog(" %d - actuall processing\n", __LINE__ );
2938 if (!IS_ITEMP (IC_RESULT (ic))) {
2939 pic16_allocDirReg(IC_RESULT (ic));
2940 debugLog (" %d - result is not temp\n", __LINE__);
2944 /* See BUGLOG0001 - VR */
2946 if (!IS_ITEMP (IC_RIGHT (ic))) {
2947 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2948 pic16_allocDirReg(IC_RIGHT (ic));
2953 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2954 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2956 debugLog (" %d - not packing - right side fails \n", __LINE__);
2960 /* if the true symbol is defined in far space or on stack
2961 then we should not since this will increase register pressure */
2962 if (isOperandInFarSpace (IC_RESULT (ic)))
2964 if ((dic = farSpacePackable (ic)))
2971 /* find the definition of iTempNN scanning backwards if we find a
2972 a use of the true symbol before we find the definition then
2974 for (dic = ic->prev; dic; dic = dic->prev)
2977 /* if there is a function call and this is
2978 a parameter & not my parameter then don't pack it */
2979 if ((dic->op == CALL || dic->op == PCALL) &&
2980 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2981 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2983 debugLog (" %d - \n", __LINE__);
2992 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2994 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2995 IS_OP_VOLATILE (IC_RESULT (dic)))
2997 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3003 if( IS_SYMOP( IC_RESULT(dic)) &&
3004 IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3006 debugLog (" %d - result is bitfield\n", __LINE__);
3012 if (IS_SYMOP (IC_RESULT (dic)) &&
3013 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3015 /* A previous result was assigned to the same register - we'll our definition */
3016 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3017 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3018 if (POINTER_SET (dic))
3024 if (IS_SYMOP (IC_RIGHT (dic)) &&
3025 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3026 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3028 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3033 if (IS_SYMOP (IC_LEFT (dic)) &&
3034 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3035 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3037 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3042 if (POINTER_SET (dic) &&
3043 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3045 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3053 return 0; /* did not find */
3056 /* This code is taken from the hc08 port. Do not know
3057 * if it fits for pic16, but I leave it here just in case */
3059 /* if assignment then check that right is not a bit */
3060 if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
3061 sym_link *etype = operandType (IC_RIGHT (dic));
3063 if (IS_BITFIELD (etype)) {
3064 /* if result is a bit too then it's ok */
3065 etype = operandType (IC_RESULT (dic));
3066 if (!IS_BITFIELD (etype)) {
3067 debugLog(" %d bitfields\n");
3074 /* if the result is on stack or iaccess then it must be
3075 the same atleast one of the operands */
3076 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3077 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3079 /* the operation has only one symbol
3080 operator then we can pack */
3081 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3082 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3085 if (!((IC_LEFT (dic) &&
3086 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3088 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3092 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3093 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3094 /* found the definition */
3095 /* replace the result with the result of */
3096 /* this assignment and remove this assignment */
3097 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3098 IC_RESULT (dic) = IC_RESULT (ic);
3100 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3102 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3104 /* delete from liverange table also
3105 delete from all the points inbetween and the new
3107 for (sic = dic; sic != ic; sic = sic->next)
3109 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3110 if (IS_ITEMP (IC_RESULT (dic)))
3111 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3114 remiCodeFromeBBlock (ebp, ic);
3115 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3117 debugLog(" %d\n", __LINE__ );
3118 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3119 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3127 #define NO_packRegsForAccUse
3128 #define NO_packRegsForSupport
3129 #define NO_packRegsForOneuse
3130 #define NO_cast_peep
3135 #ifndef NO_packRegsForSupport
3136 /*-----------------------------------------------------------------*/
3137 /* findAssignToSym : scanning backwards looks for first assig found */
3138 /*-----------------------------------------------------------------*/
3140 findAssignToSym (operand * op, iCode * ic)
3144 debugLog ("%s\n", __FUNCTION__);
3145 for (dic = ic->prev; dic; dic = dic->prev)
3148 /* if definition by assignment */
3149 if (dic->op == '=' &&
3150 !POINTER_SET (dic) &&
3151 IC_RESULT (dic)->key == op->key
3152 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3156 /* we are interested only if defined in far space */
3157 /* or in stack space in case of + & - */
3159 /* if assigned to a non-symbol then return
3161 if (!IS_SYMOP (IC_RIGHT (dic)))
3164 /* if the symbol is in far space then
3166 if (isOperandInFarSpace (IC_RIGHT (dic)))
3169 /* for + & - operations make sure that
3170 if it is on the stack it is the same
3171 as one of the three operands */
3172 if ((ic->op == '+' || ic->op == '-') &&
3173 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3175 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3176 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3177 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3185 /* if we find an usage then we cannot delete it */
3186 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3189 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3192 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3196 /* now make sure that the right side of dic
3197 is not defined between ic & dic */
3200 iCode *sic = dic->next;
3202 for (; sic != ic; sic = sic->next)
3203 if (IC_RESULT (sic) &&
3204 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3215 #ifndef NO_packRegsForSupport
3216 /*-----------------------------------------------------------------*/
3217 /* packRegsForSupport :- reduce some registers for support calls */
3218 /*-----------------------------------------------------------------*/
3220 packRegsForSupport (iCode * ic, eBBlock * ebp)
3224 debugLog ("%s\n", __FUNCTION__);
3225 /* for the left & right operand :- look to see if the
3226 left was assigned a true symbol in far space in that
3227 case replace them */
3228 if (IS_ITEMP (IC_LEFT (ic)) &&
3229 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3231 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3237 debugAopGet ("removing left:", IC_LEFT (ic));
3239 /* found it we need to remove it from the
3241 for (sic = dic; sic != ic; sic = sic->next)
3242 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3244 IC_LEFT (ic)->operand.symOperand =
3245 IC_RIGHT (dic)->operand.symOperand;
3246 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3247 remiCodeFromeBBlock (ebp, dic);
3248 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3249 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3253 /* do the same for the right operand */
3256 IS_ITEMP (IC_RIGHT (ic)) &&
3257 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3259 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3265 /* if this is a subtraction & the result
3266 is a true symbol in far space then don't pack */
3267 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3269 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3270 if (IN_FARSPACE (SPEC_OCLS (etype)))
3274 debugAopGet ("removing right:", IC_RIGHT (ic));
3276 /* found it we need to remove it from the
3278 for (sic = dic; sic != ic; sic = sic->next)
3279 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3281 IC_RIGHT (ic)->operand.symOperand =
3282 IC_RIGHT (dic)->operand.symOperand;
3283 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3285 remiCodeFromeBBlock (ebp, dic);
3286 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3287 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3296 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3298 #ifndef NO_packRegsForOneuse
3299 /*-----------------------------------------------------------------*/
3300 /* packRegsForOneuse : - will reduce some registers for single Use */
3301 /*-----------------------------------------------------------------*/
3303 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3308 debugLog ("%s\n", __FUNCTION__);
3309 /* if returning a literal then do nothing */
3313 /* only upto 2 bytes since we cannot predict
3314 the usage of b, & acc */
3315 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */
3320 /* this routine will mark the a symbol as used in one
3321 instruction use only && if the definition is local
3322 (ie. within the basic block) && has only one definition &&
3323 that definition is either a return value from a
3324 function or does not contain any variables in
3326 uses = bitVectCopy (OP_USES (op));
3327 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3328 if (!bitVectIsZero (uses)) /* has other uses */
3331 /* if it has only one defintion */
3332 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3333 return NULL; /* has more than one definition */
3335 /* get that definition */
3337 hTabItemWithKey (iCodehTab,
3338 bitVectFirstBit (OP_DEFS (op)))))
3341 /* found the definition now check if it is local */
3342 if (dic->seq < ebp->fSeq ||
3343 dic->seq > ebp->lSeq)
3344 return NULL; /* non-local */
3346 /* now check if it is the return from
3348 if (dic->op == CALL || dic->op == PCALL)
3350 if (ic->op != SEND && ic->op != RETURN &&
3351 !POINTER_SET(ic) && !POINTER_GET(ic))
3353 OP_SYMBOL (op)->ruonly = 1;
3360 /* otherwise check that the definition does
3361 not contain any symbols in far space */
3362 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3363 isOperandInFarSpace (IC_RIGHT (dic)) ||
3364 IS_OP_RUONLY (IC_LEFT (ic)) ||
3365 IS_OP_RUONLY (IC_RIGHT (ic)))
3370 /* if pointer set then make sure the pointer
3372 if (POINTER_SET (dic) &&
3373 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3376 if (POINTER_GET (dic) &&
3377 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3382 /* also make sure the intervenening instructions
3383 don't have any thing in far space */
3384 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3387 /* if there is an intervening function call then no */
3388 if (dic->op == CALL || dic->op == PCALL)
3390 /* if pointer set then make sure the pointer
3392 if (POINTER_SET (dic) &&
3393 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3396 if (POINTER_GET (dic) &&
3397 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3400 /* if address of & the result is remat then okay */
3401 if (dic->op == ADDRESS_OF &&
3402 OP_SYMBOL (IC_RESULT (dic))->remat)
3405 /* if operand has size of three or more & this
3406 operation is a '*','/' or '%' then 'b' may
3408 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3409 getSize (operandType (op)) >= 3)
3412 /* if left or right or result is in far space */
3413 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3414 isOperandInFarSpace (IC_RIGHT (dic)) ||
3415 isOperandInFarSpace (IC_RESULT (dic)) ||
3416 IS_OP_RUONLY (IC_LEFT (dic)) ||
3417 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3418 IS_OP_RUONLY (IC_RESULT (dic)))
3424 OP_SYMBOL (op)->ruonly = 1;
3431 /*-----------------------------------------------------------------*/
3432 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3433 /*-----------------------------------------------------------------*/
3435 isBitwiseOptimizable (iCode * ic)
3437 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3438 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3440 debugLog ("%s\n", __FUNCTION__);
3441 /* bitwise operations are considered optimizable
3442 under the following conditions (Jean-Louis VERN)
3454 if (IS_LITERAL (rtype) ||
3455 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3462 #ifndef NO_packRegsForAccUse
3464 /*-----------------------------------------------------------------*/
3465 /* packRegsForAccUse - pack registers for acc use */
3466 /*-----------------------------------------------------------------*/
3468 packRegsForAccUse (iCode * ic)
3472 debugLog ("%s\n", __FUNCTION__);
3474 /* if this is an aggregate, e.g. a one byte char array */
3475 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3478 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3480 /* if + or - then it has to be one byte result */
3481 if ((ic->op == '+' || ic->op == '-')
3482 && getSize (operandType (IC_RESULT (ic))) > 1)
3485 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3486 /* if shift operation make sure right side is not a literal */
3487 if (ic->op == RIGHT_OP &&
3488 (isOperandLiteral (IC_RIGHT (ic)) ||
3489 getSize (operandType (IC_RESULT (ic))) > 1))
3492 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3493 if (ic->op == LEFT_OP &&
3494 (isOperandLiteral (IC_RIGHT (ic)) ||
3495 getSize (operandType (IC_RESULT (ic))) > 1))
3498 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3499 if (IS_BITWISE_OP (ic) &&
3500 getSize (operandType (IC_RESULT (ic))) > 1)
3504 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3505 /* has only one definition */
3506 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3509 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3510 /* has only one use */
3511 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3514 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3515 /* and the usage immediately follows this iCode */
3516 if (!(uic = hTabItemWithKey (iCodehTab,
3517 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3520 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3521 if (ic->next != uic)
3524 /* if it is a conditional branch then we definitely can */
3528 if (uic->op == JUMPTABLE)
3531 /* if the usage is not is an assignment
3532 or an arithmetic / bitwise / shift operation then not */
3533 if (POINTER_SET (uic) &&
3534 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3537 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3538 if (uic->op != '=' &&
3539 !IS_ARITHMETIC_OP (uic) &&
3540 !IS_BITWISE_OP (uic) &&
3541 uic->op != LEFT_OP &&
3542 uic->op != RIGHT_OP)
3545 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3546 /* if used in ^ operation then make sure right is not a
3548 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3551 /* if shift operation make sure right side is not a literal */
3552 if (uic->op == RIGHT_OP &&
3553 (isOperandLiteral (IC_RIGHT (uic)) ||
3554 getSize (operandType (IC_RESULT (uic))) > 1))
3557 if (uic->op == LEFT_OP &&
3558 (isOperandLiteral (IC_RIGHT (uic)) ||
3559 getSize (operandType (IC_RESULT (uic))) > 1))
3562 /* make sure that the result of this icode is not on the
3563 stack, since acc is used to compute stack offset */
3564 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3565 OP_SYMBOL (IC_RESULT (uic))->onStack)
3568 /* if either one of them in far space then we cannot */
3569 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3570 isOperandInFarSpace (IC_LEFT (uic))) ||
3571 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3572 isOperandInFarSpace (IC_RIGHT (uic))))
3575 /* if the usage has only one operand then we can */
3576 if (IC_LEFT (uic) == NULL ||
3577 IC_RIGHT (uic) == NULL)
3580 /* make sure this is on the left side if not
3581 a '+' since '+' is commutative */
3582 if (ic->op != '+' &&
3583 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3587 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3588 /* if one of them is a literal then we can */
3589 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3590 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3591 (getSize (operandType (IC_RESULT (uic))) <= 1))
3593 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3598 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3599 /* if the other one is not on stack then we can */
3600 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3601 (IS_ITEMP (IC_RIGHT (uic)) ||
3602 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3603 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3606 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3607 (IS_ITEMP (IC_LEFT (uic)) ||
3608 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3609 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3615 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3616 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3623 /*-----------------------------------------------------------------*/
3624 /* packForPush - hueristics to reduce iCode for pushing */
3625 /*-----------------------------------------------------------------*/
3627 packForReceive (iCode * ic, eBBlock * ebp)
3631 debugLog ("%s\n", __FUNCTION__);
3632 debugAopGet (" result:", IC_RESULT (ic));
3633 debugAopGet (" left:", IC_LEFT (ic));
3634 debugAopGet (" right:", IC_RIGHT (ic));
3639 for (dic = ic->next; dic; dic = dic->next)
3641 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3642 debugLog (" used on left\n");
3643 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3644 debugLog (" used on right\n");
3645 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3646 debugLog (" used on result\n");
3648 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3649 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3653 debugLog (" hey we can remove this unnecessary assign\n");
3655 /*-----------------------------------------------------------------*/
3656 /* packForPush - hueristics to reduce iCode for pushing */
3657 /*-----------------------------------------------------------------*/
3659 packForPush (iCode * ic, eBBlock * ebp)
3663 debugLog ("%s\n", __FUNCTION__);
3664 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3671 n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3672 n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3673 debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3674 debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3678 /* must have only definition & one usage */
3679 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3680 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3683 /* find the definition */
3684 if (!(dic = hTabItemWithKey (iCodehTab,
3685 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3688 /* if definition is not assignment,
3689 * or is not pointer (because pointer might have changed) */
3690 if (dic->op != '=' || POINTER_SET (dic))
3693 /* we must ensure that we can use the delete the assignment,
3694 * because the source might have been modified in between.
3695 * Until I know how to fix this, I'll use the adhoc fix
3696 * to check the liveranges */
3697 if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3699 // debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3703 /* we now we know that it has one & only one def & use
3704 and the that the definition is an assignment */
3705 IC_LEFT (ic) = IC_RIGHT (dic);
3707 debugf("remiCodeFromeBBlock: %s\n", printILine(dic));
3709 remiCodeFromeBBlock (ebp, dic);
3710 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3711 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3714 static void printSymType(char * str, sym_link *sl)
3716 if(!pic16_ralloc_debug)return;
3718 debugLog (" %s Symbol type: ",str);
3719 printTypeChain( sl, debugF);
3723 /*-----------------------------------------------------------------*/
3724 /* some debug code to print the symbol S_TYPE. Note that
3725 * the function checkSClass in src/SDCCsymt.c dinks with
3726 * the S_TYPE in ways the PIC port doesn't fully like...*/
3727 /*-----------------------------------------------------------------*/
3728 static void isData(sym_link *sl)
3732 if(!pic16_ralloc_debug)return;
3739 for ( ; sl; sl=sl->next) {
3741 switch (SPEC_SCLS(sl)) {
3742 case S_DATA: fprintf (of, "data "); break;
3743 case S_XDATA: fprintf (of, "xdata "); break;
3744 case S_SFR: fprintf (of, "sfr "); break;
3745 case S_SBIT: fprintf (of, "sbit "); break;
3746 case S_CODE: fprintf (of, "code "); break;
3747 case S_IDATA: fprintf (of, "idata "); break;
3748 case S_PDATA: fprintf (of, "pdata "); break;
3749 case S_LITERAL: fprintf (of, "literal "); break;
3750 case S_STACK: fprintf (of, "stack "); break;
3751 case S_XSTACK: fprintf (of, "xstack "); break;
3752 case S_BIT: fprintf (of, "bit "); break;
3753 case S_EEPROM: fprintf (of, "eeprom "); break;
3761 /*--------------------------------------------------------------------*/
3762 /* pic16_packRegisters - does some transformations to reduce */
3763 /* register pressure */
3765 /*--------------------------------------------------------------------*/
3767 pic16_packRegisters (eBBlock * ebp)
3772 debugLog ("%s\n", __FUNCTION__);
3778 /* look for assignments of the form */
3779 /* iTempNN = TRueSym (someoperation) SomeOperand */
3781 /* TrueSym := iTempNN:1 */
3782 for (ic = ebp->sch; ic; ic = ic->next)
3784 // debugLog("%d\n", __LINE__);
3785 /* find assignment of the form TrueSym := iTempNN:1 */
3786 if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3787 change += packRegsForAssign (ic, ebp);
3791 if (POINTER_SET (ic))
3792 debugLog ("pointer is set\n");
3793 debugAopGet (" result:", IC_RESULT (ic));
3794 debugAopGet (" left:", IC_LEFT (ic));
3795 debugAopGet (" right:", IC_RIGHT (ic));
3804 for (ic = ebp->sch; ic; ic = ic->next) {
3806 if(IS_SYMOP ( IC_LEFT(ic))) {
3807 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3809 debugAopGet ("x left:", IC_LEFT (ic));
3811 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3813 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3815 debugLog (" is a pointer\n");
3817 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3818 debugLog (" is a ptr\n");
3820 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3821 debugLog (" is volatile\n");
3825 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3826 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3827 pic16_allocDirReg(IC_LEFT (ic));
3830 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3833 if(IS_SYMOP ( IC_RIGHT(ic))) {
3834 debugAopGet (" right:", IC_RIGHT (ic));
3835 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3838 if(IS_SYMOP ( IC_RESULT(ic))) {
3839 debugAopGet (" result:", IC_RESULT (ic));
3840 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3843 if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3844 debugAopGet (" right:", IC_RIGHT (ic));
3845 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3846 // pic16_allocDirReg(IC_RIGHT(ic));
3849 if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3850 debugAopGet (" result:", IC_RESULT (ic));
3851 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3852 // pic16_allocDirReg(IC_RESULT(ic));
3856 if (POINTER_SET (ic))
3857 debugLog (" %d - Pointer set\n", __LINE__);
3859 /* Look for two subsequent iCodes with */
3861 /* _c = iTemp & op; */
3862 /* and replace them by */
3865 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3867 && ic->prev->op == '='
3868 && IS_ITEMP (IC_LEFT (ic))
3869 && IC_LEFT (ic) == IC_RESULT (ic->prev)
3870 && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3872 iCode* ic_prev = ic->prev;
3873 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3875 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3876 if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
3877 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3878 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3879 prev_result_sym->liveTo == ic->seq)
3881 prev_result_sym->liveTo = ic_prev->seq;
3884 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3886 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3888 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
3889 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3890 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3891 remiCodeFromeBBlock (ebp, ic_prev);
3892 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3896 /* if this is an itemp & result of a address of a true sym
3897 then mark this as rematerialisable */
3898 if (ic->op == ADDRESS_OF &&
3899 IS_ITEMP (IC_RESULT (ic)) &&
3900 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3901 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3902 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3905 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3907 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3908 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3909 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3913 /* if straight assignment then carry remat flag if
3914 this is the only definition */
3915 if (ic->op == '=' &&
3916 !POINTER_SET (ic) &&
3917 IS_SYMOP (IC_RIGHT (ic)) &&
3918 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3919 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3921 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3923 OP_SYMBOL (IC_RESULT (ic))->remat =
3924 OP_SYMBOL (IC_RIGHT (ic))->remat;
3925 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3926 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3929 /* if this is a +/- operation with a rematerizable
3930 then mark this as rematerializable as well */
3931 if ((ic->op == '+' || ic->op == '-') &&
3932 (IS_SYMOP (IC_LEFT (ic)) &&
3933 IS_ITEMP (IC_RESULT (ic)) &&
3934 OP_SYMBOL (IC_LEFT (ic))->remat &&
3935 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3936 IS_OP_LITERAL (IC_RIGHT (ic))))
3938 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3940 operandLitValue (IC_RIGHT (ic));
3941 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3942 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3943 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3946 /* mark the pointer usages */
3947 if (POINTER_SET (ic))
3949 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3950 debugLog (" marking as a pointer (set) =>");
3951 debugAopGet (" result:", IC_RESULT (ic));
3953 if (POINTER_GET (ic))
3955 if(IS_SYMOP(IC_LEFT(ic))) {
3956 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3957 debugLog (" marking as a pointer (get) =>");
3958 debugAopGet (" left:", IC_LEFT (ic));
3962 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3966 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3967 /* if we are using a symbol on the stack
3968 then we should say pic16_ptrRegReq */
3969 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3970 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3971 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3972 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3973 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3974 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3978 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3979 if (IS_SYMOP (IC_LEFT (ic)))
3980 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3981 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3982 if (IS_SYMOP (IC_RIGHT (ic)))
3983 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3984 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3985 if (IS_SYMOP (IC_RESULT (ic)))
3986 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3987 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3990 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3994 /* if the condition of an if instruction
3995 is defined in the previous instruction then
3996 mark the itemp as a conditional */
3997 if ((IS_CONDITIONAL (ic) ||
3998 ((ic->op == BITWISEAND ||
4001 isBitwiseOptimizable (ic))) &&
4002 ic->next && ic->next->op == IFX &&
4003 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4004 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4007 debugLog (" %d\n", __LINE__);
4008 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4012 debugLog(" %d\n", __LINE__);
4014 #ifndef NO_packRegsForSupport
4015 /* reduce for support function calls */
4016 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4017 packRegsForSupport (ic, ebp);
4020 /* if a parameter is passed, it's in W, so we may not
4021 need to place a copy in a register */
4022 if (ic->op == RECEIVE)
4023 packForReceive (ic, ebp);
4025 #ifndef NO_packRegsForOneuse
4026 /* some cases the redundant moves can
4027 can be eliminated for return statements */
4028 if ((ic->op == RETURN || ic->op == SEND) &&
4029 !isOperandInFarSpace (IC_LEFT (ic)) &&
4031 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4034 #ifndef NO_packRegsForOneuse
4035 /* if pointer set & left has a size more than
4036 one and right is not in far space */
4037 if (POINTER_SET (ic) &&
4038 !isOperandInFarSpace (IC_RIGHT (ic)) &&
4039 !OP_SYMBOL (IC_RESULT (ic))->remat &&
4040 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4041 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4043 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4046 #ifndef NO_packRegsForOneuse
4047 /* if pointer get */
4048 if (POINTER_GET (ic) &&
4049 !isOperandInFarSpace (IC_RESULT (ic)) &&
4050 !OP_SYMBOL (IC_LEFT (ic))->remat &&
4051 !IS_OP_RUONLY (IC_RESULT (ic)) &&
4052 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4054 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4055 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4058 #ifndef NO_cast_peep
4059 /* if this is cast for intergral promotion then
4060 check if only use of the definition of the
4061 operand being casted/ if yes then replace
4062 the result of that arithmetic operation with
4063 this result and get rid of the cast */
4064 if (ic->op == CAST) {
4066 sym_link *fromType = operandType (IC_RIGHT (ic));
4067 sym_link *toType = operandType (IC_LEFT (ic));
4069 debugLog (" %d - casting\n", __LINE__);
4071 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4072 getSize (fromType) != getSize (toType)) {
4075 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4078 if (IS_ARITHMETIC_OP (dic)) {
4079 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
4081 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4082 IC_RESULT (dic) = IC_RESULT (ic);
4083 remiCodeFromeBBlock (ebp, ic);
4084 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4085 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4086 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4090 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4094 /* if the type from and type to are the same
4095 then if this is the only use then packit */
4096 if (compareType (operandType (IC_RIGHT (ic)),
4097 operandType (IC_LEFT (ic))) == 1) {
4099 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4102 debugLog(" %d\n", __LINE__);
4104 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4105 IC_RESULT (dic) = IC_RESULT (ic);
4106 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4107 remiCodeFromeBBlock (ebp, ic);
4108 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4109 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4118 /* there are some problems with packing variables
4119 * it seems that the live range estimator doesn't
4120 * estimate correctly the liveranges of some symbols */
4123 iTempNN := (some variable in farspace) V1
4128 if (ic->op == IPUSH)
4130 packForPush (ic, ebp);
4134 #ifndef NO_packRegsForAccUse
4135 /* pack registers for accumulator use, when the
4136 result of an arithmetic or bit wise operation
4137 has only one use, that use is immediately following
4138 the defintion and the using iCode has only one
4139 operand or has two operands but one is literal &
4140 the result of that operation is not on stack then
4141 we can leave the result of this operation in acc:b
4143 if ((IS_ARITHMETIC_OP (ic)
4145 || IS_BITWISE_OP (ic)
4147 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4150 IS_ITEMP (IC_RESULT (ic)) &&
4151 getSize (operandType (IC_RESULT (ic))) <= 1)
4153 packRegsForAccUse (ic);
4160 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4164 if (!pic16_ralloc_debug || !debugF)
4167 for (i = 0; i < count; i++)
4169 fprintf (debugF, "\n----------------------------------------------------------------\n");
4170 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4171 ebbs[i]->entryLabel->name,
4174 ebbs[i]->isLastInLoop);
4175 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4180 fprintf (debugF, "visited %d : hasFcall = %d\n",
4184 fprintf (debugF, "\ndefines bitVector :");
4185 bitVectDebugOn (ebbs[i]->defSet, debugF);
4186 fprintf (debugF, "\nlocal defines bitVector :");
4187 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4188 fprintf (debugF, "\npointers Set bitvector :");
4189 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4190 fprintf (debugF, "\nin pointers Set bitvector :");
4191 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4192 fprintf (debugF, "\ninDefs Set bitvector :");
4193 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4194 fprintf (debugF, "\noutDefs Set bitvector :");
4195 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4196 fprintf (debugF, "\nusesDefs Set bitvector :");
4197 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4198 fprintf (debugF, "\n----------------------------------------------------------------\n");
4199 printiCChain (ebbs[i]->sch, debugF);
4202 /*-----------------------------------------------------------------*/
4203 /* pic16_assignRegisters - assigns registers to each live range as need */
4204 /*-----------------------------------------------------------------*/
4206 pic16_assignRegisters (eBBlock ** ebbs, int count)
4211 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4212 debugLog ("\nebbs before optimizing:\n");
4213 dumpEbbsToDebug (ebbs, count);
4215 _inRegAllocator = 1;
4217 setToNull ((void *) &_G.funcrUsed);
4218 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4221 /* change assignments this will remove some
4222 live ranges reducing some register pressure */
4223 for (i = 0; i < count; i++)
4224 pic16_packRegisters (ebbs[i]);
4231 debugLog("dir registers allocated so far:\n");
4232 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4235 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4236 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4237 reg = hTabNextItem(dynDirectRegNames, &hkey);
4242 /* liveranges probably changed by register packing
4243 so we compute them again */
4244 recomputeLiveRanges (ebbs, count);
4246 if (options.dump_pack)
4247 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4249 /* first determine for each live range the number of
4250 registers & the type of registers required for each */
4253 /* and serially allocate registers */
4254 serialRegAssign (ebbs, count);
4257 debugLog ("ebbs after serialRegAssign:\n");
4258 dumpEbbsToDebug (ebbs, count);
4261 //pic16_freeAllRegs();
4263 /* if stack was extended then tell the user */
4266 /* werror(W_TOOMANY_SPILS,"stack", */
4267 /* _G.stackExtend,currFunc->name,""); */
4273 /* werror(W_TOOMANY_SPILS,"data space", */
4274 /* _G.dataExtend,currFunc->name,""); */
4278 /* after that create the register mask
4279 for each of the instruction */
4280 createRegMask (ebbs, count);
4282 /* redo that offsets for stacked automatic variables */
4283 redoStackOffsets ();
4285 if (options.dump_rassgn)
4286 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4288 /* now get back the chain */
4289 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4291 debugLog ("ebbs after optimizing:\n");
4292 dumpEbbsToDebug (ebbs, count);
4294 _inRegAllocator = 0;
4298 /* free up any _G.stackSpil locations allocated */
4299 applyToSet (_G.stackSpil, deallocStackSpil);
4301 setToNull ((void *) &_G.stackSpil);
4302 setToNull ((void *) &_G.spiltSet);
4303 /* mark all registers as free */
4304 pic16_freeAllRegs ();
4307 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");