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