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