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