New Memory Allocation functions
[fw/sdcc] / src / pic / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. (8051) specific
4
5                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6                 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7
8    This program is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the
10    Free Software Foundation; either version 2, or (at your option) any
11    later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21    
22    In other words, you are welcome to use, share and improve this program.
23    You are forbidden to forbid anyone else to use, share and improve
24    what you give them.   Help stamp out software-hoarding!  
25 -------------------------------------------------------------------------*/
26
27 #include "common.h"
28 #include "ralloc.h"
29 #include "gen.h"
30
31 #if defined(_MSC_VER)
32 #define __FUNCTION__ __FILE__
33 #endif
34
35 /*-----------------------------------------------------------------*/
36 /* At this point we start getting processor specific although      */
37 /* some routines are non-processor specific & can be reused when   */
38 /* targetting other processors. The decision for this will have    */
39 /* to be made on a routine by routine basis                        */
40 /* routines used to pack registers are most definitely not reusable*/
41 /* since the pack the registers depending strictly on the MCU      */
42 /*-----------------------------------------------------------------*/
43
44 extern void genpic14Code(iCode *);
45
46 /* Global data */
47 static struct {
48     bitVect *spiltSet;
49     set *stackSpil;
50     bitVect *regAssigned;
51     short blockSpil;
52     int slocNum;
53     bitVect *funcrUsed; /* registers used in a function */
54     int stackExtend;
55     int dataExtend;
56 } _G;
57
58 /* Shared with gen.c */
59 int pic14_ptrRegReq; /* one byte pointer register required */
60
61 /* pic14 registers */
62 regs regspic14[] = 
63 {
64
65   {REG_GPR,  0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
66   {REG_GPR,  0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
67   {REG_GPR,  0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
68   {REG_GPR,  0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
69   {REG_GPR,  0x10, "r0x10", "r0x10", 0x10, 1, 0},
70   {REG_GPR,  0x11, "r0x11", "r0x11", 0x11, 1, 0},
71   {REG_GPR,  0x12, "r0x12", "r0x12", 0x12, 1, 0},
72   {REG_GPR,  0x13, "r0x13", "r0x13", 0x13, 1, 0},
73   {REG_GPR,  0x14, "r0x14", "r0x14", 0x14, 1, 0},
74   {REG_GPR,  0x15, "r0x15", "r0x15", 0x15, 1, 0},
75   {REG_GPR,  0x16, "r0x16", "r0x16", 0x16, 1, 0},
76   {REG_GPR,  0x17, "r0x17", "r0x17", 0x17, 1, 0},
77   {REG_GPR,  0x18, "r0x18", "r0x18", 0x18, 1, 0},
78   {REG_GPR,  0x19, "r0x19", "r0x19", 0x19, 1, 0},
79   {REG_GPR,  0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
80   {REG_GPR,  0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
81   {REG_GPR,  0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
82   {REG_GPR,  0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
83   {REG_GPR,  0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
84   {REG_GPR,  0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
85   {REG_PTR,  4, "FSR", "FSR", 4, 1,0},
86
87 };
88
89 int pic14_nRegs = sizeof(regspic14) / sizeof(regs);
90 static void spillThis (symbol *);
91 static int debug=1;
92 static FILE *debugF=NULL;
93 /*-----------------------------------------------------------------*/
94 /* debugLog - open a file for debugging information                */
95 /*-----------------------------------------------------------------*/
96 //static void debugLog(char *inst,char *fmt, ...)
97 static void debugLog(char *fmt, ...)
98 {
99   static int append = 0;   // First time through, open the file without append.
100   char buffer[256];
101   //char *bufferP=buffer;
102   va_list ap;
103
104   if(!debug)
105     return;
106
107
108   if (!debugF) {
109     /* create the file name */
110     strcpy(buffer,srcFileName);
111     strcat(buffer,".d");
112
113     if( !(debugF = fopen(buffer, (append ? "a+" : "w") ))) {
114       werror(E_FILE_OPEN_ERR,buffer);
115       exit(1);
116     }
117     append = 1;  // Next time debubLog is called, we'll append the debug info
118   }
119
120   va_start(ap,fmt);   
121
122   vsprintf(buffer,fmt,ap);
123
124   fprintf(debugF,"%s",buffer);
125 /*
126   while (isspace(*bufferP)) bufferP++;
127
128   if (bufferP && *bufferP) 
129     lineCurr = (lineCurr ?
130                 connectLine(lineCurr,newLineNode(lb)) :
131                 (lineHead = newLineNode(lb)));
132   lineCurr->isInline = _G.inLine;
133   lineCurr->isDebug  = _G.debugLine;
134 */
135   va_end(ap);
136
137 }
138
139 static void debugNewLine(void)
140 {
141   if(debugF)
142     fputc('\n',debugF);
143 }
144 /*-----------------------------------------------------------------*/
145 /* debugLogClose - closes the debug log file (if opened)           */
146 /*-----------------------------------------------------------------*/
147 static void debugLogClose(void)
148 {
149   if(debugF) {
150     fclose(debugF);
151     debugF = NULL;
152   }
153 }
154 #define AOP(op) op->aop
155
156 static char *debugAopGet(char *str,operand *op)
157 {
158   if(str)
159     debugLog(str);
160
161   printOperand(op,debugF);debugNewLine();
162
163   return NULL;
164
165 }
166
167 static char * decodeOp(unsigned int op)
168 {
169
170   if(op<128 && op>' ') {
171     buffer[0] = (op & 0xff);
172     buffer[1] = 0;
173     return buffer;
174   }
175
176   switch(op) {
177   case IDENTIFIER:
178     return "IDENTIFIER";
179   case TYPE_NAME:
180     return "TYPE_NAME";
181   case CONSTANT:
182     return "CONSTANT";
183   case STRING_LITERAL:
184     return "STRING_LITERAL";
185   case SIZEOF:
186     return "SIZEOF";
187   case PTR_OP:
188     return "PTR_OP";
189   case INC_OP:
190     return "INC_OP";
191   case DEC_OP:
192     return "DEC_OP";
193   case LEFT_OP:
194     return "LEFT_OP";
195   case RIGHT_OP:
196     return "RIGHT_OP";
197   case LE_OP:
198     return "LE_OP";
199   case GE_OP:
200     return "GE_OP";
201   case EQ_OP:
202     return "EQ_OP";
203   case NE_OP:
204     return "NE_OP";
205   case AND_OP:
206     return "AND_OP";
207   case OR_OP:
208     return "OR_OP";
209   case MUL_ASSIGN:
210     return "MUL_ASSIGN";
211   case DIV_ASSIGN:
212     return "DIV_ASSIGN";
213   case MOD_ASSIGN:
214     return "MOD_ASSIGN";
215   case ADD_ASSIGN:
216     return "ADD_ASSIGN";
217   case SUB_ASSIGN:
218     return "SUB_ASSIGN";
219   case LEFT_ASSIGN:
220     return "LEFT_ASSIGN";
221   case RIGHT_ASSIGN:
222     return "RIGHT_ASSIGN";
223   case AND_ASSIGN:
224     return "AND_ASSIGN";
225   case XOR_ASSIGN:
226     return "XOR_ASSIGN";
227   case OR_ASSIGN:
228     return "OR_ASSIGN";
229   case TYPEDEF:
230     return "TYPEDEF";
231   case EXTERN:
232     return "EXTERN";
233   case STATIC:
234     return "STATIC";
235   case AUTO:
236     return "AUTO";
237   case REGISTER:
238     return "REGISTER";
239   case CODE:
240     return "CODE";
241   case EEPROM:
242     return "EEPROM";
243   case INTERRUPT:
244     return "INTERRUPT";
245   case SFR:
246     return "SFR";
247   case AT:
248     return "AT";
249   case SBIT:
250     return "SBIT";
251   case REENTRANT:
252     return "REENTRANT";
253   case USING:
254     return "USING";
255   case XDATA:
256     return "XDATA";
257   case DATA:
258     return "DATA";
259   case IDATA:
260     return "IDATA";
261   case PDATA:
262     return "PDATA";
263   case VAR_ARGS:
264     return "VAR_ARGS";
265   case CRITICAL:
266     return "CRITICAL";
267   case NONBANKED:
268     return "NONBANKED";
269   case BANKED:
270     return "BANKED";
271   case CHAR:
272     return "CHAR";
273   case SHORT:
274     return "SHORT";
275   case INT:
276     return "INT";
277   case LONG:
278     return "LONG";
279   case SIGNED:
280     return "SIGNED";
281   case UNSIGNED:
282     return "UNSIGNED";
283   case FLOAT:
284     return "FLOAT";
285   case DOUBLE:
286     return "DOUBLE";
287   case CONST:
288     return "CONST";
289   case VOLATILE:
290     return "VOLATILE";
291   case VOID:
292     return "VOID";
293   case BIT:
294     return "BIT";
295   case STRUCT:
296     return "STRUCT";
297   case UNION:
298     return "UNION";
299   case ENUM:
300     return "ENUM";
301   case ELIPSIS:
302     return "ELIPSIS";
303   case RANGE:
304     return "RANGE";
305   case FAR:
306     return "FAR";
307   case _XDATA:
308     return "_XDATA";
309   case _CODE:
310     return "_CODE";
311   case _GENERIC:
312     return "_GENERIC";
313   case _NEAR:
314     return "_NEAR";
315   case _PDATA:
316     return "_PDATA";
317   case _IDATA:
318     return "_IDATA";
319   case _EEPROM:
320     return "_EEPROM";
321   case CASE:
322     return "CASE";
323   case DEFAULT:
324     return "DEFAULT";
325   case IF:
326     return "IF";
327   case ELSE:
328     return "ELSE";
329   case SWITCH:
330     return "SWITCH";
331   case WHILE:
332     return "WHILE";
333   case DO:
334     return "DO";
335   case FOR:
336     return "FOR";
337   case GOTO:
338     return "GOTO";
339   case CONTINUE:
340     return "CONTINUE";
341   case BREAK:
342     return "BREAK";
343   case RETURN:
344     return "RETURN";
345   case INLINEASM:
346     return "INLINEASM";
347   case IFX:
348     return "IFX";
349   case ADDRESS_OF:
350     return "ADDRESS_OF";
351   case GET_VALUE_AT_ADDRESS:
352     return "GET_VALUE_AT_ADDRESS";
353   case SPIL:
354     return "SPIL";
355   case UNSPIL:
356     return "UNSPIL";
357   case GETHBIT:
358     return "GETHBIT";
359   case BITWISEAND:
360     return "BITWISEAND";
361   case UNARYMINUS:
362     return "UNARYMINUS";
363   case IPUSH:
364     return "IPUSH";
365   case IPOP:
366     return "IPOP";
367   case PCALL:
368     return "PCALL";
369   case ENDFUNCTION:
370     return "ENDFUNCTION";
371   case JUMPTABLE:
372     return "JUMPTABLE";
373   case RRC:
374     return "RRC";
375   case RLC:
376     return "RLC";
377   case CAST:
378     return "CAST";
379   case CALL:
380     return "CALL";
381   case PARAM:
382     return "PARAM  ";
383   case NULLOP:
384     return "NULLOP";
385   case BLOCK:
386     return "BLOCK";
387   case LABEL:
388     return "LABEL";
389   case RECEIVE:
390     return "RECEIVE";
391   case SEND:
392     return "SEND";
393   }
394   sprintf(buffer,"unkown op %d %c",op, op&0xff);
395   return buffer;
396 }
397 /*-----------------------------------------------------------------*/
398 /*-----------------------------------------------------------------*/
399 static char * debugLogRegType(short type)
400 {
401
402   switch(type) {
403   case REG_GPR:
404     return "REG_GPR";
405   case REG_PTR:
406     return "REG_PTR";
407   case REG_CND:
408     return "REG_CND";
409   }
410
411   sprintf(buffer,"unkown reg type %d",type);
412   return buffer;
413 }
414
415 /*-----------------------------------------------------------------*/
416 /* allocReg - allocates register of given type                     */
417 /*-----------------------------------------------------------------*/
418 static regs *allocReg (short type)
419 {
420     int i;
421
422     debugLog("%s of type %s\n",__FUNCTION__,debugLogRegType(type));
423
424     for ( i = 0 ; i < pic14_nRegs ; i++ ) {
425
426         /* if type is given as 0 then any
427            free register will do */
428         if (!type &&
429             regspic14[i].isFree ) {
430             regspic14[i].isFree = 0;
431             regspic14[i].wasUsed = 1;
432             if (currFunc)
433                 currFunc->regsUsed = 
434                     bitVectSetBit(currFunc->regsUsed,i);
435             debugLog("  returning %s\n",regspic14[i].name);
436             return &regspic14[i];
437         }
438         /* other wise look for specific type
439            of register */
440         if (regspic14[i].isFree && 
441             regspic14[i].type == type) {
442             regspic14[i].isFree = 0;
443             regspic14[i].wasUsed = 1;
444             if (currFunc)
445                 currFunc->regsUsed = 
446                     bitVectSetBit(currFunc->regsUsed,i);
447             debugLog("  returning %s\n",regspic14[i].name);
448             return &regspic14[i];
449         }
450     }
451     return NULL;
452 }
453
454 /*-----------------------------------------------------------------*/
455 /* pic14_regWithIdx - returns pointer to register wit index number       */
456 /*-----------------------------------------------------------------*/
457 regs *pic14_regWithIdx (int idx)
458 {
459     int i ;
460     
461     debugLog("%s\n",__FUNCTION__);
462
463     for (i=0;i < pic14_nRegs;i++)
464         if (regspic14[i].rIdx == idx)
465             return &regspic14[i];
466
467     return &regspic14[0];
468
469     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
470            "regWithIdx not found");
471     exit(1);
472 }
473
474 /*-----------------------------------------------------------------*/
475 /* freeReg - frees a register                                      */
476 /*-----------------------------------------------------------------*/
477 static void freeReg (regs *reg)
478 {
479     debugLog("%s\n",__FUNCTION__);
480     reg->isFree = 1;
481 }
482
483
484 /*-----------------------------------------------------------------*/
485 /* nFreeRegs - returns number of free registers                    */
486 /*-----------------------------------------------------------------*/
487 static int nFreeRegs (int type)
488 {
489     int i;
490     int nfr=0;
491     
492     debugLog("%s\n",__FUNCTION__);
493     for (i = 0 ; i < pic14_nRegs; i++ )
494         if (regspic14[i].isFree && regspic14[i].type == type)
495             nfr++;
496     return nfr;
497 }
498
499 /*-----------------------------------------------------------------*/
500 /* nfreeRegsType - free registers with type                         */
501 /*-----------------------------------------------------------------*/
502 static int nfreeRegsType (int type)
503 {
504     int nfr ;
505     debugLog("%s\n",__FUNCTION__);
506     if (type == REG_PTR) {
507         if ((nfr = nFreeRegs(type)) == 0)
508             return nFreeRegs(REG_GPR);
509     } 
510     
511     return nFreeRegs(type);
512 }
513
514
515 /*-----------------------------------------------------------------*/
516 /* allDefsOutOfRange - all definitions are out of a range          */
517 /*-----------------------------------------------------------------*/
518 static bool allDefsOutOfRange (bitVect *defs,int fseq, int toseq) 
519 {
520     int i ;
521
522     debugLog("%s\n",__FUNCTION__);
523     if (!defs)
524         return TRUE ;
525
526     for ( i = 0 ;i < defs->size ; i++ ) {
527         iCode *ic;
528
529         if (bitVectBitValue(defs,i)             &&
530             (ic = hTabItemWithKey(iCodehTab,i)) &&
531             ( ic->seq >= fseq  && ic->seq <= toseq))
532             
533             return FALSE;
534         
535     }
536     
537     return TRUE;
538 }
539   
540 /*-----------------------------------------------------------------*/
541 /* computeSpillable - given a point find the spillable live ranges */
542 /*-----------------------------------------------------------------*/
543 static bitVect *computeSpillable (iCode *ic)
544 {
545     bitVect *spillable ;
546
547     debugLog("%s\n",__FUNCTION__);
548     /* spillable live ranges are those that are live at this 
549        point . the following categories need to be subtracted
550        from this set. 
551        a) - those that are already spilt
552        b) - if being used by this one
553        c) - defined by this one */
554     
555     spillable = bitVectCopy(ic->rlive);
556     spillable = 
557         bitVectCplAnd(spillable,_G.spiltSet); /* those already spilt */
558     spillable = 
559         bitVectCplAnd(spillable,ic->uses); /* used in this one */    
560     bitVectUnSetBit(spillable,ic->defKey);
561     spillable = bitVectIntersect(spillable,_G.regAssigned);
562     return spillable;
563     
564 }
565
566 /*-----------------------------------------------------------------*/
567 /* noSpilLoc - return true if a variable has no spil location      */
568 /*-----------------------------------------------------------------*/
569 static int noSpilLoc (symbol *sym, eBBlock *ebp,iCode *ic)
570 {
571     debugLog("%s\n",__FUNCTION__);
572     return (sym->usl.spillLoc ? 0 : 1);
573 }
574
575 /*-----------------------------------------------------------------*/
576 /* hasSpilLoc - will return 1 if the symbol has spil location      */
577 /*-----------------------------------------------------------------*/
578 static int hasSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
579 {
580     debugLog("%s\n",__FUNCTION__);
581     return (sym->usl.spillLoc ? 1 : 0);
582 }
583
584 /*-----------------------------------------------------------------*/
585 /* directSpilLoc - will return 1 if the splilocation is in direct  */
586 /*-----------------------------------------------------------------*/
587 static int directSpilLoc (symbol *sym, eBBlock *ebp, iCode *ic)
588 {
589     debugLog("%s\n",__FUNCTION__);
590     if ( sym->usl.spillLoc &&
591          (IN_DIRSPACE(SPEC_OCLS(sym->usl.spillLoc->etype))))
592         return 1;
593     else
594         return 0;
595 }
596
597 /*-----------------------------------------------------------------*/
598 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location*/
599 /*                    but is not used as a pointer                 */
600 /*-----------------------------------------------------------------*/
601 static int hasSpilLocnoUptr (symbol *sym, eBBlock *ebp, iCode *ic)
602 {
603     debugLog("%s\n",__FUNCTION__);
604     return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
605 }
606
607 /*-----------------------------------------------------------------*/
608 /* rematable - will return 1 if the remat flag is set              */
609 /*-----------------------------------------------------------------*/
610 static int rematable (symbol *sym, eBBlock *ebp, iCode *ic)
611 {
612     debugLog("%s\n",__FUNCTION__);
613     return sym->remat;
614 }
615
616 /*-----------------------------------------------------------------*/
617 /* notUsedInBlock - not used in this block                         */
618 /*-----------------------------------------------------------------*/
619 static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
620 {   
621     debugLog("%s\n",__FUNCTION__);
622     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs) &&
623             allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
624 /*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
625 }
626
627 /*-----------------------------------------------------------------*/
628 /* notUsedInRemaining - not used or defined in remain of the block */
629 /*-----------------------------------------------------------------*/
630 static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
631 {
632     debugLog("%s\n",__FUNCTION__);
633     return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
634             allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq));
635 }
636
637 /*-----------------------------------------------------------------*/
638 /* allLRs - return true for all                                    */
639 /*-----------------------------------------------------------------*/
640 static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
641 {
642     debugLog("%s\n",__FUNCTION__);
643     return 1;
644 }
645
646 /*-----------------------------------------------------------------*/
647 /* liveRangesWith - applies function to a given set of live range  */
648 /*-----------------------------------------------------------------*/
649 static set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
650                      eBBlock *ebp, iCode *ic)
651 {
652     set *rset = NULL;
653     int i;
654
655     debugLog("%s\n",__FUNCTION__);
656     if (!lrs || !lrs->size)
657         return NULL;
658
659     for ( i = 1 ; i < lrs->size ; i++ ) {
660         symbol *sym;
661         if (!bitVectBitValue(lrs,i))
662             continue ;
663
664         /* if we don't find it in the live range 
665            hash table we are in serious trouble */
666         if (!(sym = hTabItemWithKey(liveRanges,i))) {
667             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
668                    "liveRangesWith could not find liveRange");
669             exit(1);
670         }
671         
672         if (func(sym,ebp,ic) && bitVectBitValue(_G.regAssigned,sym->key))
673             addSetHead(&rset,sym);
674     }
675
676     return rset;
677 }
678
679
680 /*-----------------------------------------------------------------*/
681 /* leastUsedLR - given a set determines which is the least used    */
682 /*-----------------------------------------------------------------*/
683 static symbol *leastUsedLR (set *sset)
684 {
685     symbol *sym = NULL, *lsym = NULL ;
686     
687     debugLog("%s\n",__FUNCTION__);
688     sym = lsym = setFirstItem(sset);
689
690     if (!lsym)
691         return NULL;
692
693     for (; lsym; lsym = setNextItem(sset)) {
694         
695         /* if usage is the same then prefer
696            the spill the smaller of the two */
697         if ( lsym->used == sym->used )
698             if (getSize(lsym->type) < getSize(sym->type))
699                 sym = lsym;
700
701         /* if less usage */
702         if (lsym->used < sym->used )
703             sym = lsym;
704         
705    }
706
707     setToNull((void **)&sset);
708     sym->blockSpil = 0;
709     return sym;
710 }
711
712 /*-----------------------------------------------------------------*/
713 /* noOverLap - will iterate through the list looking for over lap  */
714 /*-----------------------------------------------------------------*/
715 static int noOverLap (set *itmpStack, symbol *fsym)
716 {
717     symbol *sym;
718     debugLog("%s\n",__FUNCTION__);
719    
720
721     for (sym = setFirstItem(itmpStack); sym;
722          sym = setNextItem(itmpStack)) {
723         if (sym->liveTo > fsym->liveFrom )
724             return 0;
725             
726     }
727
728     return 1;
729 }
730
731 /*-----------------------------------------------------------------*/
732 /* isFree - will return 1 if the a free spil location is found     */
733 /*-----------------------------------------------------------------*/
734 static DEFSETFUNC(isFree)
735 {
736     symbol *sym = item;
737     V_ARG(symbol **,sloc);
738     V_ARG(symbol *,fsym);
739
740     debugLog("%s\n",__FUNCTION__);
741     /* if already found */
742     if (*sloc)
743         return 0;
744
745     /* if it is free && and the itmp assigned to
746        this does not have any overlapping live ranges
747        with the one currently being assigned and
748        the size can be accomodated  */
749     if (sym->isFree                        && 
750         noOverLap(sym->usl.itmpStack,fsym) &&
751         getSize(sym->type) >= getSize(fsym->type)) {
752         *sloc = sym;
753         return 1;
754     }
755
756     return 0;
757 }
758
759 /*-----------------------------------------------------------------*/
760 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
761 /*-----------------------------------------------------------------*/
762 static void spillLRWithPtrReg (symbol *forSym)
763 {
764     symbol *lrsym;
765     regs *r0,*r1;
766     int k;
767
768     debugLog("%s\n",__FUNCTION__);
769     if (!_G.regAssigned ||
770         bitVectIsZero(_G.regAssigned))
771         return;
772
773     r0 = pic14_regWithIdx(R0_IDX);
774     r1 = pic14_regWithIdx(R1_IDX);
775
776     /* for all live ranges */
777     for (lrsym = hTabFirstItem(liveRanges,&k) ; lrsym ; 
778          lrsym = hTabNextItem(liveRanges,&k) ) {
779         int j;       
780
781         /* if no registers assigned to it or
782            spilt */
783         /* if it does not overlap with this then 
784            not need to spill it */
785
786         if (lrsym->isspilt || !lrsym->nRegs ||
787             (lrsym->liveTo < forSym->liveFrom))
788             continue ;
789
790         /* go thru the registers : if it is either
791            r0 or r1 then spil it */
792         for (j = 0 ; j < lrsym->nRegs ; j++ ) 
793             if (lrsym->regs[j] == r0 ||
794                 lrsym->regs[j] == r1 ) {
795                 spillThis (lrsym);
796                 break;
797             }
798     }
799
800 }
801
802 /*-----------------------------------------------------------------*/
803 /* createStackSpil - create a location on the stack to spil        */
804 /*-----------------------------------------------------------------*/
805 static symbol *createStackSpil (symbol *sym)
806 {
807     symbol *sloc= NULL;
808     int useXstack, model, noOverlay;
809
810     char slocBuffer[30];
811     debugLog("%s\n",__FUNCTION__);
812
813     /* first go try and find a free one that is already 
814        existing on the stack */
815     if (applyToSet(_G.stackSpil,isFree,&sloc, sym)) {
816         /* found a free one : just update & return */
817         sym->usl.spillLoc = sloc;
818         sym->stackSpil= 1;
819         sloc->isFree = 0;
820         addSetHead(&sloc->usl.itmpStack,sym);
821         return sym;
822     }
823
824     /* could not then have to create one , this is the hard part
825        we need to allocate this on the stack : this is really a
826        hack!! but cannot think of anything better at this time */
827         
828     if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer))
829     {
830         fprintf(stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
831                 __FILE__, __LINE__);
832         exit(1);        
833     }
834
835     sloc = newiTemp(slocBuffer);
836
837     /* set the type to the spilling symbol */
838     sloc->type = copyLinkChain(sym->type);
839     sloc->etype = getSpec(sloc->type);
840     SPEC_SCLS(sloc->etype) = S_DATA ;
841     SPEC_EXTR(sloc->etype) = 0;
842
843     /* we don't allow it to be allocated`
844        onto the external stack since : so we
845        temporarily turn it off ; we also
846        turn off memory model to prevent
847        the spil from going to the external storage
848        and turn off overlaying 
849     */
850     
851     useXstack = options.useXstack;
852     model = options.model;
853     noOverlay = options.noOverlay;
854     options.noOverlay = 1;
855     options.model = options.useXstack = 0;
856
857     allocLocal(sloc);
858
859     options.useXstack = useXstack;
860     options.model     = model;
861     options.noOverlay = noOverlay;
862     sloc->isref = 1; /* to prevent compiler warning */
863     
864     /* if it is on the stack then update the stack */
865     if (IN_STACK(sloc->etype)) {
866         currFunc->stack += getSize(sloc->type);
867         _G.stackExtend += getSize(sloc->type);
868     } else
869         _G.dataExtend += getSize(sloc->type);
870
871     /* add it to the _G.stackSpil set */
872     addSetHead(&_G.stackSpil,sloc);
873     sym->usl.spillLoc = sloc;
874     sym->stackSpil = 1;
875     
876     /* add it to the set of itempStack set 
877        of the spill location */
878     addSetHead(&sloc->usl.itmpStack,sym);
879     return sym;
880 }
881
882 /*-----------------------------------------------------------------*/
883 /* isSpiltOnStack - returns true if the spil location is on stack  */
884 /*-----------------------------------------------------------------*/
885 static bool isSpiltOnStack (symbol *sym)
886 {
887     sym_link *etype;
888
889     debugLog("%s\n",__FUNCTION__);
890     if (!sym)
891         return FALSE ;
892     
893     if (!sym->isspilt)
894         return FALSE ;
895
896 /*     if (sym->_G.stackSpil) */
897 /*      return TRUE; */
898     
899     if (!sym->usl.spillLoc)
900         return FALSE;
901
902     etype = getSpec(sym->usl.spillLoc->type);
903     if (IN_STACK(etype))
904         return TRUE;
905
906     return FALSE ;
907 }
908
909 /*-----------------------------------------------------------------*/
910 /* spillThis - spils a specific operand                            */
911 /*-----------------------------------------------------------------*/
912 static void spillThis (symbol *sym)
913 {
914     int i;
915     debugLog("%s : %s\n",__FUNCTION__, sym->rname);
916
917     /* if this is rematerializable or has a spillLocation
918        we are okay, else we need to create a spillLocation
919        for it */
920     if (!(sym->remat || sym->usl.spillLoc)) 
921         createStackSpil (sym);
922     
923
924     /* mark it has spilt & put it in the spilt set */
925     sym->isspilt = 1;
926     _G.spiltSet = bitVectSetBit(_G.spiltSet,sym->key);
927        
928     bitVectUnSetBit(_G.regAssigned,sym->key);
929
930     for (i = 0 ; i < sym->nRegs ; i++)
931
932         if (sym->regs[i]) {
933             freeReg(sym->regs[i]);
934             sym->regs[i] = NULL;
935         }
936     
937     /* if spilt on stack then free up r0 & r1 
938        if they could have been assigned to some
939        LIVE ranges */
940     if (!pic14_ptrRegReq && isSpiltOnStack(sym)) {
941         pic14_ptrRegReq++ ;
942         spillLRWithPtrReg(sym);
943     }
944
945     if (sym->usl.spillLoc && !sym->remat)
946         sym->usl.spillLoc->allocreq = 1;
947     return;
948 }
949
950 /*-----------------------------------------------------------------*/
951 /* selectSpil - select a iTemp to spil : rather a simple procedure */
952 /*-----------------------------------------------------------------*/
953 static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
954 {
955     bitVect *lrcs= NULL ; 
956     set *selectS ;
957     symbol *sym;
958
959     debugLog("%s\n",__FUNCTION__);
960     /* get the spillable live ranges */
961     lrcs = computeSpillable (ic);
962
963     /* get all live ranges that are rematerizable */
964     if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) {
965
966         /* return the least used of these */
967         return leastUsedLR(selectS);
968     }
969
970     /* get live ranges with spillLocations in direct space */
971     if ((selectS = liveRangesWith(lrcs,directSpilLoc,ebp,ic))) {
972         sym = leastUsedLR(selectS);
973         strcpy(sym->rname,(sym->usl.spillLoc->rname[0] ? 
974                            sym->usl.spillLoc->rname : 
975                            sym->usl.spillLoc->name)); 
976         sym->spildir = 1;
977         /* mark it as allocation required */
978         sym->usl.spillLoc->allocreq = 1;
979         return sym;
980     }
981
982     /* if the symbol is local to the block then */
983     if (forSym->liveTo < ebp->lSeq) {       
984
985         /* check if there are any live ranges allocated
986            to registers that are not used in this block */
987         if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInBlock,ebp,ic))) {
988             sym = leastUsedLR(selectS);
989             /* if this is not rematerializable */
990             if (!sym->remat) {
991                 _G.blockSpil++;
992                 sym->blockSpil = 1;
993             }
994             return sym;
995         } 
996
997         /* check if there are any live ranges that not
998            used in the remainder of the block */
999         if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
1000             sym = leastUsedLR (selectS);
1001             if (!sym->remat) {
1002                 sym->remainSpil = 1;
1003                 _G.blockSpil++;
1004             }
1005             return sym;
1006         }
1007     }   
1008
1009     /* find live ranges with spillocation && not used as pointers */
1010     if ((selectS = liveRangesWith(lrcs,hasSpilLocnoUptr,ebp,ic))) {
1011        
1012         sym =  leastUsedLR(selectS);
1013         /* mark this as allocation required */
1014         sym->usl.spillLoc->allocreq = 1;
1015         return sym;
1016     }
1017
1018     /* find live ranges with spillocation */
1019     if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) {
1020         
1021         sym = leastUsedLR(selectS);
1022         sym->usl.spillLoc->allocreq = 1;
1023         return sym;
1024     }
1025
1026     /* couldn't find then we need to create a spil
1027        location on the stack , for which one? the least
1028        used ofcourse */
1029     if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) {
1030         
1031         /* return a created spil location */
1032         sym = createStackSpil(leastUsedLR(selectS));
1033         sym->usl.spillLoc->allocreq = 1;
1034         return sym;
1035     }
1036     
1037     /* this is an extreme situation we will spill
1038        this one : happens very rarely but it does happen */
1039     spillThis ( forSym );
1040     return forSym ;
1041    
1042 }
1043
1044 /*-----------------------------------------------------------------*/
1045 /* spilSomething - spil some variable & mark registers as free     */
1046 /*-----------------------------------------------------------------*/
1047 static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
1048 {
1049     symbol *ssym;
1050     int i ;
1051
1052     debugLog("%s\n",__FUNCTION__);
1053     /* get something we can spil */
1054     ssym = selectSpil(ic,ebp,forSym);
1055     
1056     /* mark it as spilt */
1057     ssym->isspilt = 1;
1058     _G.spiltSet = bitVectSetBit(_G.spiltSet,ssym->key);
1059     
1060     /* mark it as not register assigned &
1061        take it away from the set */   
1062     bitVectUnSetBit(_G.regAssigned,ssym->key);
1063  
1064     /* mark the registers as free */    
1065     for (i = 0 ; i < ssym->nRegs ;i++ )
1066         if (ssym->regs[i])
1067             freeReg(ssym->regs[i]);
1068      
1069     /* if spilt on stack then free up r0 & r1 
1070        if they could have been assigned to as gprs */
1071     if (!pic14_ptrRegReq && isSpiltOnStack(ssym) ) {
1072         pic14_ptrRegReq++ ;
1073         spillLRWithPtrReg(ssym);
1074     }
1075
1076     /* if this was a block level spil then insert push & pop 
1077        at the start & end of block respectively */
1078     if (ssym->blockSpil) {
1079         iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
1080         /* add push to the start of the block */
1081         addiCodeToeBBlock(ebp,nic,( ebp->sch->op == LABEL ? 
1082                                     ebp->sch->next : ebp->sch));
1083         nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
1084         /* add pop to the end of the block */
1085         addiCodeToeBBlock(ebp,nic,NULL);
1086     }       
1087
1088     /* if spilt because not used in the remainder of the
1089        block then add a push before this instruction and
1090        a pop at the end of the block */
1091     if (ssym->remainSpil) {
1092
1093         iCode *nic = newiCode(IPUSH,operandFromSymbol(ssym),NULL);
1094         /* add push just before this instruction */
1095         addiCodeToeBBlock(ebp,nic,ic);
1096                                     
1097         nic = newiCode(IPOP,operandFromSymbol(ssym),NULL);
1098         /* add pop to the end of the block */
1099         addiCodeToeBBlock(ebp,nic,NULL);    
1100     }
1101
1102     if (ssym == forSym )
1103         return FALSE ;
1104     else
1105         return TRUE ;
1106 }
1107
1108 /*-----------------------------------------------------------------*/
1109 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1110 /*-----------------------------------------------------------------*/
1111 static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
1112 {
1113     regs *reg;
1114
1115     debugLog("%s\n",__FUNCTION__);
1116  tryAgain:
1117     /* try for a ptr type */
1118     if ((reg = allocReg(REG_PTR))) 
1119         return reg;    
1120
1121     /* try for gpr type */
1122     if ((reg = allocReg(REG_GPR)))        
1123         return reg;    
1124
1125     /* we have to spil */
1126     if (!spilSomething (ic,ebp,sym))
1127         return NULL ;
1128
1129     /* this looks like an infinite loop but 
1130        in really selectSpil will abort  */
1131     goto tryAgain ;    
1132 }
1133
1134 /*-----------------------------------------------------------------*/
1135 /* getRegGpr - will try for GPR if not spil                        */
1136 /*-----------------------------------------------------------------*/
1137 static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
1138 {
1139     regs *reg;
1140
1141     debugLog("%s\n",__FUNCTION__);
1142  tryAgain:
1143     /* try for gpr type */
1144     if ((reg = allocReg(REG_GPR)))        
1145         return reg;    
1146
1147     if (!pic14_ptrRegReq)
1148         if ((reg = allocReg(REG_PTR)))
1149             return reg ;
1150         
1151     /* we have to spil */
1152     if (!spilSomething (ic,ebp,sym))
1153         return NULL ;
1154
1155     /* this looks like an infinite loop but 
1156        in really selectSpil will abort  */
1157     goto tryAgain ;    
1158 }
1159
1160 /*-----------------------------------------------------------------*/
1161 /* symHasReg - symbol has a given register                         */
1162 /*-----------------------------------------------------------------*/
1163 static bool symHasReg(symbol *sym,regs *reg)
1164 {
1165     int i;
1166
1167     debugLog("%s\n",__FUNCTION__);
1168     for ( i = 0 ; i < sym->nRegs ; i++)
1169         if (sym->regs[i] == reg)
1170             return TRUE;
1171             
1172     return FALSE;
1173 }
1174
1175 /*-----------------------------------------------------------------*/
1176 /* deassignLRs - check the live to and if they have registers & are*/
1177 /*               not spilt then free up the registers              */
1178 /*-----------------------------------------------------------------*/
1179 static void deassignLRs (iCode *ic, eBBlock *ebp)
1180 {
1181     symbol *sym;
1182     int k;
1183     symbol *result;
1184
1185     debugLog("%s\n",__FUNCTION__);
1186     for (sym = hTabFirstItem(liveRanges,&k); sym;
1187          sym = hTabNextItem(liveRanges,&k)) {
1188         
1189         symbol *psym= NULL;
1190         /* if it does not end here */
1191         if (sym->liveTo > ic->seq )
1192             continue ;
1193
1194         /* if it was spilt on stack then we can 
1195            mark the stack spil location as free */
1196         if (sym->isspilt ) {
1197             if (sym->stackSpil) {
1198                 sym->usl.spillLoc->isFree = 1;
1199                 sym->stackSpil = 0;
1200             }
1201             continue ;
1202         }
1203         
1204         if (!bitVectBitValue(_G.regAssigned,sym->key))
1205             continue;
1206         
1207         /* special case check if this is an IFX &
1208            the privious one was a pop and the 
1209            previous one was not spilt then keep track
1210            of the symbol */     
1211         if (ic->op == IFX && ic->prev &&
1212             ic->prev->op == IPOP && 
1213             !ic->prev->parmPush  &&
1214             !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt) 
1215             psym = OP_SYMBOL(IC_LEFT(ic->prev));
1216
1217         if (sym->nRegs) {
1218             int i = 0;
1219             
1220             bitVectUnSetBit(_G.regAssigned,sym->key);
1221
1222             /* if the result of this one needs registers
1223                and does not have it then assign it right
1224                away */
1225             if (IC_RESULT(ic) &&
1226                 !  (SKIP_IC2(ic) ||               /* not a special icode */
1227                     ic->op == JUMPTABLE ||
1228                     ic->op == IFX ||
1229                     ic->op == IPUSH ||
1230                     ic->op == IPOP ||
1231                     ic->op == RETURN ||
1232                     POINTER_SET(ic))     &&             
1233                 (result = OP_SYMBOL(IC_RESULT(ic))) && /* has a result */
1234                 result->liveTo > ic->seq &&            /* and will live beyond this */
1235                 result->liveTo <= ebp->lSeq &&         /* does not go beyond this block */
1236                 result->regType == sym->regType &&     /* same register types */
1237                 result->nRegs            &&            /* which needs registers */
1238                 ! result->isspilt        &&            /* and does not already have them */
1239                 ! result->remat          &&
1240                 ! bitVectBitValue(_G.regAssigned,result->key) &&
1241                 /* the number of free regs + number of regs in this LR
1242                    can accomodate the what result Needs */
1243                 ((nfreeRegsType(result->regType) +
1244                   sym->nRegs) >= result->nRegs)
1245                 ) {
1246                 
1247                 for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++)
1248                     if (i < sym->nRegs )
1249                         result->regs[i] = sym->regs[i] ;
1250                     else
1251                         result->regs[i] = getRegGpr (ic,ebp,result);
1252
1253                 _G.regAssigned = bitVectSetBit(_G.regAssigned,result->key);
1254                 
1255             }                   
1256             
1257             /* free the remaining */
1258             for (; i < sym->nRegs ; i++) {
1259                 if (psym) {
1260                     if (!symHasReg(psym,sym->regs[i]))
1261                         freeReg(sym->regs[i]);
1262                 } else
1263                     freeReg(sym->regs[i]);
1264             }
1265         }
1266     }
1267 }
1268
1269
1270 /*-----------------------------------------------------------------*/
1271 /* reassignLR - reassign this to registers                         */
1272 /*-----------------------------------------------------------------*/
1273 static void reassignLR (operand *op)
1274 {
1275     symbol *sym = OP_SYMBOL(op);
1276     int i;
1277
1278     debugLog("%s\n",__FUNCTION__);
1279     /* not spilt any more */     
1280     sym->isspilt = sym->blockSpil  = sym->remainSpil = 0;
1281     bitVectUnSetBit(_G.spiltSet,sym->key);
1282       
1283     _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1284
1285     _G.blockSpil--;
1286
1287     for (i=0;i<sym->nRegs;i++)
1288         sym->regs[i]->isFree = 0;
1289 }
1290
1291 /*-----------------------------------------------------------------*/
1292 /* willCauseSpill - determines if allocating will cause a spill    */
1293 /*-----------------------------------------------------------------*/
1294 static int willCauseSpill ( int nr, int rt)
1295 {
1296     debugLog("%s\n",__FUNCTION__);
1297     /* first check if there are any avlb registers
1298        of te type required */
1299     if (rt == REG_PTR) {
1300         /* special case for pointer type 
1301            if pointer type not avlb then 
1302            check for type gpr */
1303         if (nFreeRegs(rt) >= nr)
1304             return 0;
1305         if (nFreeRegs(REG_GPR) >= nr)
1306             return 0;
1307     } else {
1308         if (pic14_ptrRegReq) {
1309             if (nFreeRegs(rt) >= nr)
1310                 return 0;
1311         } else {
1312             if (nFreeRegs(REG_PTR) +
1313                 nFreeRegs(REG_GPR) >= nr)
1314                 return 0;
1315         }
1316     }
1317
1318     debugLog(" ... yep it will (cause a spill)\n");
1319     /* it will cause a spil */
1320     return 1;
1321 }
1322
1323 /*-----------------------------------------------------------------*/
1324 /* positionRegs - the allocator can allocate same registers to res-*/
1325 /* ult and operand, if this happens make sure they are in the same */
1326 /* position as the operand otherwise chaos results                 */
1327 /*-----------------------------------------------------------------*/
1328 static void positionRegs (symbol *result, symbol *opsym, int lineno)
1329 {
1330         int count = min(result->nRegs,opsym->nRegs);
1331         int i , j = 0, shared = 0;
1332
1333     debugLog("%s\n",__FUNCTION__);
1334         /* if the result has been spilt then cannot share */
1335         if (opsym->isspilt)
1336                 return ;
1337  again:
1338         shared = 0;
1339         /* first make sure that they actually share */
1340         for ( i = 0 ; i < count; i++ ) {
1341                 for (j = 0 ; j < count ; j++ ) {
1342                         if (result->regs[i] == opsym->regs[j] && i !=j) {
1343                                 shared = 1;
1344                                 goto xchgPositions;
1345                         }
1346                 }
1347         }
1348  xchgPositions:
1349         if (shared) {
1350                 regs *tmp = result->regs[i];
1351                 result->regs[i] = result->regs[j];
1352                 result->regs[j] = tmp;          
1353                 goto again;
1354         }
1355 }
1356
1357 /*-----------------------------------------------------------------*/
1358 /* serialRegAssign - serially allocate registers to the variables  */
1359 /*-----------------------------------------------------------------*/
1360 static void serialRegAssign (eBBlock **ebbs, int count)
1361 {
1362     int i;
1363
1364     debugLog("%s\n",__FUNCTION__);
1365     /* for all blocks */
1366     for (i = 0; i < count ; i++ ) {
1367         
1368         iCode *ic;
1369         
1370         if (ebbs[i]->noPath &&
1371             (ebbs[i]->entryLabel != entryLabel &&
1372              ebbs[i]->entryLabel != returnLabel ))
1373             continue ;
1374
1375         /* of all instructions do */
1376         for (ic = ebbs[i]->sch ; ic ; ic = ic->next) {
1377          
1378           debugLog("  op: %s\n", decodeOp(ic->op));
1379
1380             /* if this is an ipop that means some live
1381                range will have to be assigned again */
1382             if (ic->op == IPOP)
1383                 reassignLR (IC_LEFT(ic));
1384
1385             /* if result is present && is a true symbol */
1386             if (IC_RESULT(ic) && ic->op != IFX &&
1387                 IS_TRUE_SYMOP(IC_RESULT(ic)))
1388                 OP_SYMBOL(IC_RESULT(ic))->allocreq = 1;
1389
1390             /* take away registers from live
1391                ranges that end at this instruction */      
1392             deassignLRs (ic, ebbs[i]) ;         
1393                     
1394             /* some don't need registers */
1395             if (SKIP_IC2(ic) ||
1396                 ic->op == JUMPTABLE ||
1397                 ic->op == IFX ||
1398                 ic->op == IPUSH ||
1399                 ic->op == IPOP ||
1400                 (IC_RESULT(ic) &&POINTER_SET(ic)) )
1401                 continue;   
1402             
1403             /* now we need to allocate registers
1404                only for the result */
1405             if (IC_RESULT(ic)) {
1406                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
1407                 bitVect *spillable;
1408                 int willCS ;
1409                 int j;
1410                 int ptrRegSet = 0;
1411                                
1412                 /* if it does not need or is spilt 
1413                    or is already assigned to registers
1414                    or will not live beyond this instructions */
1415                 if (!sym->nRegs      || 
1416                     sym->isspilt     || 
1417                     bitVectBitValue(_G.regAssigned,sym->key) ||
1418                     sym->liveTo <= ic->seq)
1419                     continue ;
1420
1421                 /* if some liverange has been spilt at the block level
1422                    and this one live beyond this block then spil this
1423                    to be safe */
1424                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq) {
1425                     spillThis (sym);
1426                     continue ;
1427                 }
1428                 /* if trying to allocate this will cause
1429                    a spill and there is nothing to spill 
1430                    or this one is rematerializable then
1431                    spill this one */
1432                 willCS = willCauseSpill(sym->nRegs,sym->regType);
1433                 spillable = computeSpillable(ic);
1434                 if ( sym->remat ||                  
1435                     (willCS  && bitVectIsZero(spillable) ) ) {
1436
1437                     spillThis (sym) ;
1438                     continue ;
1439
1440                 }
1441
1442                 /* if it has a spillocation & is used less than
1443                    all other live ranges then spill this */
1444                 if ( willCS && sym->usl.spillLoc ) {
1445
1446                     symbol *leastUsed = 
1447                         leastUsedLR(liveRangesWith (spillable ,
1448                                                     allLRs,
1449                                                     ebbs[i],
1450                                                     ic));
1451                     if (leastUsed && 
1452                         leastUsed->used > sym->used) {
1453                         spillThis (sym);
1454                         continue;
1455                     }
1456                 }               
1457                 
1458                 if(ic->op == RECEIVE)
1459                   debugLog("When I get clever, I'll optimize the receive logic\n");
1460
1461                 /* if we need ptr regs for the right side
1462                    then mark it */
1463                 if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) 
1464                     <= PTRSIZE) 
1465                 {
1466                     pic14_ptrRegReq++;
1467                     ptrRegSet = 1;
1468                 }
1469                 /* else we assign registers to it */            
1470                 _G.regAssigned = bitVectSetBit(_G.regAssigned,sym->key);
1471
1472           debugLog("  %d - \n",__LINE__);
1473
1474                 for (j = 0 ; j < sym->nRegs ;j++ ) {
1475                     if (sym->regType == REG_PTR)
1476                         sym->regs[j] = getRegPtr(ic,ebbs[i],sym);
1477                     else
1478                         sym->regs[j] = getRegGpr(ic,ebbs[i],sym);
1479
1480                     /* if the allocation falied which means
1481                        this was spilt then break */
1482                     if (!sym->regs[j])
1483                         break;
1484                 }
1485           debugLog("  %d - \n",__LINE__);
1486
1487                 /* if it shares registers with operands make sure
1488                    that they are in the same position */
1489                 if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
1490                     OP_SYMBOL(IC_LEFT(ic))->nRegs  && ic->op != '=')
1491                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1492                                      OP_SYMBOL(IC_LEFT(ic)),ic->lineno);
1493                 /* do the same for the right operand */
1494                 if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
1495                     OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=')
1496                         positionRegs(OP_SYMBOL(IC_RESULT(ic)),
1497                                      OP_SYMBOL(IC_RIGHT(ic)),ic->lineno);
1498                 
1499           debugLog("  %d - \n",__LINE__);
1500                 if (ptrRegSet) {
1501           debugLog("  %d - \n",__LINE__);
1502                     pic14_ptrRegReq--;
1503                     ptrRegSet = 0;
1504                 }
1505                                 
1506             }       
1507         }
1508     }
1509 }
1510
1511 /*-----------------------------------------------------------------*/
1512 /* rUmaskForOp :- returns register mask for an operand             */
1513 /*-----------------------------------------------------------------*/
1514 static bitVect *rUmaskForOp (operand *op)
1515 {
1516     bitVect *rumask;
1517     symbol *sym;
1518     int j;
1519     
1520     debugLog("%s\n",__FUNCTION__);
1521     /* only temporaries are assigned registers */
1522     if (!IS_ITEMP(op)) 
1523         return NULL;
1524
1525     sym = OP_SYMBOL(op);
1526     
1527     /* if spilt or no registers assigned to it
1528        then nothing */
1529     if (sym->isspilt || !sym->nRegs)
1530         return NULL;
1531
1532     rumask = newBitVect(pic14_nRegs);
1533
1534     for (j = 0; j < sym->nRegs; j++) {  
1535         rumask = bitVectSetBit(rumask,
1536                                sym->regs[j]->rIdx);
1537     }
1538
1539     return rumask;
1540 }
1541
1542 /*-----------------------------------------------------------------*/
1543 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
1544 /*-----------------------------------------------------------------*/
1545 static bitVect *regsUsedIniCode (iCode *ic)
1546 {
1547     bitVect *rmask = newBitVect(pic14_nRegs);
1548
1549     debugLog("%s\n",__FUNCTION__);
1550     /* do the special cases first */
1551     if (ic->op == IFX ) {
1552         rmask = bitVectUnion(rmask,
1553                              rUmaskForOp(IC_COND(ic)));
1554         goto ret;
1555     }
1556
1557     /* for the jumptable */
1558     if (ic->op == JUMPTABLE) {
1559         rmask = bitVectUnion(rmask,
1560                              rUmaskForOp(IC_JTCOND(ic)));
1561
1562         goto ret;
1563     }
1564
1565     /* of all other cases */
1566     if (IC_LEFT(ic)) 
1567         rmask = bitVectUnion(rmask,
1568                              rUmaskForOp(IC_LEFT(ic)));
1569         
1570     
1571     if (IC_RIGHT(ic))
1572         rmask = bitVectUnion(rmask,
1573                              rUmaskForOp(IC_RIGHT(ic)));
1574
1575     if (IC_RESULT(ic))
1576         rmask = bitVectUnion(rmask,
1577                              rUmaskForOp(IC_RESULT(ic)));
1578
1579  ret:
1580     return rmask;
1581 }
1582
1583 /*-----------------------------------------------------------------*/
1584 /* createRegMask - for each instruction will determine the regsUsed*/
1585 /*-----------------------------------------------------------------*/
1586 static void createRegMask (eBBlock **ebbs, int count)
1587 {
1588     int i;
1589
1590     debugLog("%s\n",__FUNCTION__);
1591     /* for all blocks */
1592     for (i = 0; i < count ; i++ ) {
1593         iCode *ic ;
1594
1595         if ( ebbs[i]->noPath &&
1596              ( ebbs[i]->entryLabel != entryLabel &&
1597                ebbs[i]->entryLabel != returnLabel ))
1598             continue ;
1599
1600         /* for all instructions */
1601         for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) {
1602             
1603             int j;
1604
1605             if (SKIP_IC2(ic) || !ic->rlive)
1606                 continue ;
1607             
1608             /* first mark the registers used in this
1609                instruction */
1610             ic->rUsed = regsUsedIniCode(ic);
1611             _G.funcrUsed = bitVectUnion(_G.funcrUsed,ic->rUsed);
1612
1613             /* now create the register mask for those 
1614                registers that are in use : this is a
1615                super set of ic->rUsed */
1616             ic->rMask = newBitVect(pic14_nRegs+1);
1617
1618             /* for all live Ranges alive at this point */
1619             for (j = 1; j < ic->rlive->size; j++ ) {
1620                 symbol *sym;
1621                 int k;
1622
1623                 /* if not alive then continue */
1624                 if (!bitVectBitValue(ic->rlive,j))
1625                     continue ;
1626
1627                 /* find the live range we are interested in */
1628                 if (!(sym = hTabItemWithKey(liveRanges,j))) {
1629                     werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
1630                             "createRegMask cannot find live range");
1631                     exit(0);
1632                 }
1633
1634                 /* if no register assigned to it */
1635                 if (!sym->nRegs || sym->isspilt)
1636                     continue ;
1637
1638                 /* for all the registers allocated to it */
1639                 for (k = 0 ; k < sym->nRegs ;k++)
1640                     if (sym->regs[k])
1641                         ic->rMask =
1642                             bitVectSetBit(ic->rMask,sym->regs[k]->rIdx);
1643             }
1644         }
1645     }
1646 }
1647
1648 /*-----------------------------------------------------------------*/
1649 /* rematStr - returns the rematerialized string for a remat var    */
1650 /*-----------------------------------------------------------------*/
1651 static char *rematStr (symbol *sym)
1652 {
1653     char *s = buffer;   
1654     iCode *ic = sym->rematiCode;    
1655
1656     debugLog("%s\n",__FUNCTION__);
1657     while (1) {
1658
1659         printf("%s\n",s);
1660         /* if plus or minus print the right hand side */
1661 /*
1662         if (ic->op == '+' || ic->op == '-') {
1663             sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1664                     ic->op );
1665             s += strlen(s);
1666             ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1667             continue ;
1668         }
1669 */
1670         if (ic->op == '+' || ic->op == '-') {
1671             iCode *ric = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1672             sprintf(s,"(%s %c 0x%04x)",
1673                     OP_SYMBOL(IC_LEFT(ric))->rname,
1674                     ic->op,
1675                     (int) operandLitValue(IC_RIGHT(ic)));
1676
1677             //s += strlen(s);
1678             //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1679             //continue ;
1680             return buffer;
1681         }
1682
1683         /* we reached the end */
1684         sprintf(s,"%s\n",OP_SYMBOL(IC_LEFT(ic))->rname);
1685         break;
1686     }
1687
1688         printf("%s\n",buffer);
1689     return buffer ;
1690 }
1691
1692 /*-----------------------------------------------------------------*/
1693 /* regTypeNum - computes the type & number of registers required   */
1694 /*-----------------------------------------------------------------*/
1695 static void regTypeNum ()
1696 {
1697     symbol *sym;
1698     int k;
1699     iCode *ic;
1700
1701     debugLog("%s\n",__FUNCTION__);
1702     /* for each live range do */
1703     for ( sym = hTabFirstItem(liveRanges,&k); sym ;
1704           sym = hTabNextItem(liveRanges,&k)) {
1705
1706           debugLog("  %d - %s\n",__LINE__ , sym->rname);
1707
1708         /* if used zero times then no registers needed */
1709         if ((sym->liveTo - sym->liveFrom) == 0)
1710             continue ;
1711
1712
1713         /* if the live range is a temporary */
1714         if (sym->isitmp) {
1715
1716           debugLog("  %d - \n",__LINE__);
1717
1718             /* if the type is marked as a conditional */
1719             if (sym->regType == REG_CND)
1720                 continue ;
1721
1722             /* if used in return only then we don't 
1723                need registers */
1724             if (sym->ruonly || sym->accuse) {
1725                 if (IS_AGGREGATE(sym->type) || sym->isptr)
1726                     sym->type = aggrToPtr(sym->type,FALSE);
1727           debugLog("  %d - \n",__LINE__);
1728
1729                 continue ;
1730             }
1731             
1732             /* if the symbol has only one definition &
1733                that definition is a get_pointer and the
1734                pointer we are getting is rematerializable and
1735                in "data" space */
1736                
1737             if (bitVectnBitsOn(sym->defs) == 1 &&
1738                 (ic = hTabItemWithKey(iCodehTab,
1739                                       bitVectFirstBit(sym->defs))) &&
1740                 POINTER_GET(ic) && 
1741                 !IS_BITVAR(sym->etype)) {
1742                 
1743           debugLog("  %d - \n",__LINE__);
1744                                 
1745                 /* if remat in data space */
1746                 if (OP_SYMBOL(IC_LEFT(ic))->remat &&
1747                     DCL_TYPE(aggrToPtr(sym->type,FALSE)) == POINTER) {
1748                 
1749                     /* create a psuedo symbol & force a spil */
1750                     symbol *psym = newSymbol(rematStr(OP_SYMBOL(IC_LEFT(ic))),1);
1751                     psym->type = sym->type;
1752                     psym->etype = sym->etype;
1753                     strcpy(psym->rname,psym->name);
1754                     sym->isspilt = 1;
1755                     sym->usl.spillLoc = psym;
1756                     continue ;
1757                 }
1758
1759                 /* if in data space or idata space then try to
1760                    allocate pointer register */
1761                    
1762             }
1763                 
1764             /* if not then we require registers */
1765             sym->nRegs = ((IS_AGGREGATE(sym->type) || sym->isptr ) ?
1766                           getSize(sym->type = aggrToPtr(sym->type,FALSE)) :
1767                           getSize(sym->type));
1768
1769             if (sym->nRegs > 4) {
1770                 fprintf(stderr,"allocated more than 4 or 0 registers for type ");
1771                 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1772             }
1773             
1774           debugLog("  %d - \n",__LINE__);
1775
1776             /* determine the type of register required */
1777             if (sym->nRegs == 1   && 
1778                 IS_PTR(sym->type) && 
1779                 sym->uptr) 
1780                 sym->regType = REG_PTR ;            
1781             else 
1782                 sym->regType = REG_GPR ;
1783             debugLog("  reg type %s\n",debugLogRegType(sym->regType));
1784
1785         } else 
1786             /* for the first run we don't provide */
1787             /* registers for true symbols we will */
1788             /* see how things go                  */
1789             sym->nRegs = 0 ;    
1790     }
1791     
1792 }
1793
1794 /*-----------------------------------------------------------------*/
1795 /* freeAllRegs - mark all registers as free                        */
1796 /*-----------------------------------------------------------------*/
1797 static void freeAllRegs()
1798 {
1799     int i;
1800
1801     debugLog("%s\n",__FUNCTION__);
1802     for (i=0;i< pic14_nRegs;i++ )
1803         regspic14[i].isFree = 1;
1804 }
1805
1806 /*-----------------------------------------------------------------*/
1807 /* deallocStackSpil - this will set the stack pointer back         */
1808 /*-----------------------------------------------------------------*/
1809 static DEFSETFUNC(deallocStackSpil)
1810 {
1811     symbol *sym = item;
1812
1813     debugLog("%s\n",__FUNCTION__);
1814     deallocLocal(sym);
1815     return 0;
1816 }
1817
1818 /*-----------------------------------------------------------------*/
1819 /* farSpacePackable - returns the packable icode for far variables */
1820 /*-----------------------------------------------------------------*/
1821 static iCode *farSpacePackable (iCode *ic)
1822 {
1823     iCode *dic ;
1824
1825     debugLog("%s\n",__FUNCTION__);
1826     /* go thru till we find a definition for the
1827        symbol on the right */
1828     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1829                 
1830         /* if the definition is a call then no */
1831         if ((dic->op == CALL || dic->op == PCALL) &&
1832             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1833             return NULL;
1834         }
1835         
1836         /* if shift by unknown amount then not */
1837         if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
1838             IC_RESULT(dic)->key == IC_RIGHT(ic)->key)
1839             return NULL;
1840
1841         /* if pointer get and size > 1 */
1842         if (POINTER_GET(dic) &&
1843             getSize(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)) > 1)
1844             return NULL ;
1845
1846         if (POINTER_SET(dic) &&
1847             getSize(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)) > 1)
1848             return NULL ;
1849
1850         /* if any three is a true symbol in far space */
1851         if (IC_RESULT(dic) &&
1852             IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1853             isOperandInFarSpace(IC_RESULT(dic)))         
1854             return NULL;
1855
1856         if (IC_RIGHT(dic) &&
1857             IS_TRUE_SYMOP(IC_RIGHT(dic)) &&
1858             isOperandInFarSpace(IC_RIGHT(dic)) &&
1859             !isOperandEqual(IC_RIGHT(dic),IC_RESULT(ic)))
1860             return NULL;
1861
1862         if (IC_LEFT(dic) &&
1863             IS_TRUE_SYMOP(IC_LEFT(dic)) &&
1864             isOperandInFarSpace(IC_LEFT(dic)) &&
1865             !isOperandEqual(IC_LEFT(dic),IC_RESULT(ic)))
1866             return NULL;
1867         
1868         if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(dic))) {
1869             if ( (dic->op == LEFT_OP  ||
1870                   dic->op == RIGHT_OP ||
1871                   dic->op == '-') &&
1872                  IS_OP_LITERAL(IC_RIGHT(dic)))
1873                 return NULL;
1874             else
1875                 return dic;
1876         }
1877     }
1878
1879     return NULL;
1880 }
1881
1882 /*-----------------------------------------------------------------*/
1883 /* packRegsForAssign - register reduction for assignment           */
1884 /*-----------------------------------------------------------------*/
1885 static int packRegsForAssign (iCode *ic,eBBlock *ebp)
1886 {
1887
1888     iCode *dic, *sic;
1889     
1890     debugLog("%s\n",__FUNCTION__);
1891
1892     debugAopGet("  result:",IC_RESULT(ic));
1893     debugAopGet("  left:",IC_LEFT(ic));
1894     debugAopGet("  right:",IC_RIGHT(ic));
1895
1896     if (!IS_ITEMP(IC_RIGHT(ic))       ||        
1897         OP_SYMBOL(IC_RIGHT(ic))->isind ||
1898         OP_LIVETO(IC_RIGHT(ic)) > ic->seq) {
1899         return 0;
1900     }
1901         
1902     /* if the true symbol is defined in far space or on stack
1903        then we should not since this will increase register pressure */
1904     if (isOperandInFarSpace(IC_RESULT(ic))) {
1905         if ((dic = farSpacePackable(ic)))
1906             goto pack;
1907         else
1908             return 0;
1909         
1910     }
1911     /* find the definition of iTempNN scanning backwards if we find a 
1912        a use of the true symbol before we find the definition then 
1913        we cannot pack */        
1914     for ( dic = ic->prev ; dic ; dic = dic->prev) {
1915
1916         /* if there is a function call and this is
1917            a parameter & not my parameter then don't pack it */
1918         if ( (dic->op == CALL || dic->op == PCALL) &&
1919              (OP_SYMBOL(IC_RESULT(ic))->_isparm &&
1920               !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) {
1921           debugLog("  %d - \n",__LINE__);
1922             dic = NULL;
1923             break;
1924         }
1925
1926         if (SKIP_IC2(dic))
1927             continue;
1928
1929         if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
1930             IS_OP_VOLATILE(IC_RESULT(dic))) {
1931           debugLog("  %d - \n",__LINE__);
1932                 dic = NULL;
1933                 break;
1934         }
1935
1936         if (IS_SYMOP(IC_RESULT(dic)) &&
1937             IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
1938           debugLog("  %d - dic key == ic key -- pointer set=%c\n",__LINE__,((POINTER_SET(dic)) ? 'Y' :'N') );
1939             if (POINTER_SET(dic))
1940                 dic = NULL;
1941
1942             break;          
1943         }
1944
1945         if (IS_SYMOP(IC_RIGHT(dic)) && 
1946             (IC_RIGHT(dic)->key == IC_RESULT(ic)->key ||
1947              IC_RIGHT(dic)->key == IC_RIGHT(ic)->key)) {
1948           debugLog("  %d - \n",__LINE__);
1949             dic = NULL;
1950             break;
1951         }
1952         
1953         if (IS_SYMOP(IC_LEFT(dic)) && 
1954             (IC_LEFT(dic)->key == IC_RESULT(ic)->key ||
1955              IC_LEFT(dic)->key == IC_RIGHT(ic)->key)) {
1956           debugLog("  %d - \n",__LINE__);
1957             dic = NULL;
1958             break;
1959         }
1960
1961         if (POINTER_SET(dic) && 
1962             IC_RESULT(dic)->key == IC_RESULT(ic)->key ) {
1963           debugLog("  %d - \n",__LINE__);
1964             dic = NULL ;
1965             break;
1966         }
1967     }
1968     
1969     if (!dic)
1970         return 0 ; /* did not find */
1971             
1972     /* if the result is on stack or iaccess then it must be
1973        the same atleast one of the operands */
1974     if (OP_SYMBOL(IC_RESULT(ic))->onStack  || 
1975         OP_SYMBOL(IC_RESULT(ic))->iaccess ) {
1976         
1977         /* the operation has only one symbol
1978            operator then we can pack */
1979         if ((IC_LEFT(dic) && !IS_SYMOP(IC_LEFT(dic))) ||
1980             (IC_RIGHT(dic) && !IS_SYMOP(IC_RIGHT(dic))))
1981             goto pack;
1982
1983         if (!((IC_LEFT(dic) &&
1984              IC_RESULT(ic)->key == IC_LEFT(dic)->key) ||
1985               (IC_RIGHT(dic) &&
1986                IC_RESULT(ic)->key == IC_RIGHT(dic)->key)))
1987             return 0;                
1988     }
1989 pack:
1990     debugLog("  packing. removing %s\n",OP_SYMBOL(IC_RIGHT(ic))->rname);
1991     /* found the definition */
1992     /* replace the result with the result of */
1993     /* this assignment and remove this assignment */
1994     IC_RESULT(dic) = IC_RESULT(ic) ;
1995
1996     if (IS_ITEMP(IC_RESULT(dic)) && OP_SYMBOL(IC_RESULT(dic))->liveFrom > dic->seq) {
1997             OP_SYMBOL(IC_RESULT(dic))->liveFrom = dic->seq;
1998     }
1999     /* delete from liverange table also 
2000        delete from all the points inbetween and the new
2001        one */
2002     for ( sic = dic; sic != ic ; sic = sic->next ) {    
2003         bitVectUnSetBit(sic->rlive,IC_RESULT(ic)->key);
2004         if (IS_ITEMP(IC_RESULT(dic)))
2005             bitVectSetBit(sic->rlive,IC_RESULT(dic)->key);
2006     }
2007         
2008     remiCodeFromeBBlock(ebp,ic);
2009     hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2010     OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2011     return 1;
2012
2013     
2014 }
2015
2016 /*-----------------------------------------------------------------*/
2017 /* findAssignToSym : scanning backwards looks for first assig found*/
2018 /*-----------------------------------------------------------------*/
2019 static iCode *findAssignToSym (operand *op,iCode *ic)
2020 {
2021     iCode *dic;
2022
2023     debugLog("%s\n",__FUNCTION__);
2024     for (dic = ic->prev ; dic ; dic = dic->prev) {
2025         
2026         /* if definition by assignment */
2027         if (dic->op == '='                 && 
2028             !POINTER_SET(dic)              &&
2029             IC_RESULT(dic)->key == op->key
2030 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2031             ) {    
2032
2033             /* we are interested only if defined in far space */
2034             /* or in stack space in case of + & - */
2035
2036             /* if assigned to a non-symbol then return
2037                true */
2038             if (!IS_SYMOP(IC_RIGHT(dic)))
2039                 break ;
2040
2041             /* if the symbol is in far space then
2042                we should not */
2043             if (isOperandInFarSpace(IC_RIGHT(dic)))
2044                 return NULL ;
2045
2046             /* for + & - operations make sure that
2047                if it is on the stack it is the same
2048                as one of the three operands */
2049             if ((ic->op == '+' || ic->op == '-') &&
2050                 OP_SYMBOL(IC_RIGHT(dic))->onStack) {
2051
2052                 if ( IC_RESULT(ic)->key != IC_RIGHT(dic)->key &&
2053                      IC_LEFT(ic)->key   != IC_RIGHT(dic)->key &&
2054                      IC_RIGHT(ic)->key  != IC_RIGHT(dic)->key)
2055                     return NULL;
2056             }           
2057
2058             break ;
2059                 
2060         }
2061
2062         /* if we find an usage then we cannot delete it */
2063         if (IC_LEFT(dic) && IC_LEFT(dic)->key == op->key)
2064             return NULL;
2065             
2066         if (IC_RIGHT(dic) && IC_RIGHT(dic)->key == op->key)
2067             return NULL;
2068
2069         if (POINTER_SET(dic) && IC_RESULT(dic)->key == op->key)
2070             return NULL;
2071     }
2072
2073     /* now make sure that the right side of dic
2074        is not defined between ic & dic */       
2075     if (dic) {
2076         iCode *sic = dic->next ;
2077
2078         for (; sic != ic ; sic = sic->next)
2079             if (IC_RESULT(sic) &&
2080                 IC_RESULT(sic)->key == IC_RIGHT(dic)->key)
2081                 return NULL;
2082     }
2083
2084     return dic;
2085         
2086         
2087 }
2088
2089 /*-----------------------------------------------------------------*/
2090 /* packRegsForSupport :- reduce some registers for support calls   */
2091 /*-----------------------------------------------------------------*/
2092 static int packRegsForSupport (iCode *ic, eBBlock *ebp)
2093 {
2094     int change = 0 ;
2095
2096     debugLog("%s\n",__FUNCTION__);
2097     /* for the left & right operand :- look to see if the
2098        left was assigned a true symbol in far space in that
2099        case replace them */
2100     if (IS_ITEMP(IC_LEFT(ic)) && 
2101         OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) {
2102         iCode *dic = findAssignToSym(IC_LEFT(ic),ic);
2103         iCode *sic;
2104
2105         if (!dic)
2106             goto right ;
2107
2108         debugAopGet("removing left:",IC_LEFT(ic));
2109
2110         /* found it we need to remove it from the
2111            block */
2112         for ( sic = dic; sic != ic ; sic = sic->next )
2113             bitVectUnSetBit(sic->rlive,IC_LEFT(ic)->key);
2114
2115         IC_LEFT(ic)->operand.symOperand =
2116             IC_RIGHT(dic)->operand.symOperand;
2117         IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
2118         remiCodeFromeBBlock(ebp,dic);
2119         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2120         change++;      
2121     }
2122     
2123     /* do the same for the right operand */
2124  right:    
2125     if (!change && 
2126         IS_ITEMP(IC_RIGHT(ic)) &&
2127         OP_SYMBOL(IC_RIGHT(ic))->liveTo <= ic->seq) {
2128         iCode *dic = findAssignToSym(IC_RIGHT(ic),ic);
2129         iCode *sic;
2130         
2131         if (!dic)
2132             return change ;
2133
2134         /* if this is a subtraction & the result
2135            is a true symbol in far space then don't pack */
2136         if (ic->op == '-' && IS_TRUE_SYMOP(IC_RESULT(dic))) {
2137             sym_link *etype =getSpec(operandType(IC_RESULT(dic)));
2138             if (IN_FARSPACE(SPEC_OCLS(etype)))
2139                 return change ;
2140         }
2141
2142         debugAopGet("removing right:",IC_RIGHT(ic));
2143
2144         /* found it we need to remove it from the
2145            block */
2146         for ( sic = dic; sic != ic ; sic = sic->next )
2147             bitVectUnSetBit(sic->rlive,IC_RIGHT(ic)->key);
2148         
2149         IC_RIGHT(ic)->operand.symOperand =
2150             IC_RIGHT(dic)->operand.symOperand;
2151         IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
2152         
2153         remiCodeFromeBBlock(ebp,dic);
2154         hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2155         change ++;
2156     }
2157    
2158     return change ;
2159 }
2160
2161 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2162
2163
2164 /*-----------------------------------------------------------------*/
2165 /* packRegsForOneuse : - will reduce some registers for single Use */ 
2166 /*-----------------------------------------------------------------*/
2167 static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
2168 {
2169     bitVect *uses ;
2170     iCode *dic, *sic;
2171
2172     debugLog("%s\n",__FUNCTION__);
2173     /* if returning a literal then do nothing */
2174     if (!IS_SYMOP(op))
2175         return NULL;
2176     
2177     /* only upto 2 bytes since we cannot predict
2178        the usage of b, & acc */
2179     if (getSize(operandType(op)) >  (fReturnSize - 2) &&
2180         ic->op != RETURN             &&
2181         ic->op != SEND)
2182         return NULL;
2183
2184     /* this routine will mark the a symbol as used in one 
2185        instruction use only && if the definition is local 
2186        (ie. within the basic block) && has only one definition &&
2187        that definition is either a return value from a 
2188        function or does not contain any variables in
2189        far space */
2190     uses = bitVectCopy(OP_USES(op));
2191     bitVectUnSetBit(uses,ic->key); /* take away this iCode */
2192     if (!bitVectIsZero(uses)) /* has other uses */
2193         return NULL ;
2194     
2195     /* if it has only one defintion */
2196     if (bitVectnBitsOn(OP_DEFS(op)) > 1)
2197         return NULL ; /* has more than one definition */
2198
2199     /* get that definition */
2200     if (!(dic = 
2201           hTabItemWithKey(iCodehTab,
2202                           bitVectFirstBit(OP_DEFS(op)))))
2203         return NULL ;
2204
2205     /* found the definition now check if it is local */
2206     if (dic->seq < ebp->fSeq ||
2207         dic->seq > ebp->lSeq)
2208         return NULL ; /* non-local */
2209
2210     /* now check if it is the return from
2211        a function call */
2212     if (dic->op == CALL || dic->op == PCALL ) {
2213         if (ic->op != SEND && ic->op != RETURN) {
2214             OP_SYMBOL(op)->ruonly = 1;
2215             return dic;
2216         }
2217         dic = dic->next ;
2218     }
2219         
2220     
2221     /* otherwise check that the definition does
2222        not contain any symbols in far space */
2223     if (isOperandInFarSpace(IC_LEFT(dic))  ||
2224         isOperandInFarSpace(IC_RIGHT(dic)) ||
2225         IS_OP_RUONLY(IC_LEFT(ic))          ||
2226         IS_OP_RUONLY(IC_RIGHT(ic)) )        {
2227         return NULL;
2228     }
2229     
2230     /* if pointer set then make sure the pointer
2231        is one byte */
2232     if (POINTER_SET(dic) && 
2233         !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
2234         return NULL ;
2235
2236     if (POINTER_GET(dic) && 
2237         !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
2238         return NULL ;
2239     
2240     sic = dic;
2241
2242     /* also make sure the intervenening instructions
2243        don't have any thing in far space */
2244     for (dic = dic->next ; dic && dic != ic ; dic = dic->next) {
2245                 
2246         /* if there is an intervening function call then no */
2247         if (dic->op == CALL || dic->op == PCALL)
2248                 return NULL;
2249         /* if pointer set then make sure the pointer
2250            is one byte */
2251         if (POINTER_SET(dic) && 
2252             !IS_DATA_PTR(aggrToPtr(operandType(IC_RESULT(dic)),FALSE)))
2253             return NULL ;
2254         
2255         if (POINTER_GET(dic) && 
2256             !IS_DATA_PTR(aggrToPtr(operandType(IC_LEFT(dic)),FALSE)))
2257             return NULL ;
2258
2259         /* if address of & the result is remat then okay */
2260         if (dic->op == ADDRESS_OF &&
2261             OP_SYMBOL(IC_RESULT(dic))->remat)
2262             continue ;
2263            
2264         /* if operand has size of three or more & this
2265            operation is a '*','/' or '%' then 'b' may
2266            cause a problem */
2267         if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2268             getSize(operandType(op)) >= 3)
2269                 return NULL;
2270
2271         /* if left or right or result is in far space */
2272         if (isOperandInFarSpace(IC_LEFT(dic))   ||
2273             isOperandInFarSpace(IC_RIGHT(dic))  ||
2274             isOperandInFarSpace(IC_RESULT(dic)) ||
2275             IS_OP_RUONLY(IC_LEFT(dic))          ||
2276             IS_OP_RUONLY(IC_RIGHT(dic))         ||
2277             IS_OP_RUONLY(IC_RESULT(dic))            ) {
2278             return NULL;
2279         }
2280     }
2281                 
2282     OP_SYMBOL(op)->ruonly = 1;
2283     return sic;
2284         
2285 }
2286
2287 /*-----------------------------------------------------------------*/
2288 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2289 /*-----------------------------------------------------------------*/
2290 static bool isBitwiseOptimizable (iCode *ic)
2291 {
2292     sym_link *ltype = getSpec(operandType(IC_LEFT(ic)));
2293     sym_link *rtype = getSpec(operandType(IC_RIGHT(ic)));
2294
2295     debugLog("%s\n",__FUNCTION__);
2296     /* bitwise operations are considered optimizable
2297        under the following conditions (Jean-Louis VERN) 
2298        
2299        x & lit
2300        bit & bit
2301        bit & x
2302        bit ^ bit
2303        bit ^ x
2304        x   ^ lit
2305        x   | lit
2306        bit | bit
2307        bit | x
2308     */    
2309     if ( IS_LITERAL(rtype) ||
2310          (IS_BITVAR(ltype) && IN_BITSPACE(SPEC_OCLS(ltype))))
2311         return TRUE ;
2312     else
2313         return FALSE ;    
2314 }
2315
2316 /*-----------------------------------------------------------------*/
2317 /* packRegsForAccUse - pack registers for acc use                  */
2318 /*-----------------------------------------------------------------*/
2319 static void packRegsForAccUse (iCode *ic)
2320 {
2321     iCode *uic;
2322     
2323     debugLog("%s\n",__FUNCTION__);
2324     /* if + or - then it has to be one byte result */
2325     if ((ic->op == '+' || ic->op == '-')
2326         && getSize(operandType(IC_RESULT(ic))) > 1)
2327         return ;
2328     
2329     /* if shift operation make sure right side is not a literal */
2330     if (ic->op == RIGHT_OP  &&
2331         ( isOperandLiteral(IC_RIGHT(ic)) ||
2332           getSize(operandType(IC_RESULT(ic))) > 1))
2333         return ;
2334         
2335     if (ic->op == LEFT_OP &&        
2336         ( isOperandLiteral(IC_RIGHT(ic)) ||
2337           getSize(operandType(IC_RESULT(ic))) > 1))
2338         return ;
2339         
2340     if (IS_BITWISE_OP(ic) &&
2341         getSize(operandType(IC_RESULT(ic))) > 1)
2342         return ;
2343             
2344         
2345     /* has only one definition */
2346     if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
2347         return ;
2348
2349     /* has only one use */
2350     if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
2351         return ;
2352
2353     /* and the usage immediately follows this iCode */
2354     if (!(uic = hTabItemWithKey(iCodehTab,
2355                                 bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
2356         return ;
2357
2358     if (ic->next != uic)
2359         return ;
2360     
2361     /* if it is a conditional branch then we definitely can */
2362     if (uic->op == IFX  ) 
2363         goto accuse;
2364
2365     if ( uic->op == JUMPTABLE )
2366         return ;
2367
2368     /* if the usage is not is an assignment
2369        or an arithmetic / bitwise / shift operation then not */
2370     if (POINTER_SET(uic) && 
2371         getSize(aggrToPtr(operandType(IC_RESULT(uic)),FALSE)) > 1)
2372         return;
2373
2374     if (uic->op != '=' && 
2375         !IS_ARITHMETIC_OP(uic) &&
2376         !IS_BITWISE_OP(uic)    &&
2377         uic->op != LEFT_OP &&
2378         uic->op != RIGHT_OP )
2379         return;
2380
2381     /* if used in ^ operation then make sure right is not a 
2382        literl */
2383     if (uic->op == '^' && isOperandLiteral(IC_RIGHT(uic)))
2384         return ;
2385
2386     /* if shift operation make sure right side is not a literal */
2387     if (uic->op == RIGHT_OP  &&
2388         ( isOperandLiteral(IC_RIGHT(uic)) ||
2389           getSize(operandType(IC_RESULT(uic))) > 1))
2390         return ;
2391
2392     if (uic->op == LEFT_OP &&        
2393         ( isOperandLiteral(IC_RIGHT(uic)) ||
2394           getSize(operandType(IC_RESULT(uic))) > 1))
2395         return ;
2396             
2397     /* make sure that the result of this icode is not on the
2398        stack, since acc is used to compute stack offset */
2399     if (IS_TRUE_SYMOP(IC_RESULT(uic)) &&
2400         OP_SYMBOL(IC_RESULT(uic))->onStack)
2401         return ;
2402
2403     /* if either one of them in far space then we cannot */
2404     if ((IS_TRUE_SYMOP(IC_LEFT(uic)) &&
2405          isOperandInFarSpace(IC_LEFT(uic))) ||
2406         (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
2407          isOperandInFarSpace(IC_RIGHT(uic))))
2408         return ;
2409
2410     /* if the usage has only one operand then we can */
2411     if (IC_LEFT(uic) == NULL ||
2412         IC_RIGHT(uic) == NULL) 
2413         goto accuse;
2414
2415     /* make sure this is on the left side if not
2416        a '+' since '+' is commutative */
2417     if (ic->op != '+' &&
2418         IC_LEFT(uic)->key != IC_RESULT(ic)->key)
2419         return;
2420
2421     /* if one of them is a literal then we can */
2422     if ((IC_LEFT(uic) && IS_OP_LITERAL(IC_LEFT(uic))) ||
2423         (IC_RIGHT(uic) && IS_OP_LITERAL(IC_RIGHT(uic)))) {
2424         OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
2425         return ;
2426     }
2427
2428     /* if the other one is not on stack then we can */
2429     if (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
2430         (IS_ITEMP(IC_RIGHT(uic)) ||
2431          (IS_TRUE_SYMOP(IC_RIGHT(uic)) &&
2432           !OP_SYMBOL(IC_RIGHT(uic))->onStack))) 
2433         goto accuse;
2434     
2435     if (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
2436         (IS_ITEMP(IC_LEFT(uic)) ||
2437          (IS_TRUE_SYMOP(IC_LEFT(uic)) &&
2438           !OP_SYMBOL(IC_LEFT(uic))->onStack))) 
2439         goto accuse ;
2440
2441     return ;
2442
2443  accuse:
2444     OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
2445     
2446         
2447 }
2448
2449 /*-----------------------------------------------------------------*/
2450 /* packForPush - hueristics to reduce iCode for pushing            */
2451 /*-----------------------------------------------------------------*/
2452 static void packForReceive(iCode *ic, eBBlock *ebp)
2453 {
2454   iCode *dic;
2455   bool can_remove=1;    // assume that we can remove temporary
2456
2457   debugLog("%s\n",__FUNCTION__);
2458   debugAopGet("  result:",IC_RESULT(ic));
2459   debugAopGet("  left:",IC_LEFT(ic));
2460   debugAopGet("  right:",IC_RIGHT(ic));
2461
2462   if(!ic->next)
2463     return;
2464
2465   for ( dic = ic->next ; dic ; dic = dic->next ) {
2466
2467
2468
2469     if(IC_LEFT(dic) && (IC_RESULT(ic)->key == IC_LEFT(dic)->key) )
2470       debugLog("    used on left\n");
2471     if(IC_RIGHT(dic) && IC_RESULT(ic)->key == IC_RIGHT(dic)->key) 
2472       debugLog("    used on right\n");
2473     if(IC_RESULT(dic) && IC_RESULT(ic)->key == IC_RESULT(dic)->key) 
2474       debugLog("    used on result\n");
2475
2476     if( (IC_LEFT(dic) && (IC_RESULT(ic)->key == IC_LEFT(dic)->key) ) ||
2477         (IC_RESULT(dic) && IC_RESULT(ic)->key == IC_RESULT(dic)->key) )
2478       return;
2479
2480   }
2481
2482   debugLog("  hey we can remove this unnecessary assign\n");
2483 }
2484 /*-----------------------------------------------------------------*/
2485 /* packForPush - hueristics to reduce iCode for pushing            */
2486 /*-----------------------------------------------------------------*/
2487 static void packForPush(iCode *ic, eBBlock *ebp)
2488 {
2489     iCode *dic;
2490
2491     debugLog("%s\n",__FUNCTION__);
2492     if (ic->op != IPUSH || !IS_ITEMP(IC_LEFT(ic)))
2493         return ;
2494
2495     /* must have only definition & one usage */
2496     if (bitVectnBitsOn(OP_DEFS(IC_LEFT(ic))) != 1 ||
2497         bitVectnBitsOn(OP_USES(IC_LEFT(ic))) != 1 )     
2498         return ;
2499     
2500     /* find the definition */
2501     if (!(dic = hTabItemWithKey(iCodehTab,
2502                                 bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
2503         return ;
2504
2505     if (dic->op != '=' || POINTER_SET(dic))
2506         return;
2507
2508     /* we now we know that it has one & only one def & use
2509        and the that the definition is an assignment */
2510     IC_LEFT(ic) = IC_RIGHT(dic);
2511
2512     remiCodeFromeBBlock(ebp,dic);
2513     hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
2514 }
2515
2516 /*-----------------------------------------------------------------*/
2517 /* packRegisters - does some transformations to reduce register    */
2518 /*                   pressure                                      */
2519 /*-----------------------------------------------------------------*/
2520 static void packRegisters (eBBlock *ebp)
2521 {
2522     iCode *ic ;
2523     int change = 0 ;
2524     
2525     debugLog("%s\n",__FUNCTION__);
2526
2527     while (1) {
2528
2529         change = 0;
2530         
2531         /* look for assignments of the form */
2532         /* iTempNN = TRueSym (someoperation) SomeOperand */
2533         /*       ....                       */
2534         /* TrueSym := iTempNN:1             */
2535         for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2536             
2537             /* find assignment of the form TrueSym := iTempNN:1 */
2538             if (ic->op == '=' && !POINTER_SET(ic))
2539                 change += packRegsForAssign(ic,ebp);
2540             /* debug stuff */
2541             if (ic->op == '=') {
2542               if(POINTER_SET(ic))
2543                 debugLog("pointer is set\n");
2544               debugAopGet("  result:",IC_RESULT(ic));
2545               debugAopGet("  left:",IC_LEFT(ic));
2546               debugAopGet("  right:",IC_RIGHT(ic));
2547             }
2548
2549         }
2550
2551         if (!change)
2552             break;
2553     }
2554     
2555     for ( ic = ebp->sch ; ic ; ic = ic->next ) {
2556                 
2557         /* if this is an itemp & result of a address of a true sym 
2558            then mark this as rematerialisable   */
2559         if (ic->op == ADDRESS_OF && 
2560             IS_ITEMP(IC_RESULT(ic)) &&
2561             IS_TRUE_SYMOP(IC_LEFT(ic)) &&
2562             bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2563             !OP_SYMBOL(IC_LEFT(ic))->onStack ) {
2564
2565             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2566             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2567             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2568
2569         }
2570         
2571         /* if straight assignment then carry remat flag if
2572            this is the only definition */
2573         if (ic->op == '='    && 
2574             !POINTER_SET(ic) &&
2575             IS_SYMOP(IC_RIGHT(ic)) && 
2576             OP_SYMBOL(IC_RIGHT(ic))->remat &&
2577             bitVectnBitsOn(OP_SYMBOL(IC_RESULT(ic))->defs) <= 1) {
2578
2579             OP_SYMBOL(IC_RESULT(ic))->remat = 
2580                 OP_SYMBOL(IC_RIGHT(ic))->remat;
2581             OP_SYMBOL(IC_RESULT(ic))->rematiCode = 
2582                 OP_SYMBOL(IC_RIGHT(ic))->rematiCode ;
2583         }
2584
2585         /* if this is a +/- operation with a rematerizable 
2586            then mark this as rematerializable as well */
2587         if ((ic->op == '+' || ic->op == '-') &&
2588             (IS_SYMOP(IC_LEFT(ic)) && 
2589              IS_ITEMP(IC_RESULT(ic)) &&
2590              OP_SYMBOL(IC_LEFT(ic))->remat &&
2591              bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) == 1 &&
2592              IS_OP_LITERAL(IC_RIGHT(ic))) ) {
2593
2594           //int i = 
2595             operandLitValue(IC_RIGHT(ic));
2596             OP_SYMBOL(IC_RESULT(ic))->remat = 1;
2597             OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic;
2598             OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL;
2599         }
2600
2601         /* mark the pointer usages */
2602         if (POINTER_SET(ic)) {
2603             OP_SYMBOL(IC_RESULT(ic))->uptr = 1;
2604             debugLog("  marking as a pointer (set)\n");
2605         }
2606         if (POINTER_GET(ic)) {
2607             OP_SYMBOL(IC_LEFT(ic))->uptr = 1;
2608             debugLog("  marking as a pointer (get)\n");
2609         }
2610
2611         if (!SKIP_IC2(ic)) {
2612             /* if we are using a symbol on the stack
2613                then we should say pic14_ptrRegReq */
2614             if (ic->op == IFX && IS_SYMOP(IC_COND(ic)))
2615                 pic14_ptrRegReq += ((OP_SYMBOL(IC_COND(ic))->onStack ||
2616                                OP_SYMBOL(IC_COND(ic))->iaccess) ? 1 : 0);
2617             else
2618                 if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic)))
2619                     pic14_ptrRegReq += ((OP_SYMBOL(IC_JTCOND(ic))->onStack ||
2620                                    OP_SYMBOL(IC_JTCOND(ic))->iaccess) ? 1 : 0);
2621                 else {
2622                     if (IS_SYMOP(IC_LEFT(ic)))
2623                         pic14_ptrRegReq += ((OP_SYMBOL(IC_LEFT(ic))->onStack ||
2624                                        OP_SYMBOL(IC_LEFT(ic))->iaccess) ? 1 : 0);
2625                     if (IS_SYMOP(IC_RIGHT(ic)))
2626                         pic14_ptrRegReq += ((OP_SYMBOL(IC_RIGHT(ic))->onStack ||
2627                                        OP_SYMBOL(IC_RIGHT(ic))->iaccess) ? 1 : 0);
2628                     if (IS_SYMOP(IC_RESULT(ic)))
2629                         pic14_ptrRegReq += ((OP_SYMBOL(IC_RESULT(ic))->onStack ||
2630                                        OP_SYMBOL(IC_RESULT(ic))->iaccess) ? 1 : 0);    
2631                 }
2632         }
2633
2634         /* if the condition of an if instruction
2635            is defined in the previous instruction then
2636            mark the itemp as a conditional */
2637         if ((IS_CONDITIONAL(ic) ||
2638              ( ( ic->op == BITWISEAND      ||
2639                  ic->op == '|'             ||
2640                  ic->op == '^' ) &&
2641                isBitwiseOptimizable(ic))) &&        
2642             ic->next && ic->next->op == IFX &&
2643             isOperandEqual(IC_RESULT(ic),IC_COND(ic->next)) &&
2644             OP_SYMBOL(IC_RESULT(ic))->liveTo <= ic->next->seq) {
2645             
2646             OP_SYMBOL(IC_RESULT(ic))->regType = REG_CND;            
2647             continue ;
2648         }
2649         
2650         /* reduce for support function calls */
2651         if (ic->supportRtn || ic->op == '+' || ic->op == '-' )
2652             packRegsForSupport (ic,ebp);        
2653
2654         /* if a parameter is passed, it's in W, so we may not
2655            need to place a copy in a register */
2656         if(ic->op == RECEIVE)
2657           packForReceive(ic,ebp);
2658
2659         /* some cases the redundant moves can
2660            can be eliminated for return statements */
2661         if ((ic->op == RETURN || ic->op == SEND) &&
2662             !isOperandInFarSpace(IC_LEFT(ic))    &&
2663             !options.model)
2664             packRegsForOneuse (ic,IC_LEFT(ic),ebp);     
2665
2666         /* if pointer set & left has a size more than
2667            one and right is not in far space */
2668         if (POINTER_SET(ic)                    &&
2669             !isOperandInFarSpace(IC_RIGHT(ic)) &&
2670             !OP_SYMBOL(IC_RESULT(ic))->remat   &&
2671             !IS_OP_RUONLY(IC_RIGHT(ic))        &&
2672             getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 )
2673
2674             packRegsForOneuse (ic,IC_RESULT(ic),ebp);
2675
2676         /* if pointer get */
2677         if (POINTER_GET(ic)                    &&
2678             !isOperandInFarSpace(IC_RESULT(ic))&&
2679             !OP_SYMBOL(IC_LEFT(ic))->remat     &&
2680             !IS_OP_RUONLY(IC_RESULT(ic))         &&
2681             getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 )
2682
2683             packRegsForOneuse (ic,IC_LEFT(ic),ebp);
2684
2685
2686         /* if this is cast for intergral promotion then
2687            check if only use of  the definition of the 
2688            operand being casted/ if yes then replace
2689            the result of that arithmetic operation with 
2690            this result and get rid of the cast */
2691         if (ic->op == CAST) {
2692             sym_link *fromType = operandType(IC_RIGHT(ic));
2693             sym_link *toType = operandType(IC_LEFT(ic));
2694
2695             if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) &&
2696                 getSize(fromType) != getSize(toType) ) {
2697
2698                 iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp);
2699                 if (dic) {
2700                     if (IS_ARITHMETIC_OP(dic)) {
2701                         IC_RESULT(dic) = IC_RESULT(ic);
2702                         remiCodeFromeBBlock(ebp,ic);
2703                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2704                         OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2705                         ic = ic->prev;
2706                     } else
2707                         OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
2708                 }               
2709             } else {
2710                 
2711                 /* if the type from and type to are the same
2712                    then if this is the only use then packit */
2713                 if (checkType(operandType(IC_RIGHT(ic)),
2714                               operandType(IC_LEFT(ic))) == 1) {
2715                     iCode *dic = packRegsForOneuse (ic,IC_RIGHT(ic),ebp);
2716                     if (dic) {
2717                         IC_RESULT(dic) = IC_RESULT(ic);
2718                         remiCodeFromeBBlock(ebp,ic);
2719                         hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
2720                         OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key);
2721                         ic = ic->prev;
2722                     }
2723                 }
2724             }
2725         }
2726         
2727         /* pack for PUSH 
2728            iTempNN := (some variable in farspace) V1
2729            push iTempNN ;
2730            -------------
2731            push V1
2732         */
2733         if (ic->op == IPUSH ) {
2734             packForPush(ic,ebp);
2735         }
2736           
2737         
2738         /* pack registers for accumulator use, when the
2739            result of an arithmetic or bit wise operation
2740            has only one use, that use is immediately following
2741            the defintion and the using iCode has only one
2742            operand or has two operands but one is literal &
2743            the result of that operation is not on stack then
2744            we can leave the result of this operation in acc:b
2745            combination */
2746         if ((IS_ARITHMETIC_OP(ic) 
2747              
2748              || IS_BITWISE_OP(ic) 
2749              
2750              || ic->op == LEFT_OP || ic->op == RIGHT_OP
2751              
2752              ) &&
2753             IS_ITEMP(IC_RESULT(ic)) &&
2754             getSize(operandType(IC_RESULT(ic))) <= 2)
2755
2756             packRegsForAccUse (ic);
2757
2758     }
2759 }
2760
2761 static void dumpEbbsToDebug(eBBlock **ebbs, int count)
2762 {
2763   int i;
2764
2765   if(!debug || !debugF)
2766     return;
2767
2768   for (i=0; i < count ; i++ ) {
2769     fprintf(debugF,"\n----------------------------------------------------------------\n");
2770     fprintf(debugF,"Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
2771             ebbs[i]->entryLabel->name, 
2772             ebbs[i]->depth,
2773             ebbs[i]->noPath,
2774             ebbs[i]->isLastInLoop);
2775     fprintf(debugF,"depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
2776             ebbs[i]->dfnum, 
2777             ebbs[i]->bbnum,
2778             ebbs[i]->fSeq,
2779             ebbs[i]->lSeq);
2780     fprintf(debugF,"visited %d : hasFcall = %d\n",
2781             ebbs[i]->visited, 
2782             ebbs[i]->hasFcall);
2783
2784     fprintf(debugF,"\ndefines bitVector :");
2785     bitVectDebugOn(ebbs[i]->defSet,debugF);
2786     fprintf(debugF,"\nlocal defines bitVector :");
2787     bitVectDebugOn(ebbs[i]->ldefs,debugF);
2788     fprintf(debugF,"\npointers Set bitvector :");
2789     bitVectDebugOn(ebbs[i]->ptrsSet,debugF);
2790     fprintf(debugF,"\nin pointers Set bitvector :");
2791     bitVectDebugOn(ebbs[i]->inPtrsSet,debugF);
2792     fprintf(debugF,"\ninDefs Set bitvector :");
2793     bitVectDebugOn(ebbs[i]->inDefs,debugF);
2794     fprintf(debugF,"\noutDefs Set bitvector :");
2795     bitVectDebugOn(ebbs[i]->outDefs,debugF);
2796     fprintf(debugF,"\nusesDefs Set bitvector :");
2797     bitVectDebugOn(ebbs[i]->usesDefs,debugF);
2798     fprintf(debugF,"\n----------------------------------------------------------------\n");
2799     printiCChain(ebbs[i]->sch,debugF);
2800   }
2801 }
2802 /*-----------------------------------------------------------------*/
2803 /* assignRegisters - assigns registers to each live range as need  */
2804 /*-----------------------------------------------------------------*/
2805 void pic14_assignRegisters (eBBlock **ebbs, int count)
2806 {
2807     iCode *ic;
2808     int i ;
2809
2810     debugLog("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s",__FILE__,__FUNCTION__);
2811     debugLog("ebbs before optimizing:\n");
2812     dumpEbbsToDebug(ebbs,count);
2813
2814     setToNull((void *)&_G.funcrUsed);
2815     pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
2816
2817
2818     /* change assignments this will remove some
2819        live ranges reducing some register pressure */
2820     for (i = 0 ; i < count ;i++ )
2821         packRegisters (ebbs[i]);
2822     
2823     if (options.dump_pack)
2824         dumpEbbsToFileExt(".dumppack",ebbs,count);
2825
2826     /* first determine for each live range the number of 
2827        registers & the type of registers required for each */
2828     regTypeNum ();
2829     
2830     /* and serially allocate registers */ 
2831     serialRegAssign(ebbs,count);
2832
2833     /* if stack was extended then tell the user */
2834     if (_G.stackExtend) {
2835 /*      werror(W_TOOMANY_SPILS,"stack", */
2836 /*             _G.stackExtend,currFunc->name,""); */
2837         _G.stackExtend = 0 ;
2838     }
2839
2840     if (_G.dataExtend) {
2841 /*      werror(W_TOOMANY_SPILS,"data space", */
2842 /*             _G.dataExtend,currFunc->name,""); */
2843         _G.dataExtend = 0 ;
2844     }  
2845
2846     /* after that create the register mask
2847        for each of the instruction */
2848     createRegMask (ebbs,count);
2849
2850     /* redo that offsets for stacked automatic variables */
2851     redoStackOffsets ();
2852
2853     if (options.dump_rassgn)
2854         dumpEbbsToFileExt(".dumprassgn",ebbs,count);
2855
2856     /* now get back the chain */
2857     ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));
2858
2859     debugLog("ebbs after optimizing:\n");
2860     dumpEbbsToDebug(ebbs,count);
2861
2862
2863     genpic14Code(ic);
2864
2865     /* free up any _G.stackSpil locations allocated */   
2866     applyToSet(_G.stackSpil,deallocStackSpil);
2867     _G.slocNum = 0;
2868     setToNull((void **)&_G.stackSpil);
2869     setToNull((void **)&_G.spiltSet);
2870     /* mark all registers as free */
2871     freeAllRegs();
2872
2873     debugLog("leaving\n<><><><><><><><><><><><><><><><><>\n");
2874     debugLogClose();
2875     return ;
2876 }