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