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