Improved the Register Banking algorithm.
[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 "pcode.h"
30 #include "gen.h"
31
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
34 #else
35 #define STRCASECMP strcasecmp
36 #endif
37
38 /*-----------------------------------------------------------------*/
39 /* At this point we start getting processor specific although      */
40 /* some routines are non-processor specific & can be reused when   */
41 /* targetting other processors. The decision for this will have    */
42 /* to be made on a routine by routine basis                        */
43 /* routines used to pack registers are most definitely not reusable */
44 /* since the pack the registers depending strictly on the MCU      */
45 /*-----------------------------------------------------------------*/
46
47 extern void genpic14Code (iCode *);
48
49 /* Global data */
50 static struct
51   {
52     bitVect *spiltSet;
53     set *stackSpil;
54     bitVect *regAssigned;
55     short blockSpil;
56     int slocNum;
57     bitVect *funcrUsed;         /* registers used in a function */
58     int stackExtend;
59     int dataExtend;
60   }
61 _G;
62
63 /* Shared with gen.c */
64 int pic14_ptrRegReq;            /* one byte pointer register required */
65
66
67 static set *dynAllocRegs=NULL;
68 static set *dynStackRegs=NULL;
69 static set *dynProcessorRegs=NULL;
70 static set *dynDirectRegs=NULL;
71 static set *dynDirectBitRegs=NULL;
72 static set *dynInternalRegs=NULL;
73
74 static hTab  *dynDirectRegNames= NULL;
75
76 static int dynrIdx=0x20;
77 static int rDirectIdx=0;
78
79 int pic14_nRegs = 128;   // = sizeof (regspic14) / sizeof (regs);
80
81 int Gstack_base_addr=0; /* The starting address of registers that
82                          * are used to pass and return parameters */
83
84
85
86
87 static void spillThis (symbol *);
88 static int debug = 1;
89 static FILE *debugF = NULL;
90 /*-----------------------------------------------------------------*/
91 /* debugLog - open a file for debugging information                */
92 /*-----------------------------------------------------------------*/
93 //static void debugLog(char *inst,char *fmt, ...)
94 static void
95 debugLog (char *fmt,...)
96 {
97   static int append = 0;        // First time through, open the file without append.
98
99   char buffer[256];
100   //char *bufferP=buffer;
101   va_list ap;
102
103   if (!debug || !srcFileName)
104     return;
105
106
107   if (!debugF)
108     {
109       /* create the file name */
110       strcpy (buffer, srcFileName);
111       strcat (buffer, ".d");
112
113       if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
114         {
115           werror (E_FILE_OPEN_ERR, buffer);
116           exit (1);
117         }
118       append = 1;               // Next time debubLog is called, we'll append the debug info
119
120     }
121
122   va_start (ap, fmt);
123
124   vsprintf (buffer, fmt, ap);
125
126   fprintf (debugF, "%s", buffer);
127 /*
128    while (isspace(*bufferP)) bufferP++;
129
130    if (bufferP && *bufferP) 
131    lineCurr = (lineCurr ?
132    connectLine(lineCurr,newLineNode(lb)) :
133    (lineHead = newLineNode(lb)));
134    lineCurr->isInline = _G.inLine;
135    lineCurr->isDebug  = _G.debugLine;
136  */
137   va_end (ap);
138
139 }
140
141 static void
142 debugNewLine (void)
143 {
144   if (debugF)
145     fputc ('\n', debugF);
146 }
147 /*-----------------------------------------------------------------*/
148 /* debugLogClose - closes the debug log file (if opened)           */
149 /*-----------------------------------------------------------------*/
150 static void
151 debugLogClose (void)
152 {
153   if (debugF)
154     {
155       fclose (debugF);
156       debugF = NULL;
157     }
158 }
159 #define AOP(op) op->aop
160
161 static char *
162 debugAopGet (char *str, operand * op)
163 {
164   if (str)
165     debugLog (str);
166
167   printOperand (op, debugF);
168   debugNewLine ();
169
170   return NULL;
171
172 }
173
174 static char *
175 decodeOp (unsigned int op)
176 {
177
178   if (op < 128 && op > ' ')
179     {
180       buffer[0] = (op & 0xff);
181       buffer[1] = 0;
182       return buffer;
183     }
184
185   switch (op)
186     {
187     case IDENTIFIER:
188       return "IDENTIFIER";
189     case TYPE_NAME:
190       return "TYPE_NAME";
191     case CONSTANT:
192       return "CONSTANT";
193     case STRING_LITERAL:
194       return "STRING_LITERAL";
195     case SIZEOF:
196       return "SIZEOF";
197     case PTR_OP:
198       return "PTR_OP";
199     case INC_OP:
200       return "INC_OP";
201     case DEC_OP:
202       return "DEC_OP";
203     case LEFT_OP:
204       return "LEFT_OP";
205     case RIGHT_OP:
206       return "RIGHT_OP";
207     case LE_OP:
208       return "LE_OP";
209     case GE_OP:
210       return "GE_OP";
211     case EQ_OP:
212       return "EQ_OP";
213     case NE_OP:
214       return "NE_OP";
215     case AND_OP:
216       return "AND_OP";
217     case OR_OP:
218       return "OR_OP";
219     case MUL_ASSIGN:
220       return "MUL_ASSIGN";
221     case DIV_ASSIGN:
222       return "DIV_ASSIGN";
223     case MOD_ASSIGN:
224       return "MOD_ASSIGN";
225     case ADD_ASSIGN:
226       return "ADD_ASSIGN";
227     case SUB_ASSIGN:
228       return "SUB_ASSIGN";
229     case LEFT_ASSIGN:
230       return "LEFT_ASSIGN";
231     case RIGHT_ASSIGN:
232       return "RIGHT_ASSIGN";
233     case AND_ASSIGN:
234       return "AND_ASSIGN";
235     case XOR_ASSIGN:
236       return "XOR_ASSIGN";
237     case OR_ASSIGN:
238       return "OR_ASSIGN";
239     case TYPEDEF:
240       return "TYPEDEF";
241     case EXTERN:
242       return "EXTERN";
243     case STATIC:
244       return "STATIC";
245     case AUTO:
246       return "AUTO";
247     case REGISTER:
248       return "REGISTER";
249     case CODE:
250       return "CODE";
251     case EEPROM:
252       return "EEPROM";
253     case INTERRUPT:
254       return "INTERRUPT";
255     case SFR:
256       return "SFR";
257     case AT:
258       return "AT";
259     case SBIT:
260       return "SBIT";
261     case REENTRANT:
262       return "REENTRANT";
263     case USING:
264       return "USING";
265     case XDATA:
266       return "XDATA";
267     case DATA:
268       return "DATA";
269     case IDATA:
270       return "IDATA";
271     case PDATA:
272       return "PDATA";
273     case VAR_ARGS:
274       return "VAR_ARGS";
275     case CRITICAL:
276       return "CRITICAL";
277     case NONBANKED:
278       return "NONBANKED";
279     case BANKED:
280       return "BANKED";
281     case CHAR:
282       return "CHAR";
283     case SHORT:
284       return "SHORT";
285     case INT:
286       return "INT";
287     case LONG:
288       return "LONG";
289     case SIGNED:
290       return "SIGNED";
291     case UNSIGNED:
292       return "UNSIGNED";
293     case FLOAT:
294       return "FLOAT";
295     case DOUBLE:
296       return "DOUBLE";
297     case CONST:
298       return "CONST";
299     case VOLATILE:
300       return "VOLATILE";
301     case VOID:
302       return "VOID";
303     case BIT:
304       return "BIT";
305     case STRUCT:
306       return "STRUCT";
307     case UNION:
308       return "UNION";
309     case ENUM:
310       return "ENUM";
311     case ELIPSIS:
312       return "ELIPSIS";
313     case RANGE:
314       return "RANGE";
315     case FAR:
316       return "FAR";
317     case CASE:
318       return "CASE";
319     case DEFAULT:
320       return "DEFAULT";
321     case IF:
322       return "IF";
323     case ELSE:
324       return "ELSE";
325     case SWITCH:
326       return "SWITCH";
327     case WHILE:
328       return "WHILE";
329     case DO:
330       return "DO";
331     case FOR:
332       return "FOR";
333     case GOTO:
334       return "GOTO";
335     case CONTINUE:
336       return "CONTINUE";
337     case BREAK:
338       return "BREAK";
339     case RETURN:
340       return "RETURN";
341     case INLINEASM:
342       return "INLINEASM";
343     case IFX:
344       return "IFX";
345     case ADDRESS_OF:
346       return "ADDRESS_OF";
347     case GET_VALUE_AT_ADDRESS:
348       return "GET_VALUE_AT_ADDRESS";
349     case SPIL:
350       return "SPIL";
351     case UNSPIL:
352       return "UNSPIL";
353     case GETHBIT:
354       return "GETHBIT";
355     case BITWISEAND:
356       return "BITWISEAND";
357     case UNARYMINUS:
358       return "UNARYMINUS";
359     case IPUSH:
360       return "IPUSH";
361     case IPOP:
362       return "IPOP";
363     case PCALL:
364       return "PCALL";
365     case ENDFUNCTION:
366       return "ENDFUNCTION";
367     case JUMPTABLE:
368       return "JUMPTABLE";
369     case RRC:
370       return "RRC";
371     case RLC:
372       return "RLC";
373     case CAST:
374       return "CAST";
375     case CALL:
376       return "CALL";
377     case PARAM:
378       return "PARAM  ";
379     case NULLOP:
380       return "NULLOP";
381     case BLOCK:
382       return "BLOCK";
383     case LABEL:
384       return "LABEL";
385     case RECEIVE:
386       return "RECEIVE";
387     case SEND:
388       return "SEND";
389     }
390   sprintf (buffer, "unkown op %d %c", op, op & 0xff);
391   return buffer;
392 }
393 /*-----------------------------------------------------------------*/
394 /*-----------------------------------------------------------------*/
395 static char *
396 debugLogRegType (short type)
397 {
398
399   switch (type)
400     {
401     case REG_GPR:
402       return "REG_GPR";
403     case REG_PTR:
404       return "REG_PTR";
405     case REG_CND:
406       return "REG_CND";
407     }
408
409   sprintf (buffer, "unkown reg type %d", type);
410   return buffer;
411 }
412
413 /*-----------------------------------------------------------------*/
414 /* newReg - allocate and init memory for a new register            */
415 /*-----------------------------------------------------------------*/
416 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
417 {
418
419   regs *dReg;
420
421   dReg = Safe_calloc(1,sizeof(regs));
422   dReg->type = type;
423   dReg->pc_type = pc_type;
424   dReg->rIdx = rIdx;
425   if(name) 
426     dReg->name = Safe_strdup(name);
427   else {
428     sprintf(buffer,"r0x%02X", dReg->rIdx);
429     if(type == REG_STK)
430       *buffer = 's';
431     dReg->name = Safe_strdup(buffer);
432   }
433   //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
434   dReg->isFree = 0;
435   dReg->wasUsed = 1;
436   dReg->isFixed = 0;
437   dReg->isMapped = 0;
438   dReg->isEmitted = 0;
439   dReg->address = 0;
440   dReg->size = size;
441   dReg->alias = alias;
442   dReg->reg_alias = NULL;
443
444   return dReg;
445 }
446
447 /*-----------------------------------------------------------------*/
448 /* regWithIdx - Search through a set of registers that matches idx */
449 /*-----------------------------------------------------------------*/
450 static regs *
451 regWithIdx (set *dRegs, int idx, int fixed)
452 {
453   regs *dReg;
454
455   for (dReg = setFirstItem(dRegs) ; dReg ; 
456        dReg = setNextItem(dRegs)) {
457
458     if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
459       return dReg;
460     }
461   }
462
463   return NULL;
464 }
465
466 /*-----------------------------------------------------------------*/
467 /* regFindFree - Search for a free register in a set of registers  */
468 /*-----------------------------------------------------------------*/
469 static regs *
470 regFindFree (set *dRegs)
471 {
472   regs *dReg;
473
474   for (dReg = setFirstItem(dRegs) ; dReg ; 
475        dReg = setNextItem(dRegs)) {
476
477     if(dReg->isFree)
478       return dReg;
479   }
480
481   return NULL;
482 }
483 /*-----------------------------------------------------------------*/
484 /* initStack - allocate registers for a psuedo stack               */
485 /*-----------------------------------------------------------------*/
486 void initStack(int base_address, int size)
487 {
488
489   int i;
490
491   Gstack_base_addr = base_address;
492   for(i = 0; i<size; i++)
493     addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
494 }
495
496 regs *
497 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
498 {
499   return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
500 }
501
502 regs *
503 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
504 {
505   regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
506
507   if(reg) {
508     reg->wasUsed = 0;
509     return addSet(&dynInternalRegs,reg);
510   }
511
512   return NULL;
513 }
514 /*-----------------------------------------------------------------*/
515 /* allocReg - allocates register of given type                     */
516 /*-----------------------------------------------------------------*/
517 static regs *
518 allocReg (short type)
519 {
520
521   debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
522
523
524   return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
525
526 }
527
528 /*-----------------------------------------------------------------*/
529 /*-----------------------------------------------------------------*/
530 static int regname2key(char const *name)
531 {
532   int key = 0;
533
534   if(!name)
535     return 0;
536
537   while(*name) {
538
539     key += (*name++) + 1;
540
541   }
542
543   return ( (key + (key >> 4) + (key>>8)) & 0x3f);
544
545 }
546
547 /*-----------------------------------------------------------------*/
548 /* dirregWithName - search for register by name                    */
549 /*-----------------------------------------------------------------*/
550 regs *
551 dirregWithName (char *name)
552 {
553   int hkey;
554   regs *reg;
555
556   if(!name)
557     return NULL;
558
559   /* hash the name to get a key */
560
561   hkey = regname2key(name);
562
563   reg = hTabFirstItemWK(dynDirectRegNames, hkey);
564
565   while(reg) {
566
567     if(STRCASECMP(reg->name, name) == 0) {
568       return(reg);
569     }
570
571     reg = hTabNextItemWK (dynDirectRegNames);
572   
573   }
574
575   return NULL; // name wasn't found in the hash table
576 }
577
578 int IS_CONFIG_ADDRESS(int address)
579 {
580
581   return address == 0x2007;
582 }
583
584 /*-----------------------------------------------------------------*/
585 /* allocDirReg - allocates register of given type                  */
586 /*-----------------------------------------------------------------*/
587 regs *
588 allocDirReg (operand *op )
589 {
590
591   regs *reg;
592   char *name;
593
594   if(!IS_SYMOP(op)) {
595     debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
596     return NULL;
597   }
598
599   name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
600
601   /* If the symbol is at a fixed address, then remove the leading underscore
602    * from the name. This is hack to allow the .asm include file named registers
603    * to match the .c declared register names */
604
605   //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
606   //name++;
607
608   debugLog ("%s symbol name %s\n", __FUNCTION__,name);
609   {
610     if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
611       debugLog(" %d  const char\n",__LINE__);
612       debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
613     }
614
615     debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
616     if (IS_CODE ( OP_SYM_ETYPE(op)) )
617       debugLog(" %d  code space\n",__LINE__);
618
619     if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
620       debugLog(" %d  integral\n",__LINE__);
621     if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
622       debugLog(" %d  literal\n",__LINE__);
623     if (IS_SPEC ( OP_SYM_ETYPE(op)) )
624       debugLog(" %d  specifier\n",__LINE__);
625     debugAopGet(NULL, op);
626   }
627
628   if (IS_CODE ( OP_SYM_ETYPE(op)) )
629     return NULL;
630
631   /* First, search the hash table to see if there is a register with this name */
632   reg = dirregWithName(name);
633
634   if(!reg) {
635     int address = 0;
636
637     /* if this is at an absolute address, then get the address. */
638     if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
639       address = SPEC_ADDR ( OP_SYM_ETYPE(op));
640     }
641
642     /* Register wasn't found in hash, so let's create
643      * a new one and put it in the hash table AND in the 
644      * dynDirectRegNames set */
645     if(!IS_CONFIG_ADDRESS(address)) {
646       reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
647       debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
648 /*
649       if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
650         reg->isFixed = 1;
651         reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
652         debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
653       }
654 */
655       hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
656       if (IS_BITVAR (OP_SYM_ETYPE(op)))
657         addSet(&dynDirectBitRegs, reg);
658       else
659         addSet(&dynDirectRegs, reg);
660     } else {
661       debugLog ("  -- %s is declared at address 0x2007\n",name);
662
663     }
664   }
665
666   if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
667     reg->isFixed = 1;
668     reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
669     debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
670   }
671
672   return reg;
673 }
674
675 /*-----------------------------------------------------------------*/
676 /* allocDirReg - allocates register of given type                  */
677 /*-----------------------------------------------------------------*/
678 regs *
679 allocRegByName (char *name, int size)
680 {
681
682   regs *reg;
683
684   if(!name) {
685     fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
686     exit(1);
687   }
688
689   debugLog ("%s symbol name %s\n", __FUNCTION__,name);
690
691   /* First, search the hash table to see if there is a register with this name */
692   reg = dirregWithName(name);
693
694   if(!reg) {
695
696     /* Register wasn't found in hash, so let's create
697      * a new one and put it in the hash table AND in the 
698      * dynDirectRegNames set */
699
700     reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
701
702     debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
703
704     hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
705     addSet(&dynDirectRegs, reg);
706   }
707
708   return reg;
709 }
710
711 /*-----------------------------------------------------------------*/
712 /* RegWithIdx - returns pointer to register with index number       */
713 /*-----------------------------------------------------------------*/
714 static regs *
715 typeRegWithIdx (int idx, int type, int fixed)
716 {
717
718   regs *dReg;
719
720   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
721
722   if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
723
724     debugLog ("Found a Dynamic Register!\n");
725     return dReg;
726   }
727
728   if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
729     debugLog ("Found a Stack Register!\n");
730     return dReg;
731   }
732
733   if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
734     debugLog ("Found a Direct Register!\n");
735     return dReg;
736   }
737
738   if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
739     debugLog ("Found a Processor Register!\n");
740     return dReg;
741   }
742 /*
743   if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
744     debugLog ("Found a bit Register!\n");
745     return dReg;
746   }
747 */
748 /*
749   fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
750   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
751           "regWithIdx not found");
752   exit (1);
753 */
754   return NULL;
755 }
756
757 /*-----------------------------------------------------------------*/
758 /* pic14_regWithIdx - returns pointer to register with index number*/
759 /*-----------------------------------------------------------------*/
760 regs *
761 pic14_regWithIdx (int idx)
762 {
763
764   return typeRegWithIdx(idx,-1,0);
765 }
766
767 /*-----------------------------------------------------------------*/
768 /* pic14_regWithIdx - returns pointer to register with index number       */
769 /*-----------------------------------------------------------------*/
770 regs *
771 pic14_allocWithIdx (int idx)
772 {
773
774   regs *dReg;
775
776   debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
777
778   if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
779
780     debugLog ("Found a Dynamic Register!\n");
781   } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
782     debugLog ("Found a Stack Register!\n");
783   } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
784     debugLog ("Found a Processor Register!\n");
785   } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
786     debugLog ("Found an Internal Register!\n");
787   } else {
788     
789     debugLog ("Dynamic Register not found\n");
790
791
792     fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
793     werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
794             "regWithIdx not found");
795     exit (1);
796
797   }
798
799   dReg->wasUsed = 1;
800   dReg->isFree = 0;
801
802   return dReg;
803 }
804 /*-----------------------------------------------------------------*/
805 /*-----------------------------------------------------------------*/
806 regs *
807 pic14_findFreeReg(short type)
808 {
809   //  int i;
810   regs* dReg;
811
812   switch (type) {
813   case REG_GPR:
814     if((dReg = regFindFree(dynAllocRegs)) != NULL)
815       return dReg;
816
817     return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
818
819   case REG_STK:
820
821     if((dReg = regFindFree(dynStackRegs)) != NULL)
822       return dReg;
823
824     return NULL;
825
826   case REG_PTR:
827   case REG_CND:
828   case REG_SFR:
829   default:
830     return NULL;
831   }
832 }
833 /*-----------------------------------------------------------------*/
834 /* freeReg - frees a register                                      */
835 /*-----------------------------------------------------------------*/
836 static void
837 freeReg (regs * reg)
838 {
839   debugLog ("%s\n", __FUNCTION__);
840   reg->isFree = 1;
841 }
842
843
844 /*-----------------------------------------------------------------*/
845 /* nFreeRegs - returns number of free registers                    */
846 /*-----------------------------------------------------------------*/
847 static int
848 nFreeRegs (int type)
849 {
850   /* dynamically allocate as many as we need and worry about
851    * fitting them into a PIC later */
852
853   return 100;
854 #if 0
855   int i;
856   int nfr = 0;
857
858   debugLog ("%s\n", __FUNCTION__);
859   for (i = 0; i < pic14_nRegs; i++)
860     if (regspic14[i].isFree && regspic14[i].type == type)
861       nfr++;
862   return nfr;
863 #endif
864 }
865
866 /*-----------------------------------------------------------------*/
867 /* nfreeRegsType - free registers with type                         */
868 /*-----------------------------------------------------------------*/
869 static int
870 nfreeRegsType (int type)
871 {
872   int nfr;
873   debugLog ("%s\n", __FUNCTION__);
874   if (type == REG_PTR)
875     {
876       if ((nfr = nFreeRegs (type)) == 0)
877         return nFreeRegs (REG_GPR);
878     }
879
880   return nFreeRegs (type);
881 }
882
883 //<<<<<<< ralloc.c
884 void writeSetUsedRegs(FILE *of, set *dRegs)
885 {
886
887   regs *dReg;
888
889   for (dReg = setFirstItem(dRegs) ; dReg ; 
890        dReg = setNextItem(dRegs)) {
891
892     if(dReg->wasUsed)
893       fprintf (of, "\t%s\n",dReg->name);
894   }
895
896 }
897 extern void assignFixedRegisters(set *regset);
898 extern void assignRelocatableRegisters(set *regset,int used);
899 extern void dump_map(void);
900 extern void dump_cblock(FILE *of);
901
902
903 void packBits(set *bregs)
904 {
905   set *regset;
906   regs *breg;
907   regs *bitfield=NULL;
908   regs *relocbitfield=NULL;
909   int bit_no=0;
910   int byte_no=-1;
911   char buffer[20];
912
913   for (regset = bregs ; regset ;
914        regset = regset->next) {
915
916     breg = regset->item;
917     breg->isBitField = 1;
918     //fprintf(stderr,"bit reg: %s\n",breg->name);
919
920     if(breg->isFixed) {
921       //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
922
923       bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
924       breg->rIdx = breg->address & 7;
925       breg->address >>= 3;
926
927       if(!bitfield) {
928         sprintf (buffer, "fbitfield%02x", breg->address);
929         //fprintf(stderr,"new bit field\n");
930         bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
931         bitfield->isBitField = 1;
932         bitfield->isFixed = 1;
933         bitfield->address = breg->address;
934         addSet(&dynDirectRegs,bitfield);
935         hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
936       } else {
937         //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
938         ;
939       }
940       breg->reg_alias = bitfield;
941       bitfield = NULL;
942
943     } else {
944       if(!relocbitfield || bit_no >7) {
945         byte_no++;
946         bit_no=0;
947         sprintf (buffer, "bitfield%d", byte_no);
948         //fprintf(stderr,"new relocatable bit field\n");
949         relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
950         relocbitfield->isBitField = 1;
951         addSet(&dynDirectRegs,relocbitfield);
952         hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
953
954       }
955
956       breg->reg_alias = relocbitfield;
957       breg->address = rDirectIdx;   /* byte_no; */
958       breg->rIdx = bit_no++;
959     }
960   }
961       
962 }
963
964
965
966 void bitEQUs(FILE *of, set *bregs)
967 {
968   regs *breg,*bytereg;
969   int bit_no=0;
970
971   //fprintf(stderr," %s\n",__FUNCTION__);
972   for (breg = setFirstItem(bregs) ; breg ;
973        breg = setNextItem(bregs)) {
974
975     //fprintf(stderr,"bit reg: %s\n",breg->name);
976
977     bytereg = breg->reg_alias;
978     if(bytereg)
979       fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
980                breg->name,
981                bytereg->name,
982                breg->rIdx & 0x0007);
983
984     else {
985       fprintf(stderr, "bit field is not assigned to a register\n");
986       fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
987                breg->name,
988                bit_no>>3,
989                bit_no & 0x0007);
990
991       bit_no++;
992     }
993   }
994       
995 }
996 void aliasEQUs(FILE *of, set *fregs)
997 {
998   regs *reg;
999
1000
1001   for (reg = setFirstItem(fregs) ; reg ;
1002        reg = setNextItem(fregs)) {
1003
1004     if(!reg->isEmitted)
1005       fprintf (of, "%s\tEQU\t0x%03x\n",
1006                reg->name,
1007                reg->address);
1008   }
1009       
1010 }
1011
1012 void writeUsedRegs(FILE *of) 
1013 {
1014   packBits(dynDirectBitRegs);
1015
1016   assignFixedRegisters(dynAllocRegs);
1017   assignFixedRegisters(dynStackRegs);
1018   assignFixedRegisters(dynDirectRegs);
1019
1020   assignRelocatableRegisters(dynInternalRegs,1);
1021   assignRelocatableRegisters(dynAllocRegs,0);
1022   assignRelocatableRegisters(dynStackRegs,0);
1023   assignRelocatableRegisters(dynDirectRegs,0);
1024
1025   //dump_map();
1026
1027   dump_cblock(of);
1028   bitEQUs(of,dynDirectBitRegs);
1029   aliasEQUs(of,dynAllocRegs);
1030   aliasEQUs(of,dynDirectRegs);
1031   aliasEQUs(of,dynStackRegs);
1032
1033 }
1034 #if 0
1035 /*-----------------------------------------------------------------*/
1036 /* allDefsOutOfRange - all definitions are out of a range          */
1037 /*-----------------------------------------------------------------*/
1038 static bool
1039 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1040 {
1041   int i;
1042
1043   debugLog ("%s\n", __FUNCTION__);
1044   if (!defs)
1045     return TRUE;
1046
1047   for (i = 0; i < defs->size; i++)
1048     {
1049       iCode *ic;
1050
1051       if (bitVectBitValue (defs, i) &&
1052           (ic = hTabItemWithKey (iCodehTab, i)) &&
1053           (ic->seq >= fseq && ic->seq <= toseq))
1054
1055         return FALSE;
1056
1057     }
1058
1059   return TRUE;
1060 }
1061 #endif
1062 //=======
1063 //>>>>>>> 1.28
1064 /*-----------------------------------------------------------------*/
1065 /* computeSpillable - given a point find the spillable live ranges */
1066 /*-----------------------------------------------------------------*/
1067 static bitVect *
1068 computeSpillable (iCode * ic)
1069 {
1070   bitVect *spillable;
1071
1072   debugLog ("%s\n", __FUNCTION__);
1073   /* spillable live ranges are those that are live at this 
1074      point . the following categories need to be subtracted
1075      from this set. 
1076      a) - those that are already spilt
1077      b) - if being used by this one
1078      c) - defined by this one */
1079
1080   spillable = bitVectCopy (ic->rlive);
1081   spillable =
1082     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
1083   spillable =
1084     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
1085   bitVectUnSetBit (spillable, ic->defKey);
1086   spillable = bitVectIntersect (spillable, _G.regAssigned);
1087   return spillable;
1088
1089 }
1090
1091 /*-----------------------------------------------------------------*/
1092 /* noSpilLoc - return true if a variable has no spil location      */
1093 /*-----------------------------------------------------------------*/
1094 static int
1095 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1096 {
1097   debugLog ("%s\n", __FUNCTION__);
1098   return (sym->usl.spillLoc ? 0 : 1);
1099 }
1100
1101 /*-----------------------------------------------------------------*/
1102 /* hasSpilLoc - will return 1 if the symbol has spil location      */
1103 /*-----------------------------------------------------------------*/
1104 static int
1105 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1106 {
1107   debugLog ("%s\n", __FUNCTION__);
1108   return (sym->usl.spillLoc ? 1 : 0);
1109 }
1110
1111 /*-----------------------------------------------------------------*/
1112 /* directSpilLoc - will return 1 if the splilocation is in direct  */
1113 /*-----------------------------------------------------------------*/
1114 static int
1115 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1116 {
1117   debugLog ("%s\n", __FUNCTION__);
1118   if (sym->usl.spillLoc &&
1119       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1120     return 1;
1121   else
1122     return 0;
1123 }
1124
1125 /*-----------------------------------------------------------------*/
1126 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1127 /*                    but is not used as a pointer                 */
1128 /*-----------------------------------------------------------------*/
1129 static int
1130 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1131 {
1132   debugLog ("%s\n", __FUNCTION__);
1133   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1134 }
1135
1136 /*-----------------------------------------------------------------*/
1137 /* rematable - will return 1 if the remat flag is set              */
1138 /*-----------------------------------------------------------------*/
1139 static int
1140 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1141 {
1142   debugLog ("%s\n", __FUNCTION__);
1143   return sym->remat;
1144 }
1145
1146 /*-----------------------------------------------------------------*/
1147 /* notUsedInRemaining - not used or defined in remain of the block */
1148 /*-----------------------------------------------------------------*/
1149 static int
1150 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1151 {
1152   debugLog ("%s\n", __FUNCTION__);
1153   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1154           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1155 }
1156
1157 /*-----------------------------------------------------------------*/
1158 /* allLRs - return true for all                                    */
1159 /*-----------------------------------------------------------------*/
1160 static int
1161 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1162 {
1163   debugLog ("%s\n", __FUNCTION__);
1164   return 1;
1165 }
1166
1167 /*-----------------------------------------------------------------*/
1168 /* liveRangesWith - applies function to a given set of live range  */
1169 /*-----------------------------------------------------------------*/
1170 static set *
1171 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1172                 eBBlock * ebp, iCode * ic)
1173 {
1174   set *rset = NULL;
1175   int i;
1176
1177   debugLog ("%s\n", __FUNCTION__);
1178   if (!lrs || !lrs->size)
1179     return NULL;
1180
1181   for (i = 1; i < lrs->size; i++)
1182     {
1183       symbol *sym;
1184       if (!bitVectBitValue (lrs, i))
1185         continue;
1186
1187       /* if we don't find it in the live range 
1188          hash table we are in serious trouble */
1189       if (!(sym = hTabItemWithKey (liveRanges, i)))
1190         {
1191           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1192                   "liveRangesWith could not find liveRange");
1193           exit (1);
1194         }
1195
1196       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1197         addSetHead (&rset, sym);
1198     }
1199
1200   return rset;
1201 }
1202
1203
1204 /*-----------------------------------------------------------------*/
1205 /* leastUsedLR - given a set determines which is the least used    */
1206 /*-----------------------------------------------------------------*/
1207 static symbol *
1208 leastUsedLR (set * sset)
1209 {
1210   symbol *sym = NULL, *lsym = NULL;
1211
1212   debugLog ("%s\n", __FUNCTION__);
1213   sym = lsym = setFirstItem (sset);
1214
1215   if (!lsym)
1216     return NULL;
1217
1218   for (; lsym; lsym = setNextItem (sset))
1219     {
1220
1221       /* if usage is the same then prefer
1222          the spill the smaller of the two */
1223       if (lsym->used == sym->used)
1224         if (getSize (lsym->type) < getSize (sym->type))
1225           sym = lsym;
1226
1227       /* if less usage */
1228       if (lsym->used < sym->used)
1229         sym = lsym;
1230
1231     }
1232
1233   setToNull ((void **) &sset);
1234   sym->blockSpil = 0;
1235   return sym;
1236 }
1237
1238 /*-----------------------------------------------------------------*/
1239 /* noOverLap - will iterate through the list looking for over lap  */
1240 /*-----------------------------------------------------------------*/
1241 static int
1242 noOverLap (set * itmpStack, symbol * fsym)
1243 {
1244   symbol *sym;
1245   debugLog ("%s\n", __FUNCTION__);
1246
1247
1248   for (sym = setFirstItem (itmpStack); sym;
1249        sym = setNextItem (itmpStack))
1250     {
1251       if (sym->liveTo > fsym->liveFrom)
1252         return 0;
1253
1254     }
1255
1256   return 1;
1257 }
1258
1259 /*-----------------------------------------------------------------*/
1260 /* isFree - will return 1 if the a free spil location is found     */
1261 /*-----------------------------------------------------------------*/
1262 static
1263 DEFSETFUNC (isFree)
1264 {
1265   symbol *sym = item;
1266   V_ARG (symbol **, sloc);
1267   V_ARG (symbol *, fsym);
1268
1269   debugLog ("%s\n", __FUNCTION__);
1270   /* if already found */
1271   if (*sloc)
1272     return 0;
1273
1274   /* if it is free && and the itmp assigned to
1275      this does not have any overlapping live ranges
1276      with the one currently being assigned and
1277      the size can be accomodated  */
1278   if (sym->isFree &&
1279       noOverLap (sym->usl.itmpStack, fsym) &&
1280       getSize (sym->type) >= getSize (fsym->type))
1281     {
1282       *sloc = sym;
1283       return 1;
1284     }
1285
1286   return 0;
1287 }
1288
1289 /*-----------------------------------------------------------------*/
1290 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
1291 /*-----------------------------------------------------------------*/
1292 static void
1293 spillLRWithPtrReg (symbol * forSym)
1294 {
1295   symbol *lrsym;
1296   regs *r0, *r1;
1297   int k;
1298
1299   debugLog ("%s\n", __FUNCTION__);
1300   if (!_G.regAssigned ||
1301       bitVectIsZero (_G.regAssigned))
1302     return;
1303
1304   r0 = pic14_regWithIdx (R0_IDX);
1305   r1 = pic14_regWithIdx (R1_IDX);
1306
1307   /* for all live ranges */
1308   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1309        lrsym = hTabNextItem (liveRanges, &k))
1310     {
1311       int j;
1312
1313       /* if no registers assigned to it or
1314          spilt */
1315       /* if it does not overlap with this then 
1316          not need to spill it */
1317
1318       if (lrsym->isspilt || !lrsym->nRegs ||
1319           (lrsym->liveTo < forSym->liveFrom))
1320         continue;
1321
1322       /* go thru the registers : if it is either
1323          r0 or r1 then spil it */
1324       for (j = 0; j < lrsym->nRegs; j++)
1325         if (lrsym->regs[j] == r0 ||
1326             lrsym->regs[j] == r1)
1327           {
1328             spillThis (lrsym);
1329             break;
1330           }
1331     }
1332
1333 }
1334
1335 /*-----------------------------------------------------------------*/
1336 /* createStackSpil - create a location on the stack to spil        */
1337 /*-----------------------------------------------------------------*/
1338 static symbol *
1339 createStackSpil (symbol * sym)
1340 {
1341   symbol *sloc = NULL;
1342   int useXstack, model, noOverlay;
1343
1344   char slocBuffer[30];
1345   debugLog ("%s\n", __FUNCTION__);
1346
1347   /* first go try and find a free one that is already 
1348      existing on the stack */
1349   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1350     {
1351       /* found a free one : just update & return */
1352       sym->usl.spillLoc = sloc;
1353       sym->stackSpil = 1;
1354       sloc->isFree = 0;
1355       addSetHead (&sloc->usl.itmpStack, sym);
1356       return sym;
1357     }
1358
1359   /* could not then have to create one , this is the hard part
1360      we need to allocate this on the stack : this is really a
1361      hack!! but cannot think of anything better at this time */
1362
1363   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1364     {
1365       fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1366                __FILE__, __LINE__);
1367       exit (1);
1368     }
1369
1370   sloc = newiTemp (slocBuffer);
1371
1372   /* set the type to the spilling symbol */
1373   sloc->type = copyLinkChain (sym->type);
1374   sloc->etype = getSpec (sloc->type);
1375   SPEC_SCLS (sloc->etype) = S_DATA;
1376   SPEC_EXTR (sloc->etype) = 0;
1377   SPEC_STAT (sloc->etype) = 0;
1378
1379   /* we don't allow it to be allocated`
1380      onto the external stack since : so we
1381      temporarily turn it off ; we also
1382      turn off memory model to prevent
1383      the spil from going to the external storage
1384      and turn off overlaying 
1385    */
1386
1387   useXstack = options.useXstack;
1388   model = options.model;
1389   noOverlay = options.noOverlay;
1390   options.noOverlay = 1;
1391   options.model = options.useXstack = 0;
1392
1393   allocLocal (sloc);
1394
1395   options.useXstack = useXstack;
1396   options.model = model;
1397   options.noOverlay = noOverlay;
1398   sloc->isref = 1;              /* to prevent compiler warning */
1399
1400   /* if it is on the stack then update the stack */
1401   if (IN_STACK (sloc->etype))
1402     {
1403       currFunc->stack += getSize (sloc->type);
1404       _G.stackExtend += getSize (sloc->type);
1405     }
1406   else
1407     _G.dataExtend += getSize (sloc->type);
1408
1409   /* add it to the _G.stackSpil set */
1410   addSetHead (&_G.stackSpil, sloc);
1411   sym->usl.spillLoc = sloc;
1412   sym->stackSpil = 1;
1413
1414   /* add it to the set of itempStack set 
1415      of the spill location */
1416   addSetHead (&sloc->usl.itmpStack, sym);
1417   return sym;
1418 }
1419
1420 /*-----------------------------------------------------------------*/
1421 /* isSpiltOnStack - returns true if the spil location is on stack  */
1422 /*-----------------------------------------------------------------*/
1423 static bool
1424 isSpiltOnStack (symbol * sym)
1425 {
1426   sym_link *etype;
1427
1428   debugLog ("%s\n", __FUNCTION__);
1429   if (!sym)
1430     return FALSE;
1431
1432   if (!sym->isspilt)
1433     return FALSE;
1434
1435 /*     if (sym->_G.stackSpil) */
1436 /*      return TRUE; */
1437
1438   if (!sym->usl.spillLoc)
1439     return FALSE;
1440
1441   etype = getSpec (sym->usl.spillLoc->type);
1442   if (IN_STACK (etype))
1443     return TRUE;
1444
1445   return FALSE;
1446 }
1447
1448 /*-----------------------------------------------------------------*/
1449 /* spillThis - spils a specific operand                            */
1450 /*-----------------------------------------------------------------*/
1451 static void
1452 spillThis (symbol * sym)
1453 {
1454   int i;
1455   debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1456
1457   /* if this is rematerializable or has a spillLocation
1458      we are okay, else we need to create a spillLocation
1459      for it */
1460   if (!(sym->remat || sym->usl.spillLoc))
1461     createStackSpil (sym);
1462
1463
1464   /* mark it has spilt & put it in the spilt set */
1465   sym->isspilt = 1;
1466   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1467
1468   bitVectUnSetBit (_G.regAssigned, sym->key);
1469
1470   for (i = 0; i < sym->nRegs; i++)
1471
1472     if (sym->regs[i])
1473       {
1474         freeReg (sym->regs[i]);
1475         sym->regs[i] = NULL;
1476       }
1477
1478   /* if spilt on stack then free up r0 & r1 
1479      if they could have been assigned to some
1480      LIVE ranges */
1481   if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1482     {
1483       pic14_ptrRegReq++;
1484       spillLRWithPtrReg (sym);
1485     }
1486
1487   if (sym->usl.spillLoc && !sym->remat)
1488     sym->usl.spillLoc->allocreq = 1;
1489   return;
1490 }
1491
1492 /*-----------------------------------------------------------------*/
1493 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1494 /*-----------------------------------------------------------------*/
1495 static symbol *
1496 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1497 {
1498   bitVect *lrcs = NULL;
1499   set *selectS;
1500   symbol *sym;
1501
1502   debugLog ("%s\n", __FUNCTION__);
1503   /* get the spillable live ranges */
1504   lrcs = computeSpillable (ic);
1505
1506   /* get all live ranges that are rematerizable */
1507   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1508     {
1509
1510       /* return the least used of these */
1511       return leastUsedLR (selectS);
1512     }
1513
1514   /* get live ranges with spillLocations in direct space */
1515   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1516     {
1517       sym = leastUsedLR (selectS);
1518       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1519                            sym->usl.spillLoc->rname :
1520                            sym->usl.spillLoc->name));
1521       sym->spildir = 1;
1522       /* mark it as allocation required */
1523       sym->usl.spillLoc->allocreq = 1;
1524       return sym;
1525     }
1526
1527   /* if the symbol is local to the block then */
1528   if (forSym->liveTo < ebp->lSeq)
1529     {
1530
1531       /* check if there are any live ranges allocated
1532          to registers that are not used in this block */
1533       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1534         {
1535           sym = leastUsedLR (selectS);
1536           /* if this is not rematerializable */
1537           if (!sym->remat)
1538             {
1539               _G.blockSpil++;
1540               sym->blockSpil = 1;
1541             }
1542           return sym;
1543         }
1544
1545       /* check if there are any live ranges that not
1546          used in the remainder of the block */
1547       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1548         {
1549           sym = leastUsedLR (selectS);
1550           if (!sym->remat)
1551             {
1552               sym->remainSpil = 1;
1553               _G.blockSpil++;
1554             }
1555           return sym;
1556         }
1557     }
1558
1559   /* find live ranges with spillocation && not used as pointers */
1560   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1561     {
1562
1563       sym = leastUsedLR (selectS);
1564       /* mark this as allocation required */
1565       sym->usl.spillLoc->allocreq = 1;
1566       return sym;
1567     }
1568
1569   /* find live ranges with spillocation */
1570   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1571     {
1572
1573       sym = leastUsedLR (selectS);
1574       sym->usl.spillLoc->allocreq = 1;
1575       return sym;
1576     }
1577
1578   /* couldn't find then we need to create a spil
1579      location on the stack , for which one? the least
1580      used ofcourse */
1581   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1582     {
1583
1584       /* return a created spil location */
1585       sym = createStackSpil (leastUsedLR (selectS));
1586       sym->usl.spillLoc->allocreq = 1;
1587       return sym;
1588     }
1589
1590   /* this is an extreme situation we will spill
1591      this one : happens very rarely but it does happen */
1592   spillThis (forSym);
1593   return forSym;
1594
1595 }
1596
1597 /*-----------------------------------------------------------------*/
1598 /* spilSomething - spil some variable & mark registers as free     */
1599 /*-----------------------------------------------------------------*/
1600 static bool
1601 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1602 {
1603   symbol *ssym;
1604   int i;
1605
1606   debugLog ("%s\n", __FUNCTION__);
1607   /* get something we can spil */
1608   ssym = selectSpil (ic, ebp, forSym);
1609
1610   /* mark it as spilt */
1611   ssym->isspilt = 1;
1612   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1613
1614   /* mark it as not register assigned &
1615      take it away from the set */
1616   bitVectUnSetBit (_G.regAssigned, ssym->key);
1617
1618   /* mark the registers as free */
1619   for (i = 0; i < ssym->nRegs; i++)
1620     if (ssym->regs[i])
1621       freeReg (ssym->regs[i]);
1622
1623   /* if spilt on stack then free up r0 & r1 
1624      if they could have been assigned to as gprs */
1625   if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1626     {
1627       pic14_ptrRegReq++;
1628       spillLRWithPtrReg (ssym);
1629     }
1630
1631   /* if this was a block level spil then insert push & pop 
1632      at the start & end of block respectively */
1633   if (ssym->blockSpil)
1634     {
1635       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1636       /* add push to the start of the block */
1637       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1638                                     ebp->sch->next : ebp->sch));
1639       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1640       /* add pop to the end of the block */
1641       addiCodeToeBBlock (ebp, nic, NULL);
1642     }
1643
1644   /* if spilt because not used in the remainder of the
1645      block then add a push before this instruction and
1646      a pop at the end of the block */
1647   if (ssym->remainSpil)
1648     {
1649
1650       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1651       /* add push just before this instruction */
1652       addiCodeToeBBlock (ebp, nic, ic);
1653
1654       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1655       /* add pop to the end of the block */
1656       addiCodeToeBBlock (ebp, nic, NULL);
1657     }
1658
1659   if (ssym == forSym)
1660     return FALSE;
1661   else
1662     return TRUE;
1663 }
1664
1665 /*-----------------------------------------------------------------*/
1666 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1667 /*-----------------------------------------------------------------*/
1668 static regs *
1669 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1670 {
1671   regs *reg;
1672
1673   debugLog ("%s\n", __FUNCTION__);
1674 tryAgain:
1675   /* try for a ptr type */
1676   if ((reg = allocReg (REG_PTR)))
1677     return reg;
1678
1679   /* try for gpr type */
1680   if ((reg = allocReg (REG_GPR)))
1681     return reg;
1682
1683   /* we have to spil */
1684   if (!spilSomething (ic, ebp, sym))
1685     return NULL;
1686
1687   /* this looks like an infinite loop but 
1688      in really selectSpil will abort  */
1689   goto tryAgain;
1690 }
1691
1692 /*-----------------------------------------------------------------*/
1693 /* getRegGpr - will try for GPR if not spil                        */
1694 /*-----------------------------------------------------------------*/
1695 static regs *
1696 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1697 {
1698   regs *reg;
1699
1700   debugLog ("%s\n", __FUNCTION__);
1701 tryAgain:
1702   /* try for gpr type */
1703   if ((reg = allocReg (REG_GPR)))
1704     return reg;
1705
1706   if (!pic14_ptrRegReq)
1707     if ((reg = allocReg (REG_PTR)))
1708       return reg;
1709
1710   /* we have to spil */
1711   if (!spilSomething (ic, ebp, sym))
1712     return NULL;
1713
1714   /* this looks like an infinite loop but 
1715      in really selectSpil will abort  */
1716   goto tryAgain;
1717 }
1718
1719 /*-----------------------------------------------------------------*/
1720 /* symHasReg - symbol has a given register                         */
1721 /*-----------------------------------------------------------------*/
1722 static bool
1723 symHasReg (symbol * sym, regs * reg)
1724 {
1725   int i;
1726
1727   debugLog ("%s\n", __FUNCTION__);
1728   for (i = 0; i < sym->nRegs; i++)
1729     if (sym->regs[i] == reg)
1730       return TRUE;
1731
1732   return FALSE;
1733 }
1734
1735 /*-----------------------------------------------------------------*/
1736 /* deassignLRs - check the live to and if they have registers & are */
1737 /*               not spilt then free up the registers              */
1738 /*-----------------------------------------------------------------*/
1739 static void
1740 deassignLRs (iCode * ic, eBBlock * ebp)
1741 {
1742   symbol *sym;
1743   int k;
1744   symbol *result;
1745
1746   debugLog ("%s\n", __FUNCTION__);
1747   for (sym = hTabFirstItem (liveRanges, &k); sym;
1748        sym = hTabNextItem (liveRanges, &k))
1749     {
1750
1751       symbol *psym = NULL;
1752       /* if it does not end here */
1753       if (sym->liveTo > ic->seq)
1754         continue;
1755
1756       /* if it was spilt on stack then we can 
1757          mark the stack spil location as free */
1758       if (sym->isspilt)
1759         {
1760           if (sym->stackSpil)
1761             {
1762               sym->usl.spillLoc->isFree = 1;
1763               sym->stackSpil = 0;
1764             }
1765           continue;
1766         }
1767
1768       if (!bitVectBitValue (_G.regAssigned, sym->key))
1769         continue;
1770
1771       /* special case check if this is an IFX &
1772          the privious one was a pop and the 
1773          previous one was not spilt then keep track
1774          of the symbol */
1775       if (ic->op == IFX && ic->prev &&
1776           ic->prev->op == IPOP &&
1777           !ic->prev->parmPush &&
1778           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1779         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1780
1781       if (sym->nRegs)
1782         {
1783           int i = 0;
1784
1785           bitVectUnSetBit (_G.regAssigned, sym->key);
1786
1787           /* if the result of this one needs registers
1788              and does not have it then assign it right
1789              away */
1790           if (IC_RESULT (ic) &&
1791               !(SKIP_IC2 (ic) ||        /* not a special icode */
1792                 ic->op == JUMPTABLE ||
1793                 ic->op == IFX ||
1794                 ic->op == IPUSH ||
1795                 ic->op == IPOP ||
1796                 ic->op == RETURN ||
1797                 POINTER_SET (ic)) &&
1798               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1799               result->liveTo > ic->seq &&       /* and will live beyond this */
1800               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1801               result->regType == sym->regType &&        /* same register types */
1802               result->nRegs &&  /* which needs registers */
1803               !result->isspilt &&       /* and does not already have them */
1804               !result->remat &&
1805               !bitVectBitValue (_G.regAssigned, result->key) &&
1806           /* the number of free regs + number of regs in this LR
1807              can accomodate the what result Needs */
1808               ((nfreeRegsType (result->regType) +
1809                 sym->nRegs) >= result->nRegs)
1810             )
1811             {
1812
1813               for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1814                 if (i < sym->nRegs)
1815                   result->regs[i] = sym->regs[i];
1816                 else
1817                   result->regs[i] = getRegGpr (ic, ebp, result);
1818
1819               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1820
1821             }
1822
1823           /* free the remaining */
1824           for (; i < sym->nRegs; i++)
1825             {
1826               if (psym)
1827                 {
1828                   if (!symHasReg (psym, sym->regs[i]))
1829                     freeReg (sym->regs[i]);
1830                 }
1831               else
1832                 freeReg (sym->regs[i]);
1833             }
1834         }
1835     }
1836 }
1837
1838
1839 /*-----------------------------------------------------------------*/
1840 /* reassignLR - reassign this to registers                         */
1841 /*-----------------------------------------------------------------*/
1842 static void
1843 reassignLR (operand * op)
1844 {
1845   symbol *sym = OP_SYMBOL (op);
1846   int i;
1847
1848   debugLog ("%s\n", __FUNCTION__);
1849   /* not spilt any more */
1850   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1851   bitVectUnSetBit (_G.spiltSet, sym->key);
1852
1853   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1854
1855   _G.blockSpil--;
1856
1857   for (i = 0; i < sym->nRegs; i++)
1858     sym->regs[i]->isFree = 0;
1859 }
1860
1861 /*-----------------------------------------------------------------*/
1862 /* willCauseSpill - determines if allocating will cause a spill    */
1863 /*-----------------------------------------------------------------*/
1864 static int
1865 willCauseSpill (int nr, int rt)
1866 {
1867   debugLog ("%s\n", __FUNCTION__);
1868   /* first check if there are any avlb registers
1869      of te type required */
1870   if (rt == REG_PTR)
1871     {
1872       /* special case for pointer type 
1873          if pointer type not avlb then 
1874          check for type gpr */
1875       if (nFreeRegs (rt) >= nr)
1876         return 0;
1877       if (nFreeRegs (REG_GPR) >= nr)
1878         return 0;
1879     }
1880   else
1881     {
1882       if (pic14_ptrRegReq)
1883         {
1884           if (nFreeRegs (rt) >= nr)
1885             return 0;
1886         }
1887       else
1888         {
1889           if (nFreeRegs (REG_PTR) +
1890               nFreeRegs (REG_GPR) >= nr)
1891             return 0;
1892         }
1893     }
1894
1895   debugLog (" ... yep it will (cause a spill)\n");
1896   /* it will cause a spil */
1897   return 1;
1898 }
1899
1900 /*-----------------------------------------------------------------*/
1901 /* positionRegs - the allocator can allocate same registers to res- */
1902 /* ult and operand, if this happens make sure they are in the same */
1903 /* position as the operand otherwise chaos results                 */
1904 /*-----------------------------------------------------------------*/
1905 static void
1906 positionRegs (symbol * result, symbol * opsym, int lineno)
1907 {
1908   int count = min (result->nRegs, opsym->nRegs);
1909   int i, j = 0, shared = 0;
1910
1911   debugLog ("%s\n", __FUNCTION__);
1912   /* if the result has been spilt then cannot share */
1913   if (opsym->isspilt)
1914     return;
1915 again:
1916   shared = 0;
1917   /* first make sure that they actually share */
1918   for (i = 0; i < count; i++)
1919     {
1920       for (j = 0; j < count; j++)
1921         {
1922           if (result->regs[i] == opsym->regs[j] && i != j)
1923             {
1924               shared = 1;
1925               goto xchgPositions;
1926             }
1927         }
1928     }
1929 xchgPositions:
1930   if (shared)
1931     {
1932       regs *tmp = result->regs[i];
1933       result->regs[i] = result->regs[j];
1934       result->regs[j] = tmp;
1935       goto again;
1936     }
1937 }
1938
1939 /*-----------------------------------------------------------------*/
1940 /* serialRegAssign - serially allocate registers to the variables  */
1941 /*-----------------------------------------------------------------*/
1942 static void
1943 serialRegAssign (eBBlock ** ebbs, int count)
1944 {
1945   int i;
1946
1947   debugLog ("%s\n", __FUNCTION__);
1948   /* for all blocks */
1949   for (i = 0; i < count; i++)
1950     {
1951
1952       iCode *ic;
1953
1954       if (ebbs[i]->noPath &&
1955           (ebbs[i]->entryLabel != entryLabel &&
1956            ebbs[i]->entryLabel != returnLabel))
1957         continue;
1958
1959       /* of all instructions do */
1960       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1961         {
1962
1963           debugLog ("  op: %s\n", decodeOp (ic->op));
1964
1965           /* if this is an ipop that means some live
1966              range will have to be assigned again */
1967           if (ic->op == IPOP)
1968             reassignLR (IC_LEFT (ic));
1969
1970           /* if result is present && is a true symbol */
1971           if (IC_RESULT (ic) && ic->op != IFX &&
1972               IS_TRUE_SYMOP (IC_RESULT (ic)))
1973             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1974
1975           /* take away registers from live
1976              ranges that end at this instruction */
1977           deassignLRs (ic, ebbs[i]);
1978
1979           /* some don't need registers */
1980           if (SKIP_IC2 (ic) ||
1981               ic->op == JUMPTABLE ||
1982               ic->op == IFX ||
1983               ic->op == IPUSH ||
1984               ic->op == IPOP ||
1985               (IC_RESULT (ic) && POINTER_SET (ic)))
1986             continue;
1987
1988           /* now we need to allocate registers
1989              only for the result */
1990           if (IC_RESULT (ic))
1991             {
1992               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1993               bitVect *spillable;
1994               int willCS;
1995               int j;
1996               int ptrRegSet = 0;
1997
1998               /* if it does not need or is spilt 
1999                  or is already assigned to registers
2000                  or will not live beyond this instructions */
2001               if (!sym->nRegs ||
2002                   sym->isspilt ||
2003                   bitVectBitValue (_G.regAssigned, sym->key) ||
2004                   sym->liveTo <= ic->seq)
2005                 continue;
2006
2007               /* if some liverange has been spilt at the block level
2008                  and this one live beyond this block then spil this
2009                  to be safe */
2010               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2011                 {
2012                   spillThis (sym);
2013                   continue;
2014                 }
2015               /* if trying to allocate this will cause
2016                  a spill and there is nothing to spill 
2017                  or this one is rematerializable then
2018                  spill this one */
2019               willCS = willCauseSpill (sym->nRegs, sym->regType);
2020               spillable = computeSpillable (ic);
2021               if (sym->remat ||
2022                   (willCS && bitVectIsZero (spillable)))
2023                 {
2024
2025                   spillThis (sym);
2026                   continue;
2027
2028                 }
2029
2030               /* if it has a spillocation & is used less than
2031                  all other live ranges then spill this */
2032                 if (willCS) {
2033                     if (sym->usl.spillLoc) {
2034                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2035                                                                          allLRs, ebbs[i], ic));
2036                         if (leastUsed && leastUsed->used > sym->used) {
2037                             spillThis (sym);
2038                             continue;
2039                         }
2040                     } else {
2041                         /* if none of the liveRanges have a spillLocation then better
2042                            to spill this one than anything else already assigned to registers */
2043                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2044                             /* if this is local to this block then we might find a block spil */
2045                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2046                                 spillThis (sym);
2047                                 continue;
2048                             }
2049                         }
2050                     }
2051                 }
2052
2053               if (ic->op == RECEIVE)
2054                 debugLog ("When I get clever, I'll optimize the receive logic\n");
2055
2056               /* if we need ptr regs for the right side
2057                  then mark it */
2058               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2059                   <= (unsigned) PTRSIZE)
2060                 {
2061                   pic14_ptrRegReq++;
2062                   ptrRegSet = 1;
2063                 }
2064               /* else we assign registers to it */
2065               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2066
2067               debugLog ("  %d - \n", __LINE__);
2068               if(debugF) 
2069                 bitVectDebugOn(_G.regAssigned, debugF);
2070
2071               for (j = 0; j < sym->nRegs; j++)
2072                 {
2073                   if (sym->regType == REG_PTR)
2074                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2075                   else
2076                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2077
2078                   /* if the allocation falied which means
2079                      this was spilt then break */
2080                   if (!sym->regs[j])
2081                     break;
2082                 }
2083               debugLog ("  %d - \n", __LINE__);
2084
2085               /* if it shares registers with operands make sure
2086                  that they are in the same position */
2087               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2088                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2089                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2090                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2091               /* do the same for the right operand */
2092               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2093                   OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2094                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2095                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2096
2097               debugLog ("  %d - \n", __LINE__);
2098               if (ptrRegSet)
2099                 {
2100                   debugLog ("  %d - \n", __LINE__);
2101                   pic14_ptrRegReq--;
2102                   ptrRegSet = 0;
2103                 }
2104
2105             }
2106         }
2107     }
2108 }
2109
2110 /*-----------------------------------------------------------------*/
2111 /* rUmaskForOp :- returns register mask for an operand             */
2112 /*-----------------------------------------------------------------*/
2113 static bitVect *
2114 rUmaskForOp (operand * op)
2115 {
2116   bitVect *rumask;
2117   symbol *sym;
2118   int j;
2119
2120   debugLog ("%s\n", __FUNCTION__);
2121   /* only temporaries are assigned registers */
2122   if (!IS_ITEMP (op))
2123     return NULL;
2124
2125   sym = OP_SYMBOL (op);
2126
2127   /* if spilt or no registers assigned to it
2128      then nothing */
2129   if (sym->isspilt || !sym->nRegs)
2130     return NULL;
2131
2132   rumask = newBitVect (pic14_nRegs);
2133
2134   for (j = 0; j < sym->nRegs; j++)
2135     {
2136       rumask = bitVectSetBit (rumask,
2137                               sym->regs[j]->rIdx);
2138     }
2139
2140   return rumask;
2141 }
2142
2143 /*-----------------------------------------------------------------*/
2144 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2145 /*-----------------------------------------------------------------*/
2146 static bitVect *
2147 regsUsedIniCode (iCode * ic)
2148 {
2149   bitVect *rmask = newBitVect (pic14_nRegs);
2150
2151   debugLog ("%s\n", __FUNCTION__);
2152   /* do the special cases first */
2153   if (ic->op == IFX)
2154     {
2155       rmask = bitVectUnion (rmask,
2156                             rUmaskForOp (IC_COND (ic)));
2157       goto ret;
2158     }
2159
2160   /* for the jumptable */
2161   if (ic->op == JUMPTABLE)
2162     {
2163       rmask = bitVectUnion (rmask,
2164                             rUmaskForOp (IC_JTCOND (ic)));
2165
2166       goto ret;
2167     }
2168
2169   /* of all other cases */
2170   if (IC_LEFT (ic))
2171     rmask = bitVectUnion (rmask,
2172                           rUmaskForOp (IC_LEFT (ic)));
2173
2174
2175   if (IC_RIGHT (ic))
2176     rmask = bitVectUnion (rmask,
2177                           rUmaskForOp (IC_RIGHT (ic)));
2178
2179   if (IC_RESULT (ic))
2180     rmask = bitVectUnion (rmask,
2181                           rUmaskForOp (IC_RESULT (ic)));
2182
2183 ret:
2184   return rmask;
2185 }
2186
2187 /*-----------------------------------------------------------------*/
2188 /* createRegMask - for each instruction will determine the regsUsed */
2189 /*-----------------------------------------------------------------*/
2190 static void
2191 createRegMask (eBBlock ** ebbs, int count)
2192 {
2193   int i;
2194
2195   debugLog ("%s\n", __FUNCTION__);
2196   /* for all blocks */
2197   for (i = 0; i < count; i++)
2198     {
2199       iCode *ic;
2200
2201       if (ebbs[i]->noPath &&
2202           (ebbs[i]->entryLabel != entryLabel &&
2203            ebbs[i]->entryLabel != returnLabel))
2204         continue;
2205
2206       /* for all instructions */
2207       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2208         {
2209
2210           int j;
2211
2212           if (SKIP_IC2 (ic) || !ic->rlive)
2213             continue;
2214
2215           /* first mark the registers used in this
2216              instruction */
2217           ic->rUsed = regsUsedIniCode (ic);
2218           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2219
2220           /* now create the register mask for those 
2221              registers that are in use : this is a
2222              super set of ic->rUsed */
2223           ic->rMask = newBitVect (pic14_nRegs + 1);
2224
2225           /* for all live Ranges alive at this point */
2226           for (j = 1; j < ic->rlive->size; j++)
2227             {
2228               symbol *sym;
2229               int k;
2230
2231               /* if not alive then continue */
2232               if (!bitVectBitValue (ic->rlive, j))
2233                 continue;
2234
2235               /* find the live range we are interested in */
2236               if (!(sym = hTabItemWithKey (liveRanges, j)))
2237                 {
2238                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2239                           "createRegMask cannot find live range");
2240                   exit (0);
2241                 }
2242
2243               /* if no register assigned to it */
2244               if (!sym->nRegs || sym->isspilt)
2245                 continue;
2246
2247               /* for all the registers allocated to it */
2248               for (k = 0; k < sym->nRegs; k++)
2249                 if (sym->regs[k])
2250                   ic->rMask =
2251                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2252             }
2253         }
2254     }
2255 }
2256
2257 /*-----------------------------------------------------------------*/
2258 /* rematStr - returns the rematerialized string for a remat var    */
2259 /*-----------------------------------------------------------------*/
2260 static symbol *
2261 rematStr (symbol * sym)
2262 {
2263   char *s = buffer;
2264   iCode *ic = sym->rematiCode;
2265   symbol *psym = NULL;
2266
2267   debugLog ("%s\n", __FUNCTION__);
2268
2269   //printf ("%s\n", s);
2270
2271   /* if plus or minus print the right hand side */
2272
2273   if (ic->op == '+' || ic->op == '-') {
2274         
2275     iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2276
2277     sprintf (s, "(%s %c 0x%04x)",
2278              OP_SYMBOL (IC_LEFT (ric))->rname,
2279              ic->op,
2280              (int) operandLitValue (IC_RIGHT (ic)));
2281
2282
2283     //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2284
2285     psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2286     psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2287
2288     return psym;
2289   }
2290
2291   sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2292   psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2293
2294   //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2295   return psym;
2296 }
2297
2298 #if 0
2299 /*-----------------------------------------------------------------*/
2300 /* rematStr - returns the rematerialized string for a remat var    */
2301 /*-----------------------------------------------------------------*/
2302 static char *
2303 rematStr (symbol * sym)
2304 {
2305   char *s = buffer;
2306   iCode *ic = sym->rematiCode;
2307
2308   debugLog ("%s\n", __FUNCTION__);
2309   while (1)
2310     {
2311
2312       printf ("%s\n", s);
2313       /* if plus or minus print the right hand side */
2314 /*
2315    if (ic->op == '+' || ic->op == '-') {
2316    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2317    ic->op );
2318    s += strlen(s);
2319    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2320    continue ;
2321    }
2322  */
2323       if (ic->op == '+' || ic->op == '-')
2324         {
2325           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2326           sprintf (s, "(%s %c 0x%04x)",
2327                    OP_SYMBOL (IC_LEFT (ric))->rname,
2328                    ic->op,
2329                    (int) operandLitValue (IC_RIGHT (ic)));
2330
2331           //s += strlen(s);
2332           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2333           //continue ;
2334           fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2335           return buffer;
2336         }
2337
2338       /* we reached the end */
2339       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2340       break;
2341     }
2342
2343   printf ("%s\n", buffer);
2344   return buffer;
2345 }
2346 #endif
2347
2348 /*-----------------------------------------------------------------*/
2349 /* regTypeNum - computes the type & number of registers required   */
2350 /*-----------------------------------------------------------------*/
2351 static void
2352 regTypeNum ()
2353 {
2354   symbol *sym;
2355   int k;
2356   iCode *ic;
2357
2358   debugLog ("%s\n", __FUNCTION__);
2359   /* for each live range do */
2360   for (sym = hTabFirstItem (liveRanges, &k); sym;
2361        sym = hTabNextItem (liveRanges, &k)) {
2362
2363     debugLog ("  %d - %s\n", __LINE__, sym->rname);
2364
2365     /* if used zero times then no registers needed */
2366     if ((sym->liveTo - sym->liveFrom) == 0)
2367       continue;
2368
2369
2370     /* if the live range is a temporary */
2371     if (sym->isitmp) {
2372
2373       debugLog ("  %d - itemp register\n", __LINE__);
2374
2375       /* if the type is marked as a conditional */
2376       if (sym->regType == REG_CND)
2377         continue;
2378
2379       /* if used in return only then we don't 
2380          need registers */
2381       if (sym->ruonly || sym->accuse) {
2382         if (IS_AGGREGATE (sym->type) || sym->isptr)
2383           sym->type = aggrToPtr (sym->type, FALSE);
2384         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
2385
2386         continue;
2387       }
2388
2389       /* if the symbol has only one definition &
2390          that definition is a get_pointer and the
2391          pointer we are getting is rematerializable and
2392          in "data" space */
2393
2394       if (bitVectnBitsOn (sym->defs) == 1 &&
2395           (ic = hTabItemWithKey (iCodehTab,
2396                                  bitVectFirstBit (sym->defs))) &&
2397           POINTER_GET (ic) &&
2398           !sym->noSpilLoc &&
2399           !IS_BITVAR (sym->etype)) {
2400         
2401
2402         debugLog ("  %d - \n", __LINE__);
2403
2404         /* if remat in data space */
2405         if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2406             DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2407
2408           /* create a psuedo symbol & force a spil */
2409           //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2410           symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2411           psym->type = sym->type;
2412           psym->etype = sym->etype;
2413           strcpy (psym->rname, psym->name);
2414           sym->isspilt = 1;
2415           sym->usl.spillLoc = psym;
2416           continue;
2417         }
2418
2419         /* if in data space or idata space then try to
2420            allocate pointer register */
2421
2422       }
2423
2424       /* if not then we require registers */
2425       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2426                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2427                     getSize (sym->type));
2428
2429
2430     if(IS_PTR_CONST (sym->type)) {
2431       debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2432       sym->nRegs = 2;
2433     }
2434
2435       if (sym->nRegs > 4) {
2436         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2437         printTypeChain (sym->type, stderr);
2438         fprintf (stderr, "\n");
2439       }
2440
2441       /* determine the type of register required */
2442       if (sym->nRegs == 1 &&
2443           IS_PTR (sym->type) &&
2444           sym->uptr)
2445         sym->regType = REG_PTR;
2446       else
2447         sym->regType = REG_GPR;
2448
2449
2450       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2451
2452     }
2453     else
2454       /* for the first run we don't provide */
2455       /* registers for true symbols we will */
2456       /* see how things go                  */
2457       sym->nRegs = 0;
2458   }
2459
2460 }
2461 DEFSETFUNC (markRegFree)
2462 {
2463   ((regs *)item)->isFree = 1;
2464
2465   return 0;
2466 }
2467
2468 DEFSETFUNC (deallocReg)
2469 {
2470   ((regs *)item)->isFree = 1;
2471   ((regs *)item)->wasUsed = 0;
2472
2473   return 0;
2474 }
2475 /*-----------------------------------------------------------------*/
2476 /* freeAllRegs - mark all registers as free                        */
2477 /*-----------------------------------------------------------------*/
2478 void
2479 pic14_freeAllRegs ()
2480 {
2481   //  int i;
2482
2483   debugLog ("%s\n", __FUNCTION__);
2484
2485   applyToSet(dynAllocRegs,markRegFree);
2486   applyToSet(dynStackRegs,markRegFree);
2487
2488 /*
2489   for (i = 0; i < pic14_nRegs; i++)
2490     regspic14[i].isFree = 1;
2491 */
2492 }
2493
2494 /*-----------------------------------------------------------------*/
2495 /*-----------------------------------------------------------------*/
2496 void
2497 pic14_deallocateAllRegs ()
2498 {
2499   //  int i;
2500
2501   debugLog ("%s\n", __FUNCTION__);
2502
2503   applyToSet(dynAllocRegs,deallocReg);
2504
2505 /*
2506   for (i = 0; i < pic14_nRegs; i++) {
2507     if(regspic14[i].pc_type == PO_GPR_TEMP) {
2508       regspic14[i].isFree = 1;
2509       regspic14[i].wasUsed = 0;
2510     }
2511   }
2512 */
2513 }
2514
2515
2516 /*-----------------------------------------------------------------*/
2517 /* deallocStackSpil - this will set the stack pointer back         */
2518 /*-----------------------------------------------------------------*/
2519 static
2520 DEFSETFUNC (deallocStackSpil)
2521 {
2522   symbol *sym = item;
2523
2524   debugLog ("%s\n", __FUNCTION__);
2525   deallocLocal (sym);
2526   return 0;
2527 }
2528
2529 /*-----------------------------------------------------------------*/
2530 /* farSpacePackable - returns the packable icode for far variables */
2531 /*-----------------------------------------------------------------*/
2532 static iCode *
2533 farSpacePackable (iCode * ic)
2534 {
2535   iCode *dic;
2536
2537   debugLog ("%s\n", __FUNCTION__);
2538   /* go thru till we find a definition for the
2539      symbol on the right */
2540   for (dic = ic->prev; dic; dic = dic->prev)
2541     {
2542
2543       /* if the definition is a call then no */
2544       if ((dic->op == CALL || dic->op == PCALL) &&
2545           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2546         {
2547           return NULL;
2548         }
2549
2550       /* if shift by unknown amount then not */
2551       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2552           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2553         return NULL;
2554
2555       /* if pointer get and size > 1 */
2556       if (POINTER_GET (dic) &&
2557           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2558         return NULL;
2559
2560       if (POINTER_SET (dic) &&
2561           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2562         return NULL;
2563
2564       /* if any three is a true symbol in far space */
2565       if (IC_RESULT (dic) &&
2566           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2567           isOperandInFarSpace (IC_RESULT (dic)))
2568         return NULL;
2569
2570       if (IC_RIGHT (dic) &&
2571           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2572           isOperandInFarSpace (IC_RIGHT (dic)) &&
2573           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2574         return NULL;
2575
2576       if (IC_LEFT (dic) &&
2577           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2578           isOperandInFarSpace (IC_LEFT (dic)) &&
2579           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2580         return NULL;
2581
2582       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2583         {
2584           if ((dic->op == LEFT_OP ||
2585                dic->op == RIGHT_OP ||
2586                dic->op == '-') &&
2587               IS_OP_LITERAL (IC_RIGHT (dic)))
2588             return NULL;
2589           else
2590             return dic;
2591         }
2592     }
2593
2594   return NULL;
2595 }
2596
2597 /*-----------------------------------------------------------------*/
2598 /* packRegsForAssign - register reduction for assignment           */
2599 /*-----------------------------------------------------------------*/
2600 static int
2601 packRegsForAssign (iCode * ic, eBBlock * ebp)
2602 {
2603
2604   iCode *dic, *sic;
2605
2606   debugLog ("%s\n", __FUNCTION__);
2607
2608   debugAopGet ("  result:", IC_RESULT (ic));
2609   debugAopGet ("  left:", IC_LEFT (ic));
2610   debugAopGet ("  right:", IC_RIGHT (ic));
2611
2612   /* if this is at an absolute address, then get the address. */
2613   if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2614     if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2615       debugLog ("  %d - found config word declaration\n", __LINE__);
2616       if(IS_VALOP(IC_RIGHT(ic))) {
2617         debugLog ("  setting config word to %x\n", 
2618                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2619         assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2620                                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2621       }
2622
2623       /* remove the assignment from the iCode chain. */
2624
2625       remiCodeFromeBBlock (ebp, ic);
2626       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2627       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2628
2629       return 1;
2630
2631     }
2632   }
2633
2634   if (!IS_ITEMP (IC_RESULT (ic))) {
2635     allocDirReg(IC_RESULT (ic));
2636     debugLog ("  %d - result is not temp\n", __LINE__);
2637   }
2638 /*
2639   if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2640     debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2641     allocDirReg(IC_LEFT (ic));
2642   }
2643 */
2644
2645   if (!IS_ITEMP (IC_RIGHT (ic))) {
2646     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2647     allocDirReg(IC_RIGHT (ic));
2648     return 0;
2649   }
2650
2651   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2652       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2653     {
2654       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2655       return 0;
2656     }
2657
2658   /* if the true symbol is defined in far space or on stack
2659      then we should not since this will increase register pressure */
2660   if (isOperandInFarSpace (IC_RESULT (ic)))
2661     {
2662       if ((dic = farSpacePackable (ic)))
2663         goto pack;
2664       else
2665         return 0;
2666
2667     }
2668   /* find the definition of iTempNN scanning backwards if we find a 
2669      a use of the true symbol before we find the definition then 
2670      we cannot pack */
2671   for (dic = ic->prev; dic; dic = dic->prev)
2672     {
2673
2674       /* if there is a function call and this is
2675          a parameter & not my parameter then don't pack it */
2676       if ((dic->op == CALL || dic->op == PCALL) &&
2677           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2678            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2679         {
2680           debugLog ("  %d - \n", __LINE__);
2681           dic = NULL;
2682           break;
2683         }
2684
2685       if (SKIP_IC2 (dic))
2686         continue;
2687
2688       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2689           IS_OP_VOLATILE (IC_RESULT (dic)))
2690         {
2691           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2692           dic = NULL;
2693           break;
2694         }
2695
2696       if (IS_SYMOP (IC_RESULT (dic)) &&
2697           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2698         {
2699           /* A previous result was assigned to the same register - we'll our definition */
2700           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2701                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2702           if (POINTER_SET (dic))
2703             dic = NULL;
2704
2705           break;
2706         }
2707
2708       if (IS_SYMOP (IC_RIGHT (dic)) &&
2709           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2710            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2711         {
2712           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2713           dic = NULL;
2714           break;
2715         }
2716
2717       if (IS_SYMOP (IC_LEFT (dic)) &&
2718           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2719            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2720         {
2721           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2722           dic = NULL;
2723           break;
2724         }
2725
2726       if (POINTER_SET (dic) &&
2727           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2728         {
2729           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2730                     __LINE__);
2731           dic = NULL;
2732           break;
2733         }
2734     }
2735
2736   if (!dic)
2737     return 0;                   /* did not find */
2738
2739   /* if the result is on stack or iaccess then it must be
2740      the same atleast one of the operands */
2741   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2742       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2743     {
2744
2745       /* the operation has only one symbol
2746          operator then we can pack */
2747       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2748           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2749         goto pack;
2750
2751       if (!((IC_LEFT (dic) &&
2752              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2753             (IC_RIGHT (dic) &&
2754              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2755         return 0;
2756     }
2757 pack:
2758   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2759   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2760   /* found the definition */
2761   /* replace the result with the result of */
2762   /* this assignment and remove this assignment */
2763   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2764   IC_RESULT (dic) = IC_RESULT (ic);
2765
2766   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2767     {
2768       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2769     }
2770   /* delete from liverange table also 
2771      delete from all the points inbetween and the new
2772      one */
2773   for (sic = dic; sic != ic; sic = sic->next)
2774     {
2775       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2776       if (IS_ITEMP (IC_RESULT (dic)))
2777         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2778     }
2779
2780   remiCodeFromeBBlock (ebp, ic);
2781   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2782   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2783   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2784   return 1;
2785
2786
2787 }
2788
2789 /*-----------------------------------------------------------------*/
2790 /* findAssignToSym : scanning backwards looks for first assig found */
2791 /*-----------------------------------------------------------------*/
2792 static iCode *
2793 findAssignToSym (operand * op, iCode * ic)
2794 {
2795   iCode *dic;
2796
2797   debugLog ("%s\n", __FUNCTION__);
2798   for (dic = ic->prev; dic; dic = dic->prev)
2799     {
2800
2801       /* if definition by assignment */
2802       if (dic->op == '=' &&
2803           !POINTER_SET (dic) &&
2804           IC_RESULT (dic)->key == op->key
2805 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2806         )
2807         {
2808
2809           /* we are interested only if defined in far space */
2810           /* or in stack space in case of + & - */
2811
2812           /* if assigned to a non-symbol then return
2813              true */
2814           if (!IS_SYMOP (IC_RIGHT (dic)))
2815             break;
2816
2817           /* if the symbol is in far space then
2818              we should not */
2819           if (isOperandInFarSpace (IC_RIGHT (dic)))
2820             return NULL;
2821
2822           /* for + & - operations make sure that
2823              if it is on the stack it is the same
2824              as one of the three operands */
2825           if ((ic->op == '+' || ic->op == '-') &&
2826               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2827             {
2828
2829               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2830                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2831                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2832                 return NULL;
2833             }
2834
2835           break;
2836
2837         }
2838
2839       /* if we find an usage then we cannot delete it */
2840       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2841         return NULL;
2842
2843       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2844         return NULL;
2845
2846       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2847         return NULL;
2848     }
2849
2850   /* now make sure that the right side of dic
2851      is not defined between ic & dic */
2852   if (dic)
2853     {
2854       iCode *sic = dic->next;
2855
2856       for (; sic != ic; sic = sic->next)
2857         if (IC_RESULT (sic) &&
2858             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2859           return NULL;
2860     }
2861
2862   return dic;
2863
2864
2865 }
2866
2867 /*-----------------------------------------------------------------*/
2868 /* packRegsForSupport :- reduce some registers for support calls   */
2869 /*-----------------------------------------------------------------*/
2870 static int
2871 packRegsForSupport (iCode * ic, eBBlock * ebp)
2872 {
2873   int change = 0;
2874
2875   debugLog ("%s\n", __FUNCTION__);
2876   /* for the left & right operand :- look to see if the
2877      left was assigned a true symbol in far space in that
2878      case replace them */
2879   if (IS_ITEMP (IC_LEFT (ic)) &&
2880       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2881     {
2882       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2883       iCode *sic;
2884
2885       if (!dic)
2886         goto right;
2887
2888       debugAopGet ("removing left:", IC_LEFT (ic));
2889
2890       /* found it we need to remove it from the
2891          block */
2892       for (sic = dic; sic != ic; sic = sic->next)
2893         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2894
2895       IC_LEFT (ic)->operand.symOperand =
2896         IC_RIGHT (dic)->operand.symOperand;
2897       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2898       remiCodeFromeBBlock (ebp, dic);
2899       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2900       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2901       change++;
2902     }
2903
2904   /* do the same for the right operand */
2905 right:
2906   if (!change &&
2907       IS_ITEMP (IC_RIGHT (ic)) &&
2908       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2909     {
2910       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2911       iCode *sic;
2912
2913       if (!dic)
2914         return change;
2915
2916       /* if this is a subtraction & the result
2917          is a true symbol in far space then don't pack */
2918       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2919         {
2920           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2921           if (IN_FARSPACE (SPEC_OCLS (etype)))
2922             return change;
2923         }
2924
2925       debugAopGet ("removing right:", IC_RIGHT (ic));
2926
2927       /* found it we need to remove it from the
2928          block */
2929       for (sic = dic; sic != ic; sic = sic->next)
2930         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2931
2932       IC_RIGHT (ic)->operand.symOperand =
2933         IC_RIGHT (dic)->operand.symOperand;
2934       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2935
2936       remiCodeFromeBBlock (ebp, dic);
2937       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2938       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2939       change++;
2940     }
2941
2942   return change;
2943 }
2944
2945 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2946
2947
2948 /*-----------------------------------------------------------------*/
2949 /* packRegsForOneuse : - will reduce some registers for single Use */
2950 /*-----------------------------------------------------------------*/
2951 static iCode *
2952 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2953 {
2954   bitVect *uses;
2955   iCode *dic, *sic;
2956
2957   debugLog ("%s\n", __FUNCTION__);
2958   /* if returning a literal then do nothing */
2959   if (!IS_SYMOP (op))
2960     return NULL;
2961
2962   /* only upto 2 bytes since we cannot predict
2963      the usage of b, & acc */
2964   if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2965       ic->op != RETURN &&
2966       ic->op != SEND)
2967     return NULL;
2968
2969   /* this routine will mark the a symbol as used in one 
2970      instruction use only && if the definition is local 
2971      (ie. within the basic block) && has only one definition &&
2972      that definition is either a return value from a 
2973      function or does not contain any variables in
2974      far space */
2975   uses = bitVectCopy (OP_USES (op));
2976   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2977   if (!bitVectIsZero (uses))    /* has other uses */
2978     return NULL;
2979
2980   /* if it has only one defintion */
2981   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2982     return NULL;                /* has more than one definition */
2983
2984   /* get that definition */
2985   if (!(dic =
2986         hTabItemWithKey (iCodehTab,
2987                          bitVectFirstBit (OP_DEFS (op)))))
2988     return NULL;
2989
2990   /* found the definition now check if it is local */
2991   if (dic->seq < ebp->fSeq ||
2992       dic->seq > ebp->lSeq)
2993     return NULL;                /* non-local */
2994
2995   /* now check if it is the return from
2996      a function call */
2997   if (dic->op == CALL || dic->op == PCALL)
2998     {
2999       if (ic->op != SEND && ic->op != RETURN &&
3000           !POINTER_SET(ic) && !POINTER_GET(ic))
3001         {
3002           OP_SYMBOL (op)->ruonly = 1;
3003           return dic;
3004         }
3005       dic = dic->next;
3006     }
3007
3008
3009   /* otherwise check that the definition does
3010      not contain any symbols in far space */
3011   if (isOperandInFarSpace (IC_LEFT (dic)) ||
3012       isOperandInFarSpace (IC_RIGHT (dic)) ||
3013       IS_OP_RUONLY (IC_LEFT (ic)) ||
3014       IS_OP_RUONLY (IC_RIGHT (ic)))
3015     {
3016       return NULL;
3017     }
3018
3019   /* if pointer set then make sure the pointer
3020      is one byte */
3021   if (POINTER_SET (dic) &&
3022       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3023     return NULL;
3024
3025   if (POINTER_GET (dic) &&
3026       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3027     return NULL;
3028
3029   sic = dic;
3030
3031   /* also make sure the intervenening instructions
3032      don't have any thing in far space */
3033   for (dic = dic->next; dic && dic != ic; dic = dic->next)
3034     {
3035
3036       /* if there is an intervening function call then no */
3037       if (dic->op == CALL || dic->op == PCALL)
3038         return NULL;
3039       /* if pointer set then make sure the pointer
3040          is one byte */
3041       if (POINTER_SET (dic) &&
3042           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3043         return NULL;
3044
3045       if (POINTER_GET (dic) &&
3046           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3047         return NULL;
3048
3049       /* if address of & the result is remat then okay */
3050       if (dic->op == ADDRESS_OF &&
3051           OP_SYMBOL (IC_RESULT (dic))->remat)
3052         continue;
3053
3054       /* if operand has size of three or more & this
3055          operation is a '*','/' or '%' then 'b' may
3056          cause a problem */
3057       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3058           getSize (operandType (op)) >= 3)
3059         return NULL;
3060
3061       /* if left or right or result is in far space */
3062       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3063           isOperandInFarSpace (IC_RIGHT (dic)) ||
3064           isOperandInFarSpace (IC_RESULT (dic)) ||
3065           IS_OP_RUONLY (IC_LEFT (dic)) ||
3066           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3067           IS_OP_RUONLY (IC_RESULT (dic)))
3068         {
3069           return NULL;
3070         }
3071     }
3072
3073   OP_SYMBOL (op)->ruonly = 1;
3074   return sic;
3075
3076 }
3077
3078 /*-----------------------------------------------------------------*/
3079 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3080 /*-----------------------------------------------------------------*/
3081 static bool
3082 isBitwiseOptimizable (iCode * ic)
3083 {
3084   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3085   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3086
3087   debugLog ("%s\n", __FUNCTION__);
3088   /* bitwise operations are considered optimizable
3089      under the following conditions (Jean-Louis VERN) 
3090
3091      x & lit
3092      bit & bit
3093      bit & x
3094      bit ^ bit
3095      bit ^ x
3096      x   ^ lit
3097      x   | lit
3098      bit | bit
3099      bit | x
3100    */
3101   if (IS_LITERAL (rtype) ||
3102       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3103     return TRUE;
3104   else
3105     return FALSE;
3106 }
3107
3108 /*-----------------------------------------------------------------*/
3109 /* packRegsForAccUse - pack registers for acc use                  */
3110 /*-----------------------------------------------------------------*/
3111 static void
3112 packRegsForAccUse (iCode * ic)
3113 {
3114   iCode *uic;
3115
3116   debugLog ("%s\n", __FUNCTION__);
3117
3118   /* if this is an aggregate, e.g. a one byte char array */
3119   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3120     return;
3121   }
3122   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3123
3124   /* if + or - then it has to be one byte result */
3125   if ((ic->op == '+' || ic->op == '-')
3126       && getSize (operandType (IC_RESULT (ic))) > 1)
3127     return;
3128
3129   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3130   /* if shift operation make sure right side is not a literal */
3131   if (ic->op == RIGHT_OP &&
3132       (isOperandLiteral (IC_RIGHT (ic)) ||
3133        getSize (operandType (IC_RESULT (ic))) > 1))
3134     return;
3135
3136   if (ic->op == LEFT_OP &&
3137       (isOperandLiteral (IC_RIGHT (ic)) ||
3138        getSize (operandType (IC_RESULT (ic))) > 1))
3139     return;
3140
3141   if (IS_BITWISE_OP (ic) &&
3142       getSize (operandType (IC_RESULT (ic))) > 1)
3143     return;
3144
3145
3146   /* has only one definition */
3147   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3148     return;
3149
3150   /* has only one use */
3151   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3152     return;
3153
3154   /* and the usage immediately follows this iCode */
3155   if (!(uic = hTabItemWithKey (iCodehTab,
3156                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3157     return;
3158
3159   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3160   if (ic->next != uic)
3161     return;
3162
3163   /* if it is a conditional branch then we definitely can */
3164   if (uic->op == IFX)
3165     goto accuse;
3166
3167   if (uic->op == JUMPTABLE)
3168     return;
3169
3170   /* if the usage is not is an assignment
3171      or an arithmetic / bitwise / shift operation then not */
3172   if (POINTER_SET (uic) &&
3173       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3174     return;
3175
3176   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3177   if (uic->op != '=' &&
3178       !IS_ARITHMETIC_OP (uic) &&
3179       !IS_BITWISE_OP (uic) &&
3180       uic->op != LEFT_OP &&
3181       uic->op != RIGHT_OP)
3182     return;
3183
3184   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3185   /* if used in ^ operation then make sure right is not a 
3186      literl */
3187   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3188     return;
3189
3190   /* if shift operation make sure right side is not a literal */
3191   if (uic->op == RIGHT_OP &&
3192       (isOperandLiteral (IC_RIGHT (uic)) ||
3193        getSize (operandType (IC_RESULT (uic))) > 1))
3194     return;
3195
3196   if (uic->op == LEFT_OP &&
3197       (isOperandLiteral (IC_RIGHT (uic)) ||
3198        getSize (operandType (IC_RESULT (uic))) > 1))
3199     return;
3200
3201   /* make sure that the result of this icode is not on the
3202      stack, since acc is used to compute stack offset */
3203   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3204       OP_SYMBOL (IC_RESULT (uic))->onStack)
3205     return;
3206
3207   /* if either one of them in far space then we cannot */
3208   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3209        isOperandInFarSpace (IC_LEFT (uic))) ||
3210       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3211        isOperandInFarSpace (IC_RIGHT (uic))))
3212     return;
3213
3214   /* if the usage has only one operand then we can */
3215   if (IC_LEFT (uic) == NULL ||
3216       IC_RIGHT (uic) == NULL)
3217     goto accuse;
3218
3219   /* make sure this is on the left side if not
3220      a '+' since '+' is commutative */
3221   if (ic->op != '+' &&
3222       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3223     return;
3224
3225   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3226   /* if one of them is a literal then we can */
3227   if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3228         (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3229        (getSize (operandType (IC_RESULT (uic))) <= 1))
3230     {
3231       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3232       return;
3233     }
3234
3235   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3236   /* if the other one is not on stack then we can */
3237   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3238       (IS_ITEMP (IC_RIGHT (uic)) ||
3239        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3240         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3241     goto accuse;
3242
3243   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3244       (IS_ITEMP (IC_LEFT (uic)) ||
3245        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3246         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3247     goto accuse;
3248
3249   return;
3250
3251 accuse:
3252   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3253   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3254
3255
3256 }
3257
3258 /*-----------------------------------------------------------------*/
3259 /* packForPush - hueristics to reduce iCode for pushing            */
3260 /*-----------------------------------------------------------------*/
3261 static void
3262 packForReceive (iCode * ic, eBBlock * ebp)
3263 {
3264   iCode *dic;
3265
3266   debugLog ("%s\n", __FUNCTION__);
3267   debugAopGet ("  result:", IC_RESULT (ic));
3268   debugAopGet ("  left:", IC_LEFT (ic));
3269   debugAopGet ("  right:", IC_RIGHT (ic));
3270
3271   if (!ic->next)
3272     return;
3273
3274   for (dic = ic->next; dic; dic = dic->next)
3275     {
3276
3277
3278
3279       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3280         debugLog ("    used on left\n");
3281       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3282         debugLog ("    used on right\n");
3283       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3284         debugLog ("    used on result\n");
3285
3286       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3287           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3288         return;
3289
3290     }
3291
3292   debugLog ("  hey we can remove this unnecessary assign\n");
3293 }
3294 /*-----------------------------------------------------------------*/
3295 /* packForPush - hueristics to reduce iCode for pushing            */
3296 /*-----------------------------------------------------------------*/
3297 static void
3298 packForPush (iCode * ic, eBBlock * ebp)
3299 {
3300   iCode *dic;
3301
3302   debugLog ("%s\n", __FUNCTION__);
3303   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3304     return;
3305
3306   /* must have only definition & one usage */
3307   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3308       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3309     return;
3310
3311   /* find the definition */
3312   if (!(dic = hTabItemWithKey (iCodehTab,
3313                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3314     return;
3315
3316   if (dic->op != '=' || POINTER_SET (dic))
3317     return;
3318
3319   /* we now we know that it has one & only one def & use
3320      and the that the definition is an assignment */
3321   IC_LEFT (ic) = IC_RIGHT (dic);
3322
3323   remiCodeFromeBBlock (ebp, dic);
3324   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3325   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3326 }
3327
3328 void printSymType(char * str, sym_link *sl)
3329 {
3330   debugLog ("    %s Symbol type: ",str);
3331   printTypeChain( sl, debugF);
3332   debugLog ("\n");
3333
3334 }
3335
3336 /*-----------------------------------------------------------------*/
3337 /* packRegisters - does some transformations to reduce register    */
3338 /*                   pressure                                      */
3339 /*-----------------------------------------------------------------*/
3340 static void
3341 packRegisters (eBBlock * ebp)
3342 {
3343   iCode *ic;
3344   int change = 0;
3345
3346   debugLog ("%s\n", __FUNCTION__);
3347
3348   while (1) {
3349
3350     change = 0;
3351
3352     /* look for assignments of the form */
3353     /* iTempNN = TRueSym (someoperation) SomeOperand */
3354     /*       ....                       */
3355     /* TrueSym := iTempNN:1             */
3356     for (ic = ebp->sch; ic; ic = ic->next)
3357       {
3358
3359         /* find assignment of the form TrueSym := iTempNN:1 */
3360         if (ic->op == '=' && !POINTER_SET (ic))
3361           change += packRegsForAssign (ic, ebp);
3362         /* debug stuff */
3363         if (ic->op == '=')
3364           {
3365             if (POINTER_SET (ic))
3366               debugLog ("pointer is set\n");
3367             debugAopGet ("  result:", IC_RESULT (ic));
3368             debugAopGet ("  left:", IC_LEFT (ic));
3369             debugAopGet ("  right:", IC_RIGHT (ic));
3370           }
3371
3372       }
3373
3374     if (!change)
3375       break;
3376   }
3377
3378   for (ic = ebp->sch; ic; ic = ic->next) {
3379
3380     if(IS_SYMOP ( IC_LEFT(ic))) {
3381       //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3382
3383       debugAopGet ("  left:", IC_LEFT (ic));
3384       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3385         debugLog ("    is a pointer");
3386
3387       printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3388     }
3389
3390     if(IS_SYMOP ( IC_RIGHT(ic))) {
3391       debugAopGet ("  right:", IC_RIGHT (ic));
3392       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3393     }
3394
3395     if(IS_SYMOP ( IC_RESULT(ic))) {
3396       debugAopGet ("  result:", IC_RESULT (ic));
3397       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3398     }
3399
3400     if (POINTER_SET (ic))
3401         debugLog ("  %d - Pointer set\n", __LINE__);
3402
3403
3404     /* if this is an itemp & result of a address of a true sym 
3405        then mark this as rematerialisable   */
3406     if (ic->op == ADDRESS_OF &&
3407         IS_ITEMP (IC_RESULT (ic)) &&
3408         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3409         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3410         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3411       {
3412
3413         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3414
3415         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3416         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3417         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3418
3419       }
3420
3421     /* if straight assignment then carry remat flag if
3422        this is the only definition */
3423     if (ic->op == '=' &&
3424         !POINTER_SET (ic) &&
3425         IS_SYMOP (IC_RIGHT (ic)) &&
3426         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3427         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3428       {
3429         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3430
3431         OP_SYMBOL (IC_RESULT (ic))->remat =
3432           OP_SYMBOL (IC_RIGHT (ic))->remat;
3433         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3434           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3435       }
3436
3437     /* if this is a +/- operation with a rematerizable 
3438        then mark this as rematerializable as well */
3439     if ((ic->op == '+' || ic->op == '-') &&
3440         (IS_SYMOP (IC_LEFT (ic)) &&
3441          IS_ITEMP (IC_RESULT (ic)) &&
3442          OP_SYMBOL (IC_LEFT (ic))->remat &&
3443          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3444          IS_OP_LITERAL (IC_RIGHT (ic))))
3445       {
3446         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3447         //int i = 
3448         operandLitValue (IC_RIGHT (ic));
3449         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3450         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3451         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3452       }
3453
3454     /* mark the pointer usages */
3455     if (POINTER_SET (ic))
3456       {
3457         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3458         debugLog ("  marking as a pointer (set) =>");
3459         debugAopGet ("  result:", IC_RESULT (ic));
3460       }
3461     if (POINTER_GET (ic))
3462       {
3463         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3464         debugLog ("  marking as a pointer (get) =>");
3465         debugAopGet ("  left:", IC_LEFT (ic));
3466       }
3467
3468     if (!SKIP_IC2 (ic))
3469       {
3470         /* if we are using a symbol on the stack
3471            then we should say pic14_ptrRegReq */
3472         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3473           pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3474                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3475         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3476           pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3477                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3478         else
3479           {
3480             if (IS_SYMOP (IC_LEFT (ic)))
3481               pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3482                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3483             if (IS_SYMOP (IC_RIGHT (ic)))
3484               pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3485                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3486             if (IS_SYMOP (IC_RESULT (ic)))
3487               pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3488                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3489           }
3490
3491         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3492
3493       }
3494
3495     /* if the condition of an if instruction
3496        is defined in the previous instruction then
3497        mark the itemp as a conditional */
3498     if ((IS_CONDITIONAL (ic) ||
3499          ((ic->op == BITWISEAND ||
3500            ic->op == '|' ||
3501            ic->op == '^') &&
3502           isBitwiseOptimizable (ic))) &&
3503         ic->next && ic->next->op == IFX &&
3504         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3505         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3506       {
3507
3508         debugLog ("  %d\n", __LINE__);
3509         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3510         continue;
3511       }
3512
3513     /* reduce for support function calls */
3514     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3515       packRegsForSupport (ic, ebp);
3516
3517     /* if a parameter is passed, it's in W, so we may not
3518        need to place a copy in a register */
3519     if (ic->op == RECEIVE)
3520       packForReceive (ic, ebp);
3521
3522     /* some cases the redundant moves can
3523        can be eliminated for return statements */
3524     if ((ic->op == RETURN || ic->op == SEND) &&
3525         !isOperandInFarSpace (IC_LEFT (ic)) &&
3526         !options.model)
3527       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3528
3529     /* if pointer set & left has a size more than
3530        one and right is not in far space */
3531     if (POINTER_SET (ic) &&
3532         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3533         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3534         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3535         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3536
3537       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3538
3539     /* if pointer get */
3540     if (POINTER_GET (ic) &&
3541         !isOperandInFarSpace (IC_RESULT (ic)) &&
3542         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3543         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3544         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3545
3546       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3547
3548
3549     /* if this is cast for intergral promotion then
3550        check if only use of  the definition of the 
3551        operand being casted/ if yes then replace
3552        the result of that arithmetic operation with 
3553        this result and get rid of the cast */
3554     if (ic->op == CAST) {
3555         
3556       sym_link *fromType = operandType (IC_RIGHT (ic));
3557       sym_link *toType = operandType (IC_LEFT (ic));
3558
3559       debugLog ("  %d - casting\n", __LINE__);
3560
3561       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3562           getSize (fromType) != getSize (toType)) {
3563             
3564
3565         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3566         if (dic) {
3567                 
3568           if (IS_ARITHMETIC_OP (dic)) {
3569                     
3570             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3571             IC_RESULT (dic) = IC_RESULT (ic);
3572             remiCodeFromeBBlock (ebp, ic);
3573             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3574             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3575             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3576             ic = ic->prev;
3577           }  else
3578                 
3579             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3580         }
3581       } else {
3582
3583         /* if the type from and type to are the same
3584            then if this is the only use then packit */
3585         if (compareType (operandType (IC_RIGHT (ic)),
3586                          operandType (IC_LEFT (ic))) == 1) {
3587                 
3588           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3589           if (dic) {
3590                     
3591             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3592             IC_RESULT (dic) = IC_RESULT (ic);
3593             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3594             remiCodeFromeBBlock (ebp, ic);
3595             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3596             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3597             ic = ic->prev;
3598           }
3599         }
3600       }
3601     }
3602
3603     /* pack for PUSH 
3604        iTempNN := (some variable in farspace) V1
3605        push iTempNN ;
3606        -------------
3607        push V1
3608     */
3609     if (ic->op == IPUSH)
3610       {
3611         packForPush (ic, ebp);
3612       }
3613
3614
3615     /* pack registers for accumulator use, when the
3616        result of an arithmetic or bit wise operation
3617        has only one use, that use is immediately following
3618        the defintion and the using iCode has only one
3619        operand or has two operands but one is literal &
3620        the result of that operation is not on stack then
3621        we can leave the result of this operation in acc:b
3622        combination */
3623     if ((IS_ARITHMETIC_OP (ic)
3624
3625          || IS_BITWISE_OP (ic)
3626
3627          || ic->op == LEFT_OP || ic->op == RIGHT_OP
3628
3629          ) &&
3630         IS_ITEMP (IC_RESULT (ic)) &&
3631         getSize (operandType (IC_RESULT (ic))) <= 2)
3632
3633       packRegsForAccUse (ic);
3634
3635   }
3636 }
3637
3638 static void
3639 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3640 {
3641   int i;
3642
3643   if (!debug || !debugF)
3644     return;
3645
3646   for (i = 0; i < count; i++)
3647     {
3648       fprintf (debugF, "\n----------------------------------------------------------------\n");
3649       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3650                ebbs[i]->entryLabel->name,
3651                ebbs[i]->depth,
3652                ebbs[i]->noPath,
3653                ebbs[i]->isLastInLoop);
3654       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3655                ebbs[i]->dfnum,
3656                ebbs[i]->bbnum,
3657                ebbs[i]->fSeq,
3658                ebbs[i]->lSeq);
3659       fprintf (debugF, "visited %d : hasFcall = %d\n",
3660                ebbs[i]->visited,
3661                ebbs[i]->hasFcall);
3662
3663       fprintf (debugF, "\ndefines bitVector :");
3664       bitVectDebugOn (ebbs[i]->defSet, debugF);
3665       fprintf (debugF, "\nlocal defines bitVector :");
3666       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3667       fprintf (debugF, "\npointers Set bitvector :");
3668       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3669       fprintf (debugF, "\nin pointers Set bitvector :");
3670       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3671       fprintf (debugF, "\ninDefs Set bitvector :");
3672       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3673       fprintf (debugF, "\noutDefs Set bitvector :");
3674       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3675       fprintf (debugF, "\nusesDefs Set bitvector :");
3676       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3677       fprintf (debugF, "\n----------------------------------------------------------------\n");
3678       printiCChain (ebbs[i]->sch, debugF);
3679     }
3680 }
3681 /*-----------------------------------------------------------------*/
3682 /* assignRegisters - assigns registers to each live range as need  */
3683 /*-----------------------------------------------------------------*/
3684 void
3685 pic14_assignRegisters (eBBlock ** ebbs, int count)
3686 {
3687   iCode *ic;
3688   int i;
3689
3690   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3691   debugLog ("\nebbs before optimizing:\n");
3692   dumpEbbsToDebug (ebbs, count);
3693
3694   setToNull ((void *) &_G.funcrUsed);
3695   pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3696
3697
3698   /* change assignments this will remove some
3699      live ranges reducing some register pressure */
3700   for (i = 0; i < count; i++)
3701     packRegisters (ebbs[i]);
3702
3703   {
3704     regs *reg;
3705     int hkey;
3706     int i=0;
3707
3708     debugLog("dir registers allocated so far:\n");
3709     reg = hTabFirstItem(dynDirectRegNames, &hkey);
3710
3711     while(reg) {
3712       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3713       reg = hTabNextItem(dynDirectRegNames, &hkey);
3714     }
3715
3716   }
3717
3718   if (options.dump_pack)
3719     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3720
3721   /* first determine for each live range the number of 
3722      registers & the type of registers required for each */
3723   regTypeNum ();
3724
3725   /* and serially allocate registers */
3726   serialRegAssign (ebbs, count);
3727
3728   /* if stack was extended then tell the user */
3729   if (_G.stackExtend)
3730     {
3731 /*      werror(W_TOOMANY_SPILS,"stack", */
3732 /*             _G.stackExtend,currFunc->name,""); */
3733       _G.stackExtend = 0;
3734     }
3735
3736   if (_G.dataExtend)
3737     {
3738 /*      werror(W_TOOMANY_SPILS,"data space", */
3739 /*             _G.dataExtend,currFunc->name,""); */
3740       _G.dataExtend = 0;
3741     }
3742
3743   /* after that create the register mask
3744      for each of the instruction */
3745   createRegMask (ebbs, count);
3746
3747   /* redo that offsets for stacked automatic variables */
3748   redoStackOffsets ();
3749
3750   if (options.dump_rassgn)
3751     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3752
3753   /* now get back the chain */
3754   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3755
3756   debugLog ("ebbs after optimizing:\n");
3757   dumpEbbsToDebug (ebbs, count);
3758
3759
3760   genpic14Code (ic);
3761
3762   /* free up any _G.stackSpil locations allocated */
3763   applyToSet (_G.stackSpil, deallocStackSpil);
3764   _G.slocNum = 0;
3765   setToNull ((void **) &_G.stackSpil);
3766   setToNull ((void **) &_G.spiltSet);
3767   /* mark all registers as free */
3768   pic14_freeAllRegs ();
3769
3770   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3771   debugLogClose ();
3772   return;
3773 }