Added support for multiplication. Fixed peep hole bugs (and more functionality to...
[fw/sdcc] / src / pic / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. (8051) specific
4
5                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6                 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7
8    This program is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the
10    Free Software Foundation; either version 2, or (at your option) any
11    later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21    
22    In other words, you are welcome to use, share and improve this program.
23    You are forbidden to forbid anyone else to use, share and improve
24    what you give them.   Help stamp out software-hoarding!  
25 -------------------------------------------------------------------------*/
26
27 #include "common.h"
28 #include "ralloc.h"
29 #include "pcode.h"
30 #include "gen.h"
31
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define STRCASECMP stricmp
34 #else
35 #define STRCASECMP strcasecmp
36 #endif
37
38 /*-----------------------------------------------------------------*/
39 /* At this point we start getting processor specific although      */
40 /* some routines are non-processor specific & can be reused when   */
41 /* targetting other processors. The decision for this will have    */
42 /* to be made on a routine by routine basis                        */
43 /* routines used to pack registers are most definitely not reusable */
44 /* since the pack the registers depending strictly on the MCU      */
45 /*-----------------------------------------------------------------*/
46
47 extern void genpic14Code (iCode *);
48
49 /* Global data */
50 static struct
51   {
52     bitVect *spiltSet;
53     set *stackSpil;
54     bitVect *regAssigned;
55     short blockSpil;
56     int slocNum;
57     bitVect *funcrUsed;         /* registers used in a function */
58     int stackExtend;
59     int dataExtend;
60   }
61 _G;
62
63 /* Shared with gen.c */
64 int pic14_ptrRegReq;            /* one byte pointer register required */
65
66
67 static set *dynAllocRegs=NULL;
68 static set *dynStackRegs=NULL;
69 static set *dynProcessorRegs=NULL;
70 static set *dynDirectRegs=NULL;
71 static set *dynDirectBitRegs=NULL;
72 static set *dynInternalRegs=NULL;
73
74 static hTab  *dynDirectRegNames= NULL;
75
76 static int dynrIdx=0x20;
77 static int rDirectIdx=0;
78
79 int pic14_nRegs = 128;   // = sizeof (regspic14) / sizeof (regs);
80
81 int Gstack_base_addr=0; /* The starting address of registers that
82                          * are used to pass and return parameters */
83
84
85
86
87 static void spillThis (symbol *);
88 static int debug = 1;
89 static FILE *debugF = NULL;
90 /*-----------------------------------------------------------------*/
91 /* debugLog - open a file for debugging information                */
92 /*-----------------------------------------------------------------*/
93 //static void debugLog(char *inst,char *fmt, ...)
94 static void
95 debugLog (char *fmt,...)
96 {
97   static int append = 0;        // First time through, open the file without append.
98
99   char buffer[256];
100   //char *bufferP=buffer;
101   va_list ap;
102
103   if (!debug || !srcFileName)
104     return;
105
106
107   if (!debugF)
108     {
109       /* create the file name */
110       strcpy (buffer, srcFileName);
111       strcat (buffer, ".d");
112
113       if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
114         {
115           werror (E_FILE_OPEN_ERR, buffer);
116           exit (1);
117         }
118       append = 1;               // Next time debubLog is called, we'll append the debug info
119
120     }
121
122   va_start (ap, fmt);
123
124   vsprintf (buffer, fmt, ap);
125
126   fprintf (debugF, "%s", buffer);
127 /*
128    while (isspace(*bufferP)) bufferP++;
129
130    if (bufferP && *bufferP) 
131    lineCurr = (lineCurr ?
132    connectLine(lineCurr,newLineNode(lb)) :
133    (lineHead = newLineNode(lb)));
134    lineCurr->isInline = _G.inLine;
135    lineCurr->isDebug  = _G.debugLine;
136  */
137   va_end (ap);
138
139 }
140
141 static void
142 debugNewLine (void)
143 {
144   if (debugF)
145     fputc ('\n', debugF);
146 }
147 /*-----------------------------------------------------------------*/
148 /* debugLogClose - closes the debug log file (if opened)           */
149 /*-----------------------------------------------------------------*/
150 static void
151 debugLogClose (void)
152 {
153   if (debugF)
154     {
155       fclose (debugF);
156       debugF = NULL;
157     }
158 }
159 #define AOP(op) op->aop
160
161 static char *
162 debugAopGet (char *str, operand * op)
163 {
164   if (str)
165     debugLog (str);
166
167   printOperand (op, debugF);
168   debugNewLine ();
169
170   return NULL;
171
172 }
173
174 static char *
175 decodeOp (unsigned int op)
176 {
177
178   if (op < 128 && op > ' ')
179     {
180       buffer[0] = (op & 0xff);
181       buffer[1] = 0;
182       return buffer;
183     }
184
185   switch (op)
186     {
187     case IDENTIFIER:
188       return "IDENTIFIER";
189     case TYPE_NAME:
190       return "TYPE_NAME";
191     case CONSTANT:
192       return "CONSTANT";
193     case STRING_LITERAL:
194       return "STRING_LITERAL";
195     case SIZEOF:
196       return "SIZEOF";
197     case PTR_OP:
198       return "PTR_OP";
199     case INC_OP:
200       return "INC_OP";
201     case DEC_OP:
202       return "DEC_OP";
203     case LEFT_OP:
204       return "LEFT_OP";
205     case RIGHT_OP:
206       return "RIGHT_OP";
207     case LE_OP:
208       return "LE_OP";
209     case GE_OP:
210       return "GE_OP";
211     case EQ_OP:
212       return "EQ_OP";
213     case NE_OP:
214       return "NE_OP";
215     case AND_OP:
216       return "AND_OP";
217     case OR_OP:
218       return "OR_OP";
219     case MUL_ASSIGN:
220       return "MUL_ASSIGN";
221     case DIV_ASSIGN:
222       return "DIV_ASSIGN";
223     case MOD_ASSIGN:
224       return "MOD_ASSIGN";
225     case ADD_ASSIGN:
226       return "ADD_ASSIGN";
227     case SUB_ASSIGN:
228       return "SUB_ASSIGN";
229     case LEFT_ASSIGN:
230       return "LEFT_ASSIGN";
231     case RIGHT_ASSIGN:
232       return "RIGHT_ASSIGN";
233     case AND_ASSIGN:
234       return "AND_ASSIGN";
235     case XOR_ASSIGN:
236       return "XOR_ASSIGN";
237     case OR_ASSIGN:
238       return "OR_ASSIGN";
239     case TYPEDEF:
240       return "TYPEDEF";
241     case EXTERN:
242       return "EXTERN";
243     case STATIC:
244       return "STATIC";
245     case AUTO:
246       return "AUTO";
247     case REGISTER:
248       return "REGISTER";
249     case CODE:
250       return "CODE";
251     case EEPROM:
252       return "EEPROM";
253     case INTERRUPT:
254       return "INTERRUPT";
255     case SFR:
256       return "SFR";
257     case AT:
258       return "AT";
259     case SBIT:
260       return "SBIT";
261     case REENTRANT:
262       return "REENTRANT";
263     case USING:
264       return "USING";
265     case XDATA:
266       return "XDATA";
267     case DATA:
268       return "DATA";
269     case IDATA:
270       return "IDATA";
271     case PDATA:
272       return "PDATA";
273     case VAR_ARGS:
274       return "VAR_ARGS";
275     case CRITICAL:
276       return "CRITICAL";
277     case NONBANKED:
278       return "NONBANKED";
279     case BANKED:
280       return "BANKED";
281     case CHAR:
282       return "CHAR";
283     case SHORT:
284       return "SHORT";
285     case INT:
286       return "INT";
287     case LONG:
288       return "LONG";
289     case SIGNED:
290       return "SIGNED";
291     case UNSIGNED:
292       return "UNSIGNED";
293     case FLOAT:
294       return "FLOAT";
295     case DOUBLE:
296       return "DOUBLE";
297     case CONST:
298       return "CONST";
299     case VOLATILE:
300       return "VOLATILE";
301     case VOID:
302       return "VOID";
303     case BIT:
304       return "BIT";
305     case STRUCT:
306       return "STRUCT";
307     case UNION:
308       return "UNION";
309     case ENUM:
310       return "ENUM";
311     case ELIPSIS:
312       return "ELIPSIS";
313     case RANGE:
314       return "RANGE";
315     case FAR:
316       return "FAR";
317     case CASE:
318       return "CASE";
319     case DEFAULT:
320       return "DEFAULT";
321     case IF:
322       return "IF";
323     case ELSE:
324       return "ELSE";
325     case SWITCH:
326       return "SWITCH";
327     case WHILE:
328       return "WHILE";
329     case DO:
330       return "DO";
331     case FOR:
332       return "FOR";
333     case GOTO:
334       return "GOTO";
335     case CONTINUE:
336       return "CONTINUE";
337     case BREAK:
338       return "BREAK";
339     case RETURN:
340       return "RETURN";
341     case INLINEASM:
342       return "INLINEASM";
343     case IFX:
344       return "IFX";
345     case ADDRESS_OF:
346       return "ADDRESS_OF";
347     case GET_VALUE_AT_ADDRESS:
348       return "GET_VALUE_AT_ADDRESS";
349     case SPIL:
350       return "SPIL";
351     case UNSPIL:
352       return "UNSPIL";
353     case GETHBIT:
354       return "GETHBIT";
355     case BITWISEAND:
356       return "BITWISEAND";
357     case UNARYMINUS:
358       return "UNARYMINUS";
359     case IPUSH:
360       return "IPUSH";
361     case IPOP:
362       return "IPOP";
363     case PCALL:
364       return "PCALL";
365     case ENDFUNCTION:
366       return "ENDFUNCTION";
367     case JUMPTABLE:
368       return "JUMPTABLE";
369     case RRC:
370       return "RRC";
371     case RLC:
372       return "RLC";
373     case CAST:
374       return "CAST";
375     case CALL:
376       return "CALL";
377     case PARAM:
378       return "PARAM  ";
379     case NULLOP:
380       return "NULLOP";
381     case BLOCK:
382       return "BLOCK";
383     case LABEL:
384       return "LABEL";
385     case RECEIVE:
386       return "RECEIVE";
387     case SEND:
388       return "SEND";
389     }
390   sprintf (buffer, "unkown op %d %c", op, op & 0xff);
391   return buffer;
392 }
393 /*-----------------------------------------------------------------*/
394 /*-----------------------------------------------------------------*/
395 static char *
396 debugLogRegType (short type)
397 {
398
399   switch (type)
400     {
401     case REG_GPR:
402       return "REG_GPR";
403     case REG_PTR:
404       return "REG_PTR";
405     case REG_CND:
406       return "REG_CND";
407     }
408
409   sprintf (buffer, "unkown reg type %d", type);
410   return buffer;
411 }
412
413 /*-----------------------------------------------------------------*/
414 /* newReg - allocate and init memory for a new register            */
415 /*-----------------------------------------------------------------*/
416 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
417 {
418
419   regs *dReg;
420
421   dReg = Safe_calloc(1,sizeof(regs));
422   dReg->type = type;
423   dReg->pc_type = pc_type;
424   dReg->rIdx = rIdx;
425   if(name) 
426     dReg->name = Safe_strdup(name);
427   else {
428     sprintf(buffer,"r0x%02X", dReg->rIdx);
429     if(type == REG_STK)
430       *buffer = 's';
431     dReg->name = Safe_strdup(buffer);
432   }
433   //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
434   dReg->isFree = 0;
435   dReg->wasUsed = 1;
436   dReg->isFixed = 0;
437   dReg->isMapped = 0;
438   dReg->isEmitted = 0;
439   dReg->address = 0;
440   dReg->size = size;
441   dReg->alias = alias;
442   dReg->reg_alias = NULL;
443
444   return dReg;
445 }
446
447 /*-----------------------------------------------------------------*/
448 /* regWithIdx - Search through a set of registers that matches idx */
449 /*-----------------------------------------------------------------*/
450 static regs *
451 regWithIdx (set *dRegs, int idx, int fixed)
452 {
453   regs *dReg;
454
455   for (dReg = setFirstItem(dRegs) ; dReg ; 
456        dReg = setNextItem(dRegs)) {
457
458     if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
459       return dReg;
460     }
461   }
462
463   return NULL;
464 }
465
466 /*-----------------------------------------------------------------*/
467 /* regFindFree - Search for a free register in a set of registers  */
468 /*-----------------------------------------------------------------*/
469 static regs *
470 regFindFree (set *dRegs)
471 {
472   regs *dReg;
473
474   for (dReg = setFirstItem(dRegs) ; dReg ; 
475        dReg = setNextItem(dRegs)) {
476
477     if(dReg->isFree)
478       return dReg;
479   }
480
481   return NULL;
482 }
483 /*-----------------------------------------------------------------*/
484 /* initStack - allocate registers for a psuedo stack               */
485 /*-----------------------------------------------------------------*/
486 void initStack(int base_address, int size)
487 {
488
489   int i;
490
491   Gstack_base_addr = base_address;
492   for(i = 0; i<size; i++)
493     addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
494 }
495
496 regs *
497 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
498 {
499   return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
500 }
501
502 regs *
503 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
504 {
505   regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
506
507   if(reg) {
508     reg->wasUsed = 0;
509     return addSet(&dynInternalRegs,reg);
510   }
511
512   return NULL;
513 }
514 /*-----------------------------------------------------------------*/
515 /* allocReg - allocates register of given type                     */
516 /*-----------------------------------------------------------------*/
517 static regs *
518 allocReg (short type)
519 {
520
521   debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
522
523
524   return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
525
526 }
527
528 /*-----------------------------------------------------------------*/
529 /*-----------------------------------------------------------------*/
530 static int regname2key(char const *name)
531 {
532   int key = 0;
533
534   if(!name)
535     return 0;
536
537   while(*name) {
538
539     key += (*name++) + 1;
540
541   }
542
543   return ( (key + (key >> 4) + (key>>8)) & 0x3f);
544
545 }
546
547 /*-----------------------------------------------------------------*/
548 /* dirregWithName - search for register by name                    */
549 /*-----------------------------------------------------------------*/
550 regs *
551 dirregWithName (char *name)
552 {
553   int hkey;
554   regs *reg;
555
556   if(!name)
557     return NULL;
558
559   /* hash the name to get a key */
560
561   hkey = regname2key(name);
562
563   reg = hTabFirstItemWK(dynDirectRegNames, hkey);
564
565   while(reg) {
566
567     if(STRCASECMP(reg->name, name) == 0) {
568       return(reg);
569     }
570
571     reg = hTabNextItemWK (dynDirectRegNames);
572   
573   }
574
575   return NULL; // name wasn't found in the hash table
576 }
577
578 /*-----------------------------------------------------------------*/
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, int size)
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,size,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,1,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 symbol *
2239 rematStr (symbol * sym)
2240 {
2241   char *s = buffer;
2242   iCode *ic = sym->rematiCode;
2243   symbol *psym = NULL;
2244
2245   debugLog ("%s\n", __FUNCTION__);
2246
2247   printf ("%s\n", s);
2248
2249   /* if plus or minus print the right hand side */
2250
2251   if (ic->op == '+' || ic->op == '-') {
2252         
2253     iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2254
2255     sprintf (s, "(%s %c 0x%04x)",
2256              OP_SYMBOL (IC_LEFT (ric))->rname,
2257              ic->op,
2258              (int) operandLitValue (IC_RIGHT (ic)));
2259
2260
2261     fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2262
2263     psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2264     psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2265
2266     return psym;
2267   }
2268
2269   sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2270   psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2271
2272   printf ("%s\n", buffer);
2273   return psym;
2274 }
2275
2276 #if 0
2277 /*-----------------------------------------------------------------*/
2278 /* rematStr - returns the rematerialized string for a remat var    */
2279 /*-----------------------------------------------------------------*/
2280 static char *
2281 rematStr (symbol * sym)
2282 {
2283   char *s = buffer;
2284   iCode *ic = sym->rematiCode;
2285
2286   debugLog ("%s\n", __FUNCTION__);
2287   while (1)
2288     {
2289
2290       printf ("%s\n", s);
2291       /* if plus or minus print the right hand side */
2292 /*
2293    if (ic->op == '+' || ic->op == '-') {
2294    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2295    ic->op );
2296    s += strlen(s);
2297    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2298    continue ;
2299    }
2300  */
2301       if (ic->op == '+' || ic->op == '-')
2302         {
2303           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2304           sprintf (s, "(%s %c 0x%04x)",
2305                    OP_SYMBOL (IC_LEFT (ric))->rname,
2306                    ic->op,
2307                    (int) operandLitValue (IC_RIGHT (ic)));
2308
2309           //s += strlen(s);
2310           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2311           //continue ;
2312           fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2313           return buffer;
2314         }
2315
2316       /* we reached the end */
2317       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2318       break;
2319     }
2320
2321   printf ("%s\n", buffer);
2322   return buffer;
2323 }
2324 #endif
2325
2326 /*-----------------------------------------------------------------*/
2327 /* regTypeNum - computes the type & number of registers required   */
2328 /*-----------------------------------------------------------------*/
2329 static void
2330 regTypeNum ()
2331 {
2332   symbol *sym;
2333   int k;
2334   iCode *ic;
2335
2336   debugLog ("%s\n", __FUNCTION__);
2337   /* for each live range do */
2338   for (sym = hTabFirstItem (liveRanges, &k); sym;
2339        sym = hTabNextItem (liveRanges, &k)) {
2340
2341     debugLog ("  %d - %s\n", __LINE__, sym->rname);
2342
2343     /* if used zero times then no registers needed */
2344     if ((sym->liveTo - sym->liveFrom) == 0)
2345       continue;
2346
2347
2348     /* if the live range is a temporary */
2349     if (sym->isitmp) {
2350
2351       debugLog ("  %d - itemp register\n", __LINE__);
2352
2353       /* if the type is marked as a conditional */
2354       if (sym->regType == REG_CND)
2355         continue;
2356
2357       /* if used in return only then we don't 
2358          need registers */
2359       if (sym->ruonly || sym->accuse) {
2360         if (IS_AGGREGATE (sym->type) || sym->isptr)
2361           sym->type = aggrToPtr (sym->type, FALSE);
2362         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
2363
2364         continue;
2365       }
2366
2367       /* if the symbol has only one definition &
2368          that definition is a get_pointer and the
2369          pointer we are getting is rematerializable and
2370          in "data" space */
2371
2372       if (bitVectnBitsOn (sym->defs) == 1 &&
2373           (ic = hTabItemWithKey (iCodehTab,
2374                                  bitVectFirstBit (sym->defs))) &&
2375           POINTER_GET (ic) &&
2376           !sym->noSpilLoc &&
2377           !IS_BITVAR (sym->etype)) {
2378         
2379
2380         debugLog ("  %d - \n", __LINE__);
2381
2382         /* if remat in data space */
2383         if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2384             DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2385
2386           /* create a psuedo symbol & force a spil */
2387           //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2388           symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2389           psym->type = sym->type;
2390           psym->etype = sym->etype;
2391           strcpy (psym->rname, psym->name);
2392           sym->isspilt = 1;
2393           sym->usl.spillLoc = psym;
2394           continue;
2395         }
2396
2397         /* if in data space or idata space then try to
2398            allocate pointer register */
2399
2400       }
2401
2402       /* if not then we require registers */
2403       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2404                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2405                     getSize (sym->type));
2406
2407
2408     if(IS_PTR_CONST (sym->type)) {
2409       debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2410       sym->nRegs = 2;
2411     }
2412
2413       if (sym->nRegs > 4) {
2414         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2415         printTypeChain (sym->type, stderr);
2416         fprintf (stderr, "\n");
2417       }
2418
2419       /* determine the type of register required */
2420       if (sym->nRegs == 1 &&
2421           IS_PTR (sym->type) &&
2422           sym->uptr)
2423         sym->regType = REG_PTR;
2424       else
2425         sym->regType = REG_GPR;
2426
2427
2428       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2429
2430     }
2431     else
2432       /* for the first run we don't provide */
2433       /* registers for true symbols we will */
2434       /* see how things go                  */
2435       sym->nRegs = 0;
2436   }
2437
2438 }
2439 DEFSETFUNC (markRegFree)
2440 {
2441   ((regs *)item)->isFree = 1;
2442
2443   return 0;
2444 }
2445
2446 DEFSETFUNC (deallocReg)
2447 {
2448   ((regs *)item)->isFree = 1;
2449   ((regs *)item)->wasUsed = 0;
2450
2451   return 0;
2452 }
2453 /*-----------------------------------------------------------------*/
2454 /* freeAllRegs - mark all registers as free                        */
2455 /*-----------------------------------------------------------------*/
2456 void
2457 pic14_freeAllRegs ()
2458 {
2459   //  int i;
2460
2461   debugLog ("%s\n", __FUNCTION__);
2462
2463   applyToSet(dynAllocRegs,markRegFree);
2464   applyToSet(dynStackRegs,markRegFree);
2465
2466 /*
2467   for (i = 0; i < pic14_nRegs; i++)
2468     regspic14[i].isFree = 1;
2469 */
2470 }
2471
2472 /*-----------------------------------------------------------------*/
2473 /*-----------------------------------------------------------------*/
2474 void
2475 pic14_deallocateAllRegs ()
2476 {
2477   //  int i;
2478
2479   debugLog ("%s\n", __FUNCTION__);
2480
2481   applyToSet(dynAllocRegs,deallocReg);
2482
2483 /*
2484   for (i = 0; i < pic14_nRegs; i++) {
2485     if(regspic14[i].pc_type == PO_GPR_TEMP) {
2486       regspic14[i].isFree = 1;
2487       regspic14[i].wasUsed = 0;
2488     }
2489   }
2490 */
2491 }
2492
2493
2494 /*-----------------------------------------------------------------*/
2495 /* deallocStackSpil - this will set the stack pointer back         */
2496 /*-----------------------------------------------------------------*/
2497 static
2498 DEFSETFUNC (deallocStackSpil)
2499 {
2500   symbol *sym = item;
2501
2502   debugLog ("%s\n", __FUNCTION__);
2503   deallocLocal (sym);
2504   return 0;
2505 }
2506
2507 /*-----------------------------------------------------------------*/
2508 /* farSpacePackable - returns the packable icode for far variables */
2509 /*-----------------------------------------------------------------*/
2510 static iCode *
2511 farSpacePackable (iCode * ic)
2512 {
2513   iCode *dic;
2514
2515   debugLog ("%s\n", __FUNCTION__);
2516   /* go thru till we find a definition for the
2517      symbol on the right */
2518   for (dic = ic->prev; dic; dic = dic->prev)
2519     {
2520
2521       /* if the definition is a call then no */
2522       if ((dic->op == CALL || dic->op == PCALL) &&
2523           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2524         {
2525           return NULL;
2526         }
2527
2528       /* if shift by unknown amount then not */
2529       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2530           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2531         return NULL;
2532
2533       /* if pointer get and size > 1 */
2534       if (POINTER_GET (dic) &&
2535           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2536         return NULL;
2537
2538       if (POINTER_SET (dic) &&
2539           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2540         return NULL;
2541
2542       /* if any three is a true symbol in far space */
2543       if (IC_RESULT (dic) &&
2544           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2545           isOperandInFarSpace (IC_RESULT (dic)))
2546         return NULL;
2547
2548       if (IC_RIGHT (dic) &&
2549           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2550           isOperandInFarSpace (IC_RIGHT (dic)) &&
2551           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2552         return NULL;
2553
2554       if (IC_LEFT (dic) &&
2555           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2556           isOperandInFarSpace (IC_LEFT (dic)) &&
2557           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2558         return NULL;
2559
2560       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2561         {
2562           if ((dic->op == LEFT_OP ||
2563                dic->op == RIGHT_OP ||
2564                dic->op == '-') &&
2565               IS_OP_LITERAL (IC_RIGHT (dic)))
2566             return NULL;
2567           else
2568             return dic;
2569         }
2570     }
2571
2572   return NULL;
2573 }
2574
2575 /*-----------------------------------------------------------------*/
2576 /* packRegsForAssign - register reduction for assignment           */
2577 /*-----------------------------------------------------------------*/
2578 static int
2579 packRegsForAssign (iCode * ic, eBBlock * ebp)
2580 {
2581
2582   iCode *dic, *sic;
2583
2584   debugLog ("%s\n", __FUNCTION__);
2585
2586   debugAopGet ("  result:", IC_RESULT (ic));
2587   debugAopGet ("  left:", IC_LEFT (ic));
2588   debugAopGet ("  right:", IC_RIGHT (ic));
2589
2590   if (!IS_ITEMP (IC_RESULT (ic))) {
2591     allocDirReg(IC_RESULT (ic));
2592     debugLog ("  %d - result is not temp\n", __LINE__);
2593   }
2594 /*
2595   if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2596     debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2597     allocDirReg(IC_LEFT (ic));
2598   }
2599 */
2600
2601   if (!IS_ITEMP (IC_RIGHT (ic))) {
2602     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2603     allocDirReg(IC_RIGHT (ic));
2604     return 0;
2605   }
2606
2607   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2608       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2609     {
2610       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2611       return 0;
2612     }
2613
2614   /* if the true symbol is defined in far space or on stack
2615      then we should not since this will increase register pressure */
2616   if (isOperandInFarSpace (IC_RESULT (ic)))
2617     {
2618       if ((dic = farSpacePackable (ic)))
2619         goto pack;
2620       else
2621         return 0;
2622
2623     }
2624   /* find the definition of iTempNN scanning backwards if we find a 
2625      a use of the true symbol before we find the definition then 
2626      we cannot pack */
2627   for (dic = ic->prev; dic; dic = dic->prev)
2628     {
2629
2630       /* if there is a function call and this is
2631          a parameter & not my parameter then don't pack it */
2632       if ((dic->op == CALL || dic->op == PCALL) &&
2633           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2634            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2635         {
2636           debugLog ("  %d - \n", __LINE__);
2637           dic = NULL;
2638           break;
2639         }
2640
2641       if (SKIP_IC2 (dic))
2642         continue;
2643
2644       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2645           IS_OP_VOLATILE (IC_RESULT (dic)))
2646         {
2647           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2648           dic = NULL;
2649           break;
2650         }
2651
2652       if (IS_SYMOP (IC_RESULT (dic)) &&
2653           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2654         {
2655           /* A previous result was assigned to the same register - we'll our definition */
2656           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2657                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2658           if (POINTER_SET (dic))
2659             dic = NULL;
2660
2661           break;
2662         }
2663
2664       if (IS_SYMOP (IC_RIGHT (dic)) &&
2665           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2666            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2667         {
2668           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2669           dic = NULL;
2670           break;
2671         }
2672
2673       if (IS_SYMOP (IC_LEFT (dic)) &&
2674           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2675            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2676         {
2677           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2678           dic = NULL;
2679           break;
2680         }
2681
2682       if (POINTER_SET (dic) &&
2683           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2684         {
2685           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2686                     __LINE__);
2687           dic = NULL;
2688           break;
2689         }
2690     }
2691
2692   if (!dic)
2693     return 0;                   /* did not find */
2694
2695   /* if the result is on stack or iaccess then it must be
2696      the same atleast one of the operands */
2697   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2698       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2699     {
2700
2701       /* the operation has only one symbol
2702          operator then we can pack */
2703       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2704           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2705         goto pack;
2706
2707       if (!((IC_LEFT (dic) &&
2708              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2709             (IC_RIGHT (dic) &&
2710              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2711         return 0;
2712     }
2713 pack:
2714   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2715   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2716   /* found the definition */
2717   /* replace the result with the result of */
2718   /* this assignment and remove this assignment */
2719   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2720   IC_RESULT (dic) = IC_RESULT (ic);
2721
2722   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2723     {
2724       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2725     }
2726   /* delete from liverange table also 
2727      delete from all the points inbetween and the new
2728      one */
2729   for (sic = dic; sic != ic; sic = sic->next)
2730     {
2731       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2732       if (IS_ITEMP (IC_RESULT (dic)))
2733         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2734     }
2735
2736   remiCodeFromeBBlock (ebp, ic);
2737   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2738   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2739   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2740   return 1;
2741
2742
2743 }
2744
2745 /*-----------------------------------------------------------------*/
2746 /* findAssignToSym : scanning backwards looks for first assig found */
2747 /*-----------------------------------------------------------------*/
2748 static iCode *
2749 findAssignToSym (operand * op, iCode * ic)
2750 {
2751   iCode *dic;
2752
2753   debugLog ("%s\n", __FUNCTION__);
2754   for (dic = ic->prev; dic; dic = dic->prev)
2755     {
2756
2757       /* if definition by assignment */
2758       if (dic->op == '=' &&
2759           !POINTER_SET (dic) &&
2760           IC_RESULT (dic)->key == op->key
2761 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2762         )
2763         {
2764
2765           /* we are interested only if defined in far space */
2766           /* or in stack space in case of + & - */
2767
2768           /* if assigned to a non-symbol then return
2769              true */
2770           if (!IS_SYMOP (IC_RIGHT (dic)))
2771             break;
2772
2773           /* if the symbol is in far space then
2774              we should not */
2775           if (isOperandInFarSpace (IC_RIGHT (dic)))
2776             return NULL;
2777
2778           /* for + & - operations make sure that
2779              if it is on the stack it is the same
2780              as one of the three operands */
2781           if ((ic->op == '+' || ic->op == '-') &&
2782               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2783             {
2784
2785               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2786                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2787                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2788                 return NULL;
2789             }
2790
2791           break;
2792
2793         }
2794
2795       /* if we find an usage then we cannot delete it */
2796       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2797         return NULL;
2798
2799       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2800         return NULL;
2801
2802       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2803         return NULL;
2804     }
2805
2806   /* now make sure that the right side of dic
2807      is not defined between ic & dic */
2808   if (dic)
2809     {
2810       iCode *sic = dic->next;
2811
2812       for (; sic != ic; sic = sic->next)
2813         if (IC_RESULT (sic) &&
2814             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2815           return NULL;
2816     }
2817
2818   return dic;
2819
2820
2821 }
2822
2823 /*-----------------------------------------------------------------*/
2824 /* packRegsForSupport :- reduce some registers for support calls   */
2825 /*-----------------------------------------------------------------*/
2826 static int
2827 packRegsForSupport (iCode * ic, eBBlock * ebp)
2828 {
2829   int change = 0;
2830
2831   debugLog ("%s\n", __FUNCTION__);
2832   /* for the left & right operand :- look to see if the
2833      left was assigned a true symbol in far space in that
2834      case replace them */
2835   if (IS_ITEMP (IC_LEFT (ic)) &&
2836       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2837     {
2838       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2839       iCode *sic;
2840
2841       if (!dic)
2842         goto right;
2843
2844       debugAopGet ("removing left:", IC_LEFT (ic));
2845
2846       /* found it we need to remove it from the
2847          block */
2848       for (sic = dic; sic != ic; sic = sic->next)
2849         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2850
2851       IC_LEFT (ic)->operand.symOperand =
2852         IC_RIGHT (dic)->operand.symOperand;
2853       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2854       remiCodeFromeBBlock (ebp, dic);
2855       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2856       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2857       change++;
2858     }
2859
2860   /* do the same for the right operand */
2861 right:
2862   if (!change &&
2863       IS_ITEMP (IC_RIGHT (ic)) &&
2864       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2865     {
2866       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2867       iCode *sic;
2868
2869       if (!dic)
2870         return change;
2871
2872       /* if this is a subtraction & the result
2873          is a true symbol in far space then don't pack */
2874       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2875         {
2876           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2877           if (IN_FARSPACE (SPEC_OCLS (etype)))
2878             return change;
2879         }
2880
2881       debugAopGet ("removing right:", IC_RIGHT (ic));
2882
2883       /* found it we need to remove it from the
2884          block */
2885       for (sic = dic; sic != ic; sic = sic->next)
2886         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2887
2888       IC_RIGHT (ic)->operand.symOperand =
2889         IC_RIGHT (dic)->operand.symOperand;
2890       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2891
2892       remiCodeFromeBBlock (ebp, dic);
2893       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2894       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2895       change++;
2896     }
2897
2898   return change;
2899 }
2900
2901 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2902
2903
2904 /*-----------------------------------------------------------------*/
2905 /* packRegsForOneuse : - will reduce some registers for single Use */
2906 /*-----------------------------------------------------------------*/
2907 static iCode *
2908 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2909 {
2910   bitVect *uses;
2911   iCode *dic, *sic;
2912
2913   debugLog ("%s\n", __FUNCTION__);
2914   /* if returning a literal then do nothing */
2915   if (!IS_SYMOP (op))
2916     return NULL;
2917
2918   /* only upto 2 bytes since we cannot predict
2919      the usage of b, & acc */
2920   if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2921       ic->op != RETURN &&
2922       ic->op != SEND)
2923     return NULL;
2924
2925   /* this routine will mark the a symbol as used in one 
2926      instruction use only && if the definition is local 
2927      (ie. within the basic block) && has only one definition &&
2928      that definition is either a return value from a 
2929      function or does not contain any variables in
2930      far space */
2931   uses = bitVectCopy (OP_USES (op));
2932   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2933   if (!bitVectIsZero (uses))    /* has other uses */
2934     return NULL;
2935
2936   /* if it has only one defintion */
2937   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2938     return NULL;                /* has more than one definition */
2939
2940   /* get that definition */
2941   if (!(dic =
2942         hTabItemWithKey (iCodehTab,
2943                          bitVectFirstBit (OP_DEFS (op)))))
2944     return NULL;
2945
2946   /* found the definition now check if it is local */
2947   if (dic->seq < ebp->fSeq ||
2948       dic->seq > ebp->lSeq)
2949     return NULL;                /* non-local */
2950
2951   /* now check if it is the return from
2952      a function call */
2953   if (dic->op == CALL || dic->op == PCALL)
2954     {
2955       if (ic->op != SEND && ic->op != RETURN &&
2956           !POINTER_SET(ic) && !POINTER_GET(ic))
2957         {
2958           OP_SYMBOL (op)->ruonly = 1;
2959           return dic;
2960         }
2961       dic = dic->next;
2962     }
2963
2964
2965   /* otherwise check that the definition does
2966      not contain any symbols in far space */
2967   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2968       isOperandInFarSpace (IC_RIGHT (dic)) ||
2969       IS_OP_RUONLY (IC_LEFT (ic)) ||
2970       IS_OP_RUONLY (IC_RIGHT (ic)))
2971     {
2972       return NULL;
2973     }
2974
2975   /* if pointer set then make sure the pointer
2976      is one byte */
2977   if (POINTER_SET (dic) &&
2978       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2979     return NULL;
2980
2981   if (POINTER_GET (dic) &&
2982       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2983     return NULL;
2984
2985   sic = dic;
2986
2987   /* also make sure the intervenening instructions
2988      don't have any thing in far space */
2989   for (dic = dic->next; dic && dic != ic; dic = dic->next)
2990     {
2991
2992       /* if there is an intervening function call then no */
2993       if (dic->op == CALL || dic->op == PCALL)
2994         return NULL;
2995       /* if pointer set then make sure the pointer
2996          is one byte */
2997       if (POINTER_SET (dic) &&
2998           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2999         return NULL;
3000
3001       if (POINTER_GET (dic) &&
3002           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3003         return NULL;
3004
3005       /* if address of & the result is remat then okay */
3006       if (dic->op == ADDRESS_OF &&
3007           OP_SYMBOL (IC_RESULT (dic))->remat)
3008         continue;
3009
3010       /* if operand has size of three or more & this
3011          operation is a '*','/' or '%' then 'b' may
3012          cause a problem */
3013       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3014           getSize (operandType (op)) >= 3)
3015         return NULL;
3016
3017       /* if left or right or result is in far space */
3018       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3019           isOperandInFarSpace (IC_RIGHT (dic)) ||
3020           isOperandInFarSpace (IC_RESULT (dic)) ||
3021           IS_OP_RUONLY (IC_LEFT (dic)) ||
3022           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3023           IS_OP_RUONLY (IC_RESULT (dic)))
3024         {
3025           return NULL;
3026         }
3027     }
3028
3029   OP_SYMBOL (op)->ruonly = 1;
3030   return sic;
3031
3032 }
3033
3034 /*-----------------------------------------------------------------*/
3035 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3036 /*-----------------------------------------------------------------*/
3037 static bool
3038 isBitwiseOptimizable (iCode * ic)
3039 {
3040   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3041   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3042
3043   debugLog ("%s\n", __FUNCTION__);
3044   /* bitwise operations are considered optimizable
3045      under the following conditions (Jean-Louis VERN) 
3046
3047      x & lit
3048      bit & bit
3049      bit & x
3050      bit ^ bit
3051      bit ^ x
3052      x   ^ lit
3053      x   | lit
3054      bit | bit
3055      bit | x
3056    */
3057   if (IS_LITERAL (rtype) ||
3058       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3059     return TRUE;
3060   else
3061     return FALSE;
3062 }
3063
3064 /*-----------------------------------------------------------------*/
3065 /* packRegsForAccUse - pack registers for acc use                  */
3066 /*-----------------------------------------------------------------*/
3067 static void
3068 packRegsForAccUse (iCode * ic)
3069 {
3070   iCode *uic;
3071
3072   debugLog ("%s\n", __FUNCTION__);
3073
3074   /* if this is an aggregate, e.g. a one byte char array */
3075   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3076     return;
3077   }
3078
3079   /* if + or - then it has to be one byte result */
3080   if ((ic->op == '+' || ic->op == '-')
3081       && getSize (operandType (IC_RESULT (ic))) > 1)
3082     return;
3083
3084   /* if shift operation make sure right side is not a literal */
3085   if (ic->op == RIGHT_OP &&
3086       (isOperandLiteral (IC_RIGHT (ic)) ||
3087        getSize (operandType (IC_RESULT (ic))) > 1))
3088     return;
3089
3090   if (ic->op == LEFT_OP &&
3091       (isOperandLiteral (IC_RIGHT (ic)) ||
3092        getSize (operandType (IC_RESULT (ic))) > 1))
3093     return;
3094
3095   if (IS_BITWISE_OP (ic) &&
3096       getSize (operandType (IC_RESULT (ic))) > 1)
3097     return;
3098
3099
3100   /* has only one definition */
3101   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3102     return;
3103
3104   /* has only one use */
3105   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3106     return;
3107
3108   /* and the usage immediately follows this iCode */
3109   if (!(uic = hTabItemWithKey (iCodehTab,
3110                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3111     return;
3112
3113   if (ic->next != uic)
3114     return;
3115
3116   /* if it is a conditional branch then we definitely can */
3117   if (uic->op == IFX)
3118     goto accuse;
3119
3120   if (uic->op == JUMPTABLE)
3121     return;
3122
3123   /* if the usage is not is an assignment
3124      or an arithmetic / bitwise / shift operation then not */
3125   if (POINTER_SET (uic) &&
3126       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3127     return;
3128
3129   if (uic->op != '=' &&
3130       !IS_ARITHMETIC_OP (uic) &&
3131       !IS_BITWISE_OP (uic) &&
3132       uic->op != LEFT_OP &&
3133       uic->op != RIGHT_OP)
3134     return;
3135
3136   /* if used in ^ operation then make sure right is not a 
3137      literl */
3138   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3139     return;
3140
3141   /* if shift operation make sure right side is not a literal */
3142   if (uic->op == RIGHT_OP &&
3143       (isOperandLiteral (IC_RIGHT (uic)) ||
3144        getSize (operandType (IC_RESULT (uic))) > 1))
3145     return;
3146
3147   if (uic->op == LEFT_OP &&
3148       (isOperandLiteral (IC_RIGHT (uic)) ||
3149        getSize (operandType (IC_RESULT (uic))) > 1))
3150     return;
3151
3152   /* make sure that the result of this icode is not on the
3153      stack, since acc is used to compute stack offset */
3154   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3155       OP_SYMBOL (IC_RESULT (uic))->onStack)
3156     return;
3157
3158   /* if either one of them in far space then we cannot */
3159   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3160        isOperandInFarSpace (IC_LEFT (uic))) ||
3161       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3162        isOperandInFarSpace (IC_RIGHT (uic))))
3163     return;
3164
3165   /* if the usage has only one operand then we can */
3166   if (IC_LEFT (uic) == NULL ||
3167       IC_RIGHT (uic) == NULL)
3168     goto accuse;
3169
3170   /* make sure this is on the left side if not
3171      a '+' since '+' is commutative */
3172   if (ic->op != '+' &&
3173       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3174     return;
3175
3176   /* if one of them is a literal then we can */
3177   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3178       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
3179     {
3180       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3181       return;
3182     }
3183
3184   /* if the other one is not on stack then we can */
3185   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3186       (IS_ITEMP (IC_RIGHT (uic)) ||
3187        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3188         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3189     goto accuse;
3190
3191   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3192       (IS_ITEMP (IC_LEFT (uic)) ||
3193        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3194         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3195     goto accuse;
3196
3197   return;
3198
3199 accuse:
3200   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3201   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3202
3203
3204 }
3205
3206 /*-----------------------------------------------------------------*/
3207 /* packForPush - hueristics to reduce iCode for pushing            */
3208 /*-----------------------------------------------------------------*/
3209 static void
3210 packForReceive (iCode * ic, eBBlock * ebp)
3211 {
3212   iCode *dic;
3213
3214   debugLog ("%s\n", __FUNCTION__);
3215   debugAopGet ("  result:", IC_RESULT (ic));
3216   debugAopGet ("  left:", IC_LEFT (ic));
3217   debugAopGet ("  right:", IC_RIGHT (ic));
3218
3219   if (!ic->next)
3220     return;
3221
3222   for (dic = ic->next; dic; dic = dic->next)
3223     {
3224
3225
3226
3227       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3228         debugLog ("    used on left\n");
3229       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3230         debugLog ("    used on right\n");
3231       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3232         debugLog ("    used on result\n");
3233
3234       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3235           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3236         return;
3237
3238     }
3239
3240   debugLog ("  hey we can remove this unnecessary assign\n");
3241 }
3242 /*-----------------------------------------------------------------*/
3243 /* packForPush - hueristics to reduce iCode for pushing            */
3244 /*-----------------------------------------------------------------*/
3245 static void
3246 packForPush (iCode * ic, eBBlock * ebp)
3247 {
3248   iCode *dic;
3249
3250   debugLog ("%s\n", __FUNCTION__);
3251   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3252     return;
3253
3254   /* must have only definition & one usage */
3255   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3256       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3257     return;
3258
3259   /* find the definition */
3260   if (!(dic = hTabItemWithKey (iCodehTab,
3261                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3262     return;
3263
3264   if (dic->op != '=' || POINTER_SET (dic))
3265     return;
3266
3267   /* we now we know that it has one & only one def & use
3268      and the that the definition is an assignment */
3269   IC_LEFT (ic) = IC_RIGHT (dic);
3270
3271   remiCodeFromeBBlock (ebp, dic);
3272   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3273   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3274 }
3275
3276 void printSymType(char * str, sym_link *sl)
3277 {
3278   debugLog ("    %s Symbol type: ",str);
3279   printTypeChain( sl, debugF);
3280   debugLog ("\n");
3281
3282 }
3283
3284 /*-----------------------------------------------------------------*/
3285 /* packRegisters - does some transformations to reduce register    */
3286 /*                   pressure                                      */
3287 /*-----------------------------------------------------------------*/
3288 static void
3289 packRegisters (eBBlock * ebp)
3290 {
3291   iCode *ic;
3292   int change = 0;
3293
3294   debugLog ("%s\n", __FUNCTION__);
3295
3296   while (1) {
3297
3298     change = 0;
3299
3300     /* look for assignments of the form */
3301     /* iTempNN = TRueSym (someoperation) SomeOperand */
3302     /*       ....                       */
3303     /* TrueSym := iTempNN:1             */
3304     for (ic = ebp->sch; ic; ic = ic->next)
3305       {
3306
3307         /* find assignment of the form TrueSym := iTempNN:1 */
3308         if (ic->op == '=' && !POINTER_SET (ic))
3309           change += packRegsForAssign (ic, ebp);
3310         /* debug stuff */
3311         if (ic->op == '=')
3312           {
3313             if (POINTER_SET (ic))
3314               debugLog ("pointer is set\n");
3315             debugAopGet ("  result:", IC_RESULT (ic));
3316             debugAopGet ("  left:", IC_LEFT (ic));
3317             debugAopGet ("  right:", IC_RIGHT (ic));
3318           }
3319
3320       }
3321
3322     if (!change)
3323       break;
3324   }
3325
3326   for (ic = ebp->sch; ic; ic = ic->next) {
3327
3328     if(IS_SYMOP ( IC_LEFT(ic))) {
3329       //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3330
3331       debugAopGet ("  left:", IC_LEFT (ic));
3332       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3333         debugLog ("    is a pointer");
3334
3335       printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3336     }
3337
3338     if(IS_SYMOP ( IC_RIGHT(ic))) {
3339       debugAopGet ("  right:", IC_RIGHT (ic));
3340       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3341     }
3342
3343     if(IS_SYMOP ( IC_RESULT(ic))) {
3344       debugAopGet ("  result:", IC_RESULT (ic));
3345       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3346     }
3347
3348     if (POINTER_SET (ic))
3349         debugLog ("  %d - Pointer set\n", __LINE__);
3350
3351
3352     /* if this is an itemp & result of a address of a true sym 
3353        then mark this as rematerialisable   */
3354     if (ic->op == ADDRESS_OF &&
3355         IS_ITEMP (IC_RESULT (ic)) &&
3356         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3357         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3358         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3359       {
3360
3361         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3362
3363         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3364         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3365         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3366
3367       }
3368
3369     /* if straight assignment then carry remat flag if
3370        this is the only definition */
3371     if (ic->op == '=' &&
3372         !POINTER_SET (ic) &&
3373         IS_SYMOP (IC_RIGHT (ic)) &&
3374         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3375         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3376       {
3377         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3378
3379         OP_SYMBOL (IC_RESULT (ic))->remat =
3380           OP_SYMBOL (IC_RIGHT (ic))->remat;
3381         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3382           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3383       }
3384
3385     /* if this is a +/- operation with a rematerizable 
3386        then mark this as rematerializable as well */
3387     if ((ic->op == '+' || ic->op == '-') &&
3388         (IS_SYMOP (IC_LEFT (ic)) &&
3389          IS_ITEMP (IC_RESULT (ic)) &&
3390          OP_SYMBOL (IC_LEFT (ic))->remat &&
3391          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3392          IS_OP_LITERAL (IC_RIGHT (ic))))
3393       {
3394         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3395         //int i = 
3396         operandLitValue (IC_RIGHT (ic));
3397         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3398         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3399         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3400       }
3401
3402     /* mark the pointer usages */
3403     if (POINTER_SET (ic))
3404       {
3405         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3406         debugLog ("  marking as a pointer (set) =>");
3407         debugAopGet ("  result:", IC_RESULT (ic));
3408       }
3409     if (POINTER_GET (ic))
3410       {
3411         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3412         debugLog ("  marking as a pointer (get) =>");
3413         debugAopGet ("  left:", IC_LEFT (ic));
3414       }
3415
3416     if (!SKIP_IC2 (ic))
3417       {
3418         /* if we are using a symbol on the stack
3419            then we should say pic14_ptrRegReq */
3420         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3421           pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3422                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3423         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3424           pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3425                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3426         else
3427           {
3428             if (IS_SYMOP (IC_LEFT (ic)))
3429               pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3430                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3431             if (IS_SYMOP (IC_RIGHT (ic)))
3432               pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3433                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3434             if (IS_SYMOP (IC_RESULT (ic)))
3435               pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3436                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3437           }
3438
3439         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3440
3441       }
3442
3443     /* if the condition of an if instruction
3444        is defined in the previous instruction then
3445        mark the itemp as a conditional */
3446     if ((IS_CONDITIONAL (ic) ||
3447          ((ic->op == BITWISEAND ||
3448            ic->op == '|' ||
3449            ic->op == '^') &&
3450           isBitwiseOptimizable (ic))) &&
3451         ic->next && ic->next->op == IFX &&
3452         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3453         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3454       {
3455
3456         debugLog ("  %d\n", __LINE__);
3457         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3458         continue;
3459       }
3460
3461     /* reduce for support function calls */
3462     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3463       packRegsForSupport (ic, ebp);
3464
3465     /* if a parameter is passed, it's in W, so we may not
3466        need to place a copy in a register */
3467     if (ic->op == RECEIVE)
3468       packForReceive (ic, ebp);
3469
3470     /* some cases the redundant moves can
3471        can be eliminated for return statements */
3472     if ((ic->op == RETURN || ic->op == SEND) &&
3473         !isOperandInFarSpace (IC_LEFT (ic)) &&
3474         !options.model)
3475       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3476
3477     /* if pointer set & left has a size more than
3478        one and right is not in far space */
3479     if (POINTER_SET (ic) &&
3480         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3481         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3482         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3483         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3484
3485       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3486
3487     /* if pointer get */
3488     if (POINTER_GET (ic) &&
3489         !isOperandInFarSpace (IC_RESULT (ic)) &&
3490         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3491         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3492         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3493
3494       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3495
3496
3497     /* if this is cast for intergral promotion then
3498        check if only use of  the definition of the 
3499        operand being casted/ if yes then replace
3500        the result of that arithmetic operation with 
3501        this result and get rid of the cast */
3502     if (ic->op == CAST) {
3503         
3504       sym_link *fromType = operandType (IC_RIGHT (ic));
3505       sym_link *toType = operandType (IC_LEFT (ic));
3506
3507       debugLog ("  %d - casting\n", __LINE__);
3508
3509       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3510           getSize (fromType) != getSize (toType)) {
3511             
3512
3513         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3514         if (dic) {
3515                 
3516           if (IS_ARITHMETIC_OP (dic)) {
3517                     
3518             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3519             IC_RESULT (dic) = IC_RESULT (ic);
3520             remiCodeFromeBBlock (ebp, ic);
3521             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3522             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3523             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3524             ic = ic->prev;
3525           }  else
3526                 
3527             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3528         }
3529       } else {
3530
3531         /* if the type from and type to are the same
3532            then if this is the only use then packit */
3533         if (compareType (operandType (IC_RIGHT (ic)),
3534                          operandType (IC_LEFT (ic))) == 1) {
3535                 
3536           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3537           if (dic) {
3538                     
3539             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3540             IC_RESULT (dic) = IC_RESULT (ic);
3541             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3542             remiCodeFromeBBlock (ebp, ic);
3543             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3544             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3545             ic = ic->prev;
3546           }
3547         }
3548       }
3549     }
3550
3551     /* pack for PUSH 
3552        iTempNN := (some variable in farspace) V1
3553        push iTempNN ;
3554        -------------
3555        push V1
3556     */
3557     if (ic->op == IPUSH)
3558       {
3559         packForPush (ic, ebp);
3560       }
3561
3562
3563     /* pack registers for accumulator use, when the
3564        result of an arithmetic or bit wise operation
3565        has only one use, that use is immediately following
3566        the defintion and the using iCode has only one
3567        operand or has two operands but one is literal &
3568        the result of that operation is not on stack then
3569        we can leave the result of this operation in acc:b
3570        combination */
3571     if ((IS_ARITHMETIC_OP (ic)
3572
3573          || IS_BITWISE_OP (ic)
3574
3575          || ic->op == LEFT_OP || ic->op == RIGHT_OP
3576
3577          ) &&
3578         IS_ITEMP (IC_RESULT (ic)) &&
3579         getSize (operandType (IC_RESULT (ic))) <= 2)
3580
3581       packRegsForAccUse (ic);
3582
3583   }
3584 }
3585
3586 static void
3587 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3588 {
3589   int i;
3590
3591   if (!debug || !debugF)
3592     return;
3593
3594   for (i = 0; i < count; i++)
3595     {
3596       fprintf (debugF, "\n----------------------------------------------------------------\n");
3597       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3598                ebbs[i]->entryLabel->name,
3599                ebbs[i]->depth,
3600                ebbs[i]->noPath,
3601                ebbs[i]->isLastInLoop);
3602       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3603                ebbs[i]->dfnum,
3604                ebbs[i]->bbnum,
3605                ebbs[i]->fSeq,
3606                ebbs[i]->lSeq);
3607       fprintf (debugF, "visited %d : hasFcall = %d\n",
3608                ebbs[i]->visited,
3609                ebbs[i]->hasFcall);
3610
3611       fprintf (debugF, "\ndefines bitVector :");
3612       bitVectDebugOn (ebbs[i]->defSet, debugF);
3613       fprintf (debugF, "\nlocal defines bitVector :");
3614       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3615       fprintf (debugF, "\npointers Set bitvector :");
3616       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3617       fprintf (debugF, "\nin pointers Set bitvector :");
3618       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3619       fprintf (debugF, "\ninDefs Set bitvector :");
3620       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3621       fprintf (debugF, "\noutDefs Set bitvector :");
3622       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3623       fprintf (debugF, "\nusesDefs Set bitvector :");
3624       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3625       fprintf (debugF, "\n----------------------------------------------------------------\n");
3626       printiCChain (ebbs[i]->sch, debugF);
3627     }
3628 }
3629 /*-----------------------------------------------------------------*/
3630 /* assignRegisters - assigns registers to each live range as need  */
3631 /*-----------------------------------------------------------------*/
3632 void
3633 pic14_assignRegisters (eBBlock ** ebbs, int count)
3634 {
3635   iCode *ic;
3636   int i;
3637
3638   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3639   debugLog ("\nebbs before optimizing:\n");
3640   dumpEbbsToDebug (ebbs, count);
3641
3642   setToNull ((void *) &_G.funcrUsed);
3643   pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3644
3645
3646   /* change assignments this will remove some
3647      live ranges reducing some register pressure */
3648   for (i = 0; i < count; i++)
3649     packRegisters (ebbs[i]);
3650
3651   {
3652     regs *reg;
3653     int hkey;
3654     int i=0;
3655
3656     debugLog("dir registers allocated so far:\n");
3657     reg = hTabFirstItem(dynDirectRegNames, &hkey);
3658
3659     while(reg) {
3660       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3661       reg = hTabNextItem(dynDirectRegNames, &hkey);
3662     }
3663
3664   }
3665
3666   if (options.dump_pack)
3667     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3668
3669   /* first determine for each live range the number of 
3670      registers & the type of registers required for each */
3671   regTypeNum ();
3672
3673   /* and serially allocate registers */
3674   serialRegAssign (ebbs, count);
3675
3676   /* if stack was extended then tell the user */
3677   if (_G.stackExtend)
3678     {
3679 /*      werror(W_TOOMANY_SPILS,"stack", */
3680 /*             _G.stackExtend,currFunc->name,""); */
3681       _G.stackExtend = 0;
3682     }
3683
3684   if (_G.dataExtend)
3685     {
3686 /*      werror(W_TOOMANY_SPILS,"data space", */
3687 /*             _G.dataExtend,currFunc->name,""); */
3688       _G.dataExtend = 0;
3689     }
3690
3691   /* after that create the register mask
3692      for each of the instruction */
3693   createRegMask (ebbs, count);
3694
3695   /* redo that offsets for stacked automatic variables */
3696   redoStackOffsets ();
3697
3698   if (options.dump_rassgn)
3699     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3700
3701   /* now get back the chain */
3702   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3703
3704   debugLog ("ebbs after optimizing:\n");
3705   dumpEbbsToDebug (ebbs, count);
3706
3707
3708   genpic14Code (ic);
3709
3710   /* free up any _G.stackSpil locations allocated */
3711   applyToSet (_G.stackSpil, deallocStackSpil);
3712   _G.slocNum = 0;
3713   setToNull ((void **) &_G.stackSpil);
3714   setToNull ((void **) &_G.spiltSet);
3715   /* mark all registers as free */
3716   pic14_freeAllRegs ();
3717
3718   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3719   debugLogClose ();
3720   return;
3721 }