Replaced cast (void **) with (void *) to avoid gcc 3 warning:
[fw/sdcc] / src / pic16 / ralloc.c
1 /*------------------------------------------------------------------------
2
3   ralloc.c - source file for register allocation. PIC16 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 0
2505     if(IS_PTR_CONST (sym->type)) {
2506 #else
2507     if(IS_CODEPTR (sym->type)) {
2508 #endif
2509       debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2510       sym->nRegs = 2;
2511     }
2512
2513       if (sym->nRegs > 4) {
2514         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2515         printTypeChain (sym->type, stderr);
2516         fprintf (stderr, "\n");
2517       }
2518
2519       /* determine the type of register required */
2520       if (sym->nRegs == 1 &&
2521           IS_PTR (sym->type) &&
2522           sym->uptr)
2523         sym->regType = REG_PTR;
2524       else
2525         sym->regType = REG_GPR;
2526
2527
2528       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2529
2530     }
2531     else
2532       /* for the first run we don't provide */
2533       /* registers for true symbols we will */
2534       /* see how things go                  */
2535       sym->nRegs = 0;
2536   }
2537
2538 }
2539 static DEFSETFUNC (markRegFree)
2540 {
2541   ((regs *)item)->isFree = 1;
2542
2543   return 0;
2544 }
2545
2546 DEFSETFUNC (pic16_deallocReg)
2547 {
2548   fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2549   ((regs *)item)->isFree = 1;
2550   ((regs *)item)->wasUsed = 0;
2551
2552   return 0;
2553 }
2554 /*-----------------------------------------------------------------*/
2555 /* freeAllRegs - mark all registers as free                        */
2556 /*-----------------------------------------------------------------*/
2557 void
2558 pic16_freeAllRegs ()
2559 {
2560   //  int i;
2561
2562   debugLog ("%s\n", __FUNCTION__);
2563
2564   applyToSet(pic16_dynAllocRegs,markRegFree);
2565   applyToSet(pic16_dynStackRegs,markRegFree);
2566
2567 /*
2568   for (i = 0; i < pic16_nRegs; i++)
2569     regspic16[i].isFree = 1;
2570 */
2571 }
2572
2573 /*-----------------------------------------------------------------*/
2574 /*-----------------------------------------------------------------*/
2575 void
2576 pic16_deallocateAllRegs ()
2577 {
2578   //  int i;
2579
2580   debugLog ("%s\n", __FUNCTION__);
2581
2582   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2583
2584 /*
2585   for (i = 0; i < pic16_nRegs; i++) {
2586     if(regspic16[i].pc_type == PO_GPR_TEMP) {
2587       regspic16[i].isFree = 1;
2588       regspic16[i].wasUsed = 0;
2589     }
2590   }
2591 */
2592 }
2593
2594
2595 /*-----------------------------------------------------------------*/
2596 /* deallocStackSpil - this will set the stack pointer back         */
2597 /*-----------------------------------------------------------------*/
2598 static
2599 DEFSETFUNC (deallocStackSpil)
2600 {
2601   symbol *sym = item;
2602
2603   debugLog ("%s\n", __FUNCTION__);
2604   deallocLocal (sym);
2605   return 0;
2606 }
2607
2608 /*-----------------------------------------------------------------*/
2609 /* farSpacePackable - returns the packable icode for far variables */
2610 /*-----------------------------------------------------------------*/
2611 static iCode *
2612 farSpacePackable (iCode * ic)
2613 {
2614   iCode *dic;
2615
2616   debugLog ("%s\n", __FUNCTION__);
2617   /* go thru till we find a definition for the
2618      symbol on the right */
2619   for (dic = ic->prev; dic; dic = dic->prev)
2620     {
2621
2622       /* if the definition is a call then no */
2623       if ((dic->op == CALL || dic->op == PCALL) &&
2624           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2625         {
2626           return NULL;
2627         }
2628
2629       /* if shift by unknown amount then not */
2630       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2631           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2632         return NULL;
2633
2634       /* if pointer get and size > 1 */
2635       if (POINTER_GET (dic) &&
2636           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2637         return NULL;
2638
2639       if (POINTER_SET (dic) &&
2640           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2641         return NULL;
2642
2643       /* if any three is a true symbol in far space */
2644       if (IC_RESULT (dic) &&
2645           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2646           isOperandInFarSpace (IC_RESULT (dic)))
2647         return NULL;
2648
2649       if (IC_RIGHT (dic) &&
2650           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2651           isOperandInFarSpace (IC_RIGHT (dic)) &&
2652           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2653         return NULL;
2654
2655       if (IC_LEFT (dic) &&
2656           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2657           isOperandInFarSpace (IC_LEFT (dic)) &&
2658           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2659         return NULL;
2660
2661       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2662         {
2663           if ((dic->op == LEFT_OP ||
2664                dic->op == RIGHT_OP ||
2665                dic->op == '-') &&
2666               IS_OP_LITERAL (IC_RIGHT (dic)))
2667             return NULL;
2668           else
2669             return dic;
2670         }
2671     }
2672
2673   return NULL;
2674 }
2675
2676 /*-----------------------------------------------------------------*/
2677 /* packRegsForAssign - register reduction for assignment           */
2678 /*-----------------------------------------------------------------*/
2679 static int
2680 packRegsForAssign (iCode * ic, eBBlock * ebp)
2681 {
2682
2683   iCode *dic, *sic;
2684
2685   debugLog ("%s\n", __FUNCTION__);
2686
2687   debugAopGet ("  result:", IC_RESULT (ic));
2688   debugAopGet ("  left:", IC_LEFT (ic));
2689   debugAopGet ("  right:", IC_RIGHT (ic));
2690
2691   /* if this is at an absolute address, then get the address. */
2692   if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2693     if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2694       debugLog ("  %d - found config word declaration\n", __LINE__);
2695       if(IS_VALOP(IC_RIGHT(ic))) {
2696         debugLog ("  setting config word to %x\n", 
2697                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2698         pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2699                                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2700       }
2701
2702       /* remove the assignment from the iCode chain. */
2703
2704       remiCodeFromeBBlock (ebp, ic);
2705       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2706       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2707
2708       return 1;
2709
2710     }
2711   }
2712
2713   if (!IS_ITEMP (IC_RESULT (ic))) {
2714     pic16_allocDirReg(IC_RESULT (ic));
2715     debugLog ("  %d - result is not temp\n", __LINE__);
2716   }
2717 /*
2718   if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2719     debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2720     pic16_allocDirReg(IC_LEFT (ic));
2721   }
2722 */
2723
2724   if (!IS_ITEMP (IC_RIGHT (ic))) {
2725     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2726     pic16_allocDirReg(IC_RIGHT (ic));
2727     return 0;
2728   }
2729
2730   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2731       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2732     {
2733       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2734       return 0;
2735     }
2736
2737   /* if the true symbol is defined in far space or on stack
2738      then we should not since this will increase register pressure */
2739   if (isOperandInFarSpace (IC_RESULT (ic)))
2740     {
2741       if ((dic = farSpacePackable (ic)))
2742         goto pack;
2743       else
2744         return 0;
2745
2746     }
2747   /* find the definition of iTempNN scanning backwards if we find a 
2748      a use of the true symbol before we find the definition then 
2749      we cannot pack */
2750   for (dic = ic->prev; dic; dic = dic->prev)
2751     {
2752
2753       /* if there is a function call and this is
2754          a parameter & not my parameter then don't pack it */
2755       if ((dic->op == CALL || dic->op == PCALL) &&
2756           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2757            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2758         {
2759           debugLog ("  %d - \n", __LINE__);
2760           dic = NULL;
2761           break;
2762         }
2763
2764       if (SKIP_IC2 (dic))
2765         continue;
2766
2767       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2768           IS_OP_VOLATILE (IC_RESULT (dic)))
2769         {
2770           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2771           dic = NULL;
2772           break;
2773         }
2774
2775       if (IS_SYMOP (IC_RESULT (dic)) &&
2776           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2777         {
2778           /* A previous result was assigned to the same register - we'll our definition */
2779           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2780                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2781           if (POINTER_SET (dic))
2782             dic = NULL;
2783
2784           break;
2785         }
2786
2787       if (IS_SYMOP (IC_RIGHT (dic)) &&
2788           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2789            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2790         {
2791           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2792           dic = NULL;
2793           break;
2794         }
2795
2796       if (IS_SYMOP (IC_LEFT (dic)) &&
2797           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2798            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2799         {
2800           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2801           dic = NULL;
2802           break;
2803         }
2804
2805       if (POINTER_SET (dic) &&
2806           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2807         {
2808           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2809                     __LINE__);
2810           dic = NULL;
2811           break;
2812         }
2813     }
2814
2815   if (!dic)
2816     return 0;                   /* did not find */
2817
2818   /* if the result is on stack or iaccess then it must be
2819      the same atleast one of the operands */
2820   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2821       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2822     {
2823
2824       /* the operation has only one symbol
2825          operator then we can pack */
2826       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2827           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2828         goto pack;
2829
2830       if (!((IC_LEFT (dic) &&
2831              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2832             (IC_RIGHT (dic) &&
2833              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2834         return 0;
2835     }
2836 pack:
2837   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2838   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2839   /* found the definition */
2840   /* replace the result with the result of */
2841   /* this assignment and remove this assignment */
2842   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2843   IC_RESULT (dic) = IC_RESULT (ic);
2844
2845   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2846     {
2847       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2848     }
2849   /* delete from liverange table also 
2850      delete from all the points inbetween and the new
2851      one */
2852   for (sic = dic; sic != ic; sic = sic->next)
2853     {
2854       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2855       if (IS_ITEMP (IC_RESULT (dic)))
2856         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2857     }
2858
2859   remiCodeFromeBBlock (ebp, ic);
2860   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2861   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2862   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2863   return 1;
2864
2865
2866 }
2867
2868 /*-----------------------------------------------------------------*/
2869 /* findAssignToSym : scanning backwards looks for first assig found */
2870 /*-----------------------------------------------------------------*/
2871 static iCode *
2872 findAssignToSym (operand * op, iCode * ic)
2873 {
2874   iCode *dic;
2875
2876   debugLog ("%s\n", __FUNCTION__);
2877   for (dic = ic->prev; dic; dic = dic->prev)
2878     {
2879
2880       /* if definition by assignment */
2881       if (dic->op == '=' &&
2882           !POINTER_SET (dic) &&
2883           IC_RESULT (dic)->key == op->key
2884 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2885         )
2886         {
2887
2888           /* we are interested only if defined in far space */
2889           /* or in stack space in case of + & - */
2890
2891           /* if assigned to a non-symbol then return
2892              true */
2893           if (!IS_SYMOP (IC_RIGHT (dic)))
2894             break;
2895
2896           /* if the symbol is in far space then
2897              we should not */
2898           if (isOperandInFarSpace (IC_RIGHT (dic)))
2899             return NULL;
2900
2901           /* for + & - operations make sure that
2902              if it is on the stack it is the same
2903              as one of the three operands */
2904           if ((ic->op == '+' || ic->op == '-') &&
2905               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2906             {
2907
2908               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2909                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2910                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2911                 return NULL;
2912             }
2913
2914           break;
2915
2916         }
2917
2918       /* if we find an usage then we cannot delete it */
2919       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2920         return NULL;
2921
2922       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2923         return NULL;
2924
2925       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2926         return NULL;
2927     }
2928
2929   /* now make sure that the right side of dic
2930      is not defined between ic & dic */
2931   if (dic)
2932     {
2933       iCode *sic = dic->next;
2934
2935       for (; sic != ic; sic = sic->next)
2936         if (IC_RESULT (sic) &&
2937             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2938           return NULL;
2939     }
2940
2941   return dic;
2942
2943
2944 }
2945
2946 /*-----------------------------------------------------------------*/
2947 /* packRegsForSupport :- reduce some registers for support calls   */
2948 /*-----------------------------------------------------------------*/
2949 static int
2950 packRegsForSupport (iCode * ic, eBBlock * ebp)
2951 {
2952   int change = 0;
2953
2954   debugLog ("%s\n", __FUNCTION__);
2955   /* for the left & right operand :- look to see if the
2956      left was assigned a true symbol in far space in that
2957      case replace them */
2958   if (IS_ITEMP (IC_LEFT (ic)) &&
2959       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2960     {
2961       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2962       iCode *sic;
2963
2964       if (!dic)
2965         goto right;
2966
2967       debugAopGet ("removing left:", IC_LEFT (ic));
2968
2969       /* found it we need to remove it from the
2970          block */
2971       for (sic = dic; sic != ic; sic = sic->next)
2972         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2973
2974       IC_LEFT (ic)->operand.symOperand =
2975         IC_RIGHT (dic)->operand.symOperand;
2976       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2977       remiCodeFromeBBlock (ebp, dic);
2978       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2979       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2980       change++;
2981     }
2982
2983   /* do the same for the right operand */
2984 right:
2985   if (!change &&
2986       IS_ITEMP (IC_RIGHT (ic)) &&
2987       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2988     {
2989       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2990       iCode *sic;
2991
2992       if (!dic)
2993         return change;
2994
2995       /* if this is a subtraction & the result
2996          is a true symbol in far space then don't pack */
2997       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2998         {
2999           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3000           if (IN_FARSPACE (SPEC_OCLS (etype)))
3001             return change;
3002         }
3003
3004       debugAopGet ("removing right:", IC_RIGHT (ic));
3005
3006       /* found it we need to remove it from the
3007          block */
3008       for (sic = dic; sic != ic; sic = sic->next)
3009         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3010
3011       IC_RIGHT (ic)->operand.symOperand =
3012         IC_RIGHT (dic)->operand.symOperand;
3013       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3014
3015       remiCodeFromeBBlock (ebp, dic);
3016       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3017       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3018       change++;
3019     }
3020
3021   return change;
3022 }
3023
3024 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3025
3026
3027 /*-----------------------------------------------------------------*/
3028 /* packRegsForOneuse : - will reduce some registers for single Use */
3029 /*-----------------------------------------------------------------*/
3030 static iCode *
3031 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3032 {
3033   bitVect *uses;
3034   iCode *dic, *sic;
3035
3036   debugLog ("%s\n", __FUNCTION__);
3037   /* if returning a literal then do nothing */
3038   if (!IS_SYMOP (op))
3039     return NULL;
3040
3041   /* only upto 2 bytes since we cannot predict
3042      the usage of b, & acc */
3043   if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3044       ic->op != RETURN &&
3045       ic->op != SEND)
3046     return NULL;
3047
3048   /* this routine will mark the a symbol as used in one 
3049      instruction use only && if the definition is local 
3050      (ie. within the basic block) && has only one definition &&
3051      that definition is either a return value from a 
3052      function or does not contain any variables in
3053      far space */
3054   uses = bitVectCopy (OP_USES (op));
3055   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
3056   if (!bitVectIsZero (uses))    /* has other uses */
3057     return NULL;
3058
3059   /* if it has only one defintion */
3060   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3061     return NULL;                /* has more than one definition */
3062
3063   /* get that definition */
3064   if (!(dic =
3065         hTabItemWithKey (iCodehTab,
3066                          bitVectFirstBit (OP_DEFS (op)))))
3067     return NULL;
3068
3069   /* found the definition now check if it is local */
3070   if (dic->seq < ebp->fSeq ||
3071       dic->seq > ebp->lSeq)
3072     return NULL;                /* non-local */
3073
3074   /* now check if it is the return from
3075      a function call */
3076   if (dic->op == CALL || dic->op == PCALL)
3077     {
3078       if (ic->op != SEND && ic->op != RETURN &&
3079           !POINTER_SET(ic) && !POINTER_GET(ic))
3080         {
3081           OP_SYMBOL (op)->ruonly = 1;
3082           return dic;
3083         }
3084       dic = dic->next;
3085     }
3086
3087
3088   /* otherwise check that the definition does
3089      not contain any symbols in far space */
3090   if (isOperandInFarSpace (IC_LEFT (dic)) ||
3091       isOperandInFarSpace (IC_RIGHT (dic)) ||
3092       IS_OP_RUONLY (IC_LEFT (ic)) ||
3093       IS_OP_RUONLY (IC_RIGHT (ic)))
3094     {
3095       return NULL;
3096     }
3097
3098   /* if pointer set then make sure the pointer
3099      is one byte */
3100   if (POINTER_SET (dic) &&
3101       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3102     return NULL;
3103
3104   if (POINTER_GET (dic) &&
3105       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3106     return NULL;
3107
3108   sic = dic;
3109
3110   /* also make sure the intervenening instructions
3111      don't have any thing in far space */
3112   for (dic = dic->next; dic && dic != ic; dic = dic->next)
3113     {
3114
3115       /* if there is an intervening function call then no */
3116       if (dic->op == CALL || dic->op == PCALL)
3117         return NULL;
3118       /* if pointer set then make sure the pointer
3119          is one byte */
3120       if (POINTER_SET (dic) &&
3121           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3122         return NULL;
3123
3124       if (POINTER_GET (dic) &&
3125           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3126         return NULL;
3127
3128       /* if address of & the result is remat then okay */
3129       if (dic->op == ADDRESS_OF &&
3130           OP_SYMBOL (IC_RESULT (dic))->remat)
3131         continue;
3132
3133       /* if operand has size of three or more & this
3134          operation is a '*','/' or '%' then 'b' may
3135          cause a problem */
3136       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3137           getSize (operandType (op)) >= 3)
3138         return NULL;
3139
3140       /* if left or right or result is in far space */
3141       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3142           isOperandInFarSpace (IC_RIGHT (dic)) ||
3143           isOperandInFarSpace (IC_RESULT (dic)) ||
3144           IS_OP_RUONLY (IC_LEFT (dic)) ||
3145           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3146           IS_OP_RUONLY (IC_RESULT (dic)))
3147         {
3148           return NULL;
3149         }
3150     }
3151
3152   OP_SYMBOL (op)->ruonly = 1;
3153   return sic;
3154
3155 }
3156
3157 /*-----------------------------------------------------------------*/
3158 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3159 /*-----------------------------------------------------------------*/
3160 static bool
3161 isBitwiseOptimizable (iCode * ic)
3162 {
3163   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3164   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3165
3166   debugLog ("%s\n", __FUNCTION__);
3167   /* bitwise operations are considered optimizable
3168      under the following conditions (Jean-Louis VERN) 
3169
3170      x & lit
3171      bit & bit
3172      bit & x
3173      bit ^ bit
3174      bit ^ x
3175      x   ^ lit
3176      x   | lit
3177      bit | bit
3178      bit | x
3179    */
3180   if (IS_LITERAL (rtype) ||
3181       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3182     return TRUE;
3183   else
3184     return FALSE;
3185 }
3186
3187 /*-----------------------------------------------------------------*/
3188 /* packRegsForAccUse - pack registers for acc use                  */
3189 /*-----------------------------------------------------------------*/
3190 static void
3191 packRegsForAccUse (iCode * ic)
3192 {
3193   iCode *uic;
3194
3195   debugLog ("%s\n", __FUNCTION__);
3196
3197   /* if this is an aggregate, e.g. a one byte char array */
3198   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3199     return;
3200   }
3201   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3202
3203   /* if + or - then it has to be one byte result */
3204   if ((ic->op == '+' || ic->op == '-')
3205       && getSize (operandType (IC_RESULT (ic))) > 1)
3206     return;
3207
3208   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3209   /* if shift operation make sure right side is not a literal */
3210   if (ic->op == RIGHT_OP &&
3211       (isOperandLiteral (IC_RIGHT (ic)) ||
3212        getSize (operandType (IC_RESULT (ic))) > 1))
3213     return;
3214
3215   if (ic->op == LEFT_OP &&
3216       (isOperandLiteral (IC_RIGHT (ic)) ||
3217        getSize (operandType (IC_RESULT (ic))) > 1))
3218     return;
3219
3220   if (IS_BITWISE_OP (ic) &&
3221       getSize (operandType (IC_RESULT (ic))) > 1)
3222     return;
3223
3224
3225   /* has only one definition */
3226   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3227     return;
3228
3229   /* has only one use */
3230   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3231     return;
3232
3233   /* and the usage immediately follows this iCode */
3234   if (!(uic = hTabItemWithKey (iCodehTab,
3235                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3236     return;
3237
3238   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3239   if (ic->next != uic)
3240     return;
3241
3242   /* if it is a conditional branch then we definitely can */
3243   if (uic->op == IFX)
3244     goto accuse;
3245
3246   if (uic->op == JUMPTABLE)
3247     return;
3248
3249   /* if the usage is not is an assignment
3250      or an arithmetic / bitwise / shift operation then not */
3251   if (POINTER_SET (uic) &&
3252       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3253     return;
3254
3255   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3256   if (uic->op != '=' &&
3257       !IS_ARITHMETIC_OP (uic) &&
3258       !IS_BITWISE_OP (uic) &&
3259       uic->op != LEFT_OP &&
3260       uic->op != RIGHT_OP)
3261     return;
3262
3263   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3264   /* if used in ^ operation then make sure right is not a 
3265      literl */
3266   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3267     return;
3268
3269   /* if shift operation make sure right side is not a literal */
3270   if (uic->op == RIGHT_OP &&
3271       (isOperandLiteral (IC_RIGHT (uic)) ||
3272        getSize (operandType (IC_RESULT (uic))) > 1))
3273     return;
3274
3275   if (uic->op == LEFT_OP &&
3276       (isOperandLiteral (IC_RIGHT (uic)) ||
3277        getSize (operandType (IC_RESULT (uic))) > 1))
3278     return;
3279
3280   /* make sure that the result of this icode is not on the
3281      stack, since acc is used to compute stack offset */
3282   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3283       OP_SYMBOL (IC_RESULT (uic))->onStack)
3284     return;
3285
3286   /* if either one of them in far space then we cannot */
3287   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3288        isOperandInFarSpace (IC_LEFT (uic))) ||
3289       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3290        isOperandInFarSpace (IC_RIGHT (uic))))
3291     return;
3292
3293   /* if the usage has only one operand then we can */
3294   if (IC_LEFT (uic) == NULL ||
3295       IC_RIGHT (uic) == NULL)
3296     goto accuse;
3297
3298   /* make sure this is on the left side if not
3299      a '+' since '+' is commutative */
3300   if (ic->op != '+' &&
3301       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3302     return;
3303
3304   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3305   /* if one of them is a literal then we can */
3306   if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3307         (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3308        (getSize (operandType (IC_RESULT (uic))) <= 1))
3309     {
3310       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3311       return;
3312     }
3313
3314   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3315   /* if the other one is not on stack then we can */
3316   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3317       (IS_ITEMP (IC_RIGHT (uic)) ||
3318        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3319         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3320     goto accuse;
3321
3322   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3323       (IS_ITEMP (IC_LEFT (uic)) ||
3324        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3325         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3326     goto accuse;
3327
3328   return;
3329
3330 accuse:
3331   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3332   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3333
3334
3335 }
3336
3337 /*-----------------------------------------------------------------*/
3338 /* packForPush - hueristics to reduce iCode for pushing            */
3339 /*-----------------------------------------------------------------*/
3340 static void
3341 packForReceive (iCode * ic, eBBlock * ebp)
3342 {
3343   iCode *dic;
3344
3345   debugLog ("%s\n", __FUNCTION__);
3346   debugAopGet ("  result:", IC_RESULT (ic));
3347   debugAopGet ("  left:", IC_LEFT (ic));
3348   debugAopGet ("  right:", IC_RIGHT (ic));
3349
3350   if (!ic->next)
3351     return;
3352
3353   for (dic = ic->next; dic; dic = dic->next)
3354     {
3355
3356
3357
3358       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3359         debugLog ("    used on left\n");
3360       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3361         debugLog ("    used on right\n");
3362       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3363         debugLog ("    used on result\n");
3364
3365       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3366           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3367         return;
3368
3369     }
3370
3371   debugLog ("  hey we can remove this unnecessary assign\n");
3372 }
3373 /*-----------------------------------------------------------------*/
3374 /* packForPush - hueristics to reduce iCode for pushing            */
3375 /*-----------------------------------------------------------------*/
3376 static void
3377 packForPush (iCode * ic, eBBlock * ebp)
3378 {
3379   iCode *dic;
3380
3381   debugLog ("%s\n", __FUNCTION__);
3382   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3383     return;
3384
3385   /* must have only definition & one usage */
3386   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3387       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3388     return;
3389
3390   /* find the definition */
3391   if (!(dic = hTabItemWithKey (iCodehTab,
3392                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3393     return;
3394
3395   if (dic->op != '=' || POINTER_SET (dic))
3396     return;
3397
3398   /* we now we know that it has one & only one def & use
3399      and the that the definition is an assignment */
3400   IC_LEFT (ic) = IC_RIGHT (dic);
3401
3402   remiCodeFromeBBlock (ebp, dic);
3403   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3404   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3405 }
3406
3407 static void printSymType(char * str, sym_link *sl)
3408 {
3409   debugLog ("    %s Symbol type: ",str);
3410   printTypeChain( sl, debugF);
3411   debugLog ("\n");
3412
3413 }
3414
3415 /*-----------------------------------------------------------------*/
3416 /* some debug code to print the symbol S_TYPE. Note that
3417  * the function checkSClass in src/SDCCsymt.c dinks with
3418  * the S_TYPE in ways the PIC port doesn't fully like...*/
3419 /*-----------------------------------------------------------------*/
3420 static void isData(sym_link *sl)
3421 {
3422   FILE *of = stderr;
3423
3424   if(!sl)
3425     return;
3426
3427   if(debugF)
3428     of = debugF;
3429
3430   for ( ; sl; sl=sl->next) {
3431     if(!IS_DECL(sl) ) {
3432       switch (SPEC_SCLS(sl)) {
3433         
3434       case S_DATA: fprintf (of, "data "); break;
3435       case S_XDATA: fprintf (of, "xdata "); break;
3436       case S_SFR: fprintf (of, "sfr "); break;
3437       case S_SBIT: fprintf (of, "sbit "); break;
3438       case S_CODE: fprintf (of, "code "); break;
3439       case S_IDATA: fprintf (of, "idata "); break;
3440       case S_PDATA: fprintf (of, "pdata "); break;
3441       case S_LITERAL: fprintf (of, "literal "); break;
3442       case S_STACK: fprintf (of, "stack "); break;
3443       case S_XSTACK: fprintf (of, "xstack "); break;
3444       case S_BIT: fprintf (of, "bit "); break;
3445       case S_EEPROM: fprintf (of, "eeprom "); break;
3446       default: break;
3447       }
3448
3449     }
3450
3451   }
3452     
3453 }
3454 /*-----------------------------------------------------------------*/
3455 /* packRegisters - does some transformations to reduce register    */
3456 /*                   pressure                                      */
3457 /*-----------------------------------------------------------------*/
3458 static void
3459 packRegisters (eBBlock * ebp)
3460 {
3461   iCode *ic;
3462   int change = 0;
3463
3464   debugLog ("%s\n", __FUNCTION__);
3465
3466   while (1) {
3467
3468     change = 0;
3469
3470     /* look for assignments of the form */
3471     /* iTempNN = TRueSym (someoperation) SomeOperand */
3472     /*       ....                       */
3473     /* TrueSym := iTempNN:1             */
3474     for (ic = ebp->sch; ic; ic = ic->next)
3475       {
3476
3477         /* find assignment of the form TrueSym := iTempNN:1 */
3478         if (ic->op == '=' && !POINTER_SET (ic))
3479           change += packRegsForAssign (ic, ebp);
3480         /* debug stuff */
3481         if (ic->op == '=')
3482           {
3483             if (POINTER_SET (ic))
3484               debugLog ("pointer is set\n");
3485             debugAopGet ("  result:", IC_RESULT (ic));
3486             debugAopGet ("  left:", IC_LEFT (ic));
3487             debugAopGet ("  right:", IC_RIGHT (ic));
3488           }
3489
3490       }
3491
3492     if (!change)
3493       break;
3494   }
3495
3496   for (ic = ebp->sch; ic; ic = ic->next) {
3497
3498     if(IS_SYMOP ( IC_LEFT(ic))) {
3499       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3500
3501       debugAopGet ("  left:", IC_LEFT (ic));
3502 #if 0
3503       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3504 #else
3505       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3506 #endif
3507         debugLog ("    is a pointer\n");
3508
3509       if(IS_OP_VOLATILE(IC_LEFT(ic)))
3510         debugLog ("    is volatile\n");
3511
3512       isData(etype);
3513
3514       printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3515     }
3516
3517     if(IS_SYMOP ( IC_RIGHT(ic))) {
3518       debugAopGet ("  right:", IC_RIGHT (ic));
3519       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3520     }
3521
3522     if(IS_SYMOP ( IC_RESULT(ic))) {
3523       debugAopGet ("  result:", IC_RESULT (ic));
3524       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3525     }
3526
3527     if (POINTER_SET (ic))
3528         debugLog ("  %d - Pointer set\n", __LINE__);
3529
3530
3531     /* if this is an itemp & result of a address of a true sym 
3532        then mark this as rematerialisable   */
3533     if (ic->op == ADDRESS_OF &&
3534         IS_ITEMP (IC_RESULT (ic)) &&
3535         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3536         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3537         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3538       {
3539
3540         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3541
3542         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3543         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3544         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3545
3546       }
3547
3548     /* if straight assignment then carry remat flag if
3549        this is the only definition */
3550     if (ic->op == '=' &&
3551         !POINTER_SET (ic) &&
3552         IS_SYMOP (IC_RIGHT (ic)) &&
3553         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3554         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3555       {
3556         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3557
3558         OP_SYMBOL (IC_RESULT (ic))->remat =
3559           OP_SYMBOL (IC_RIGHT (ic))->remat;
3560         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3561           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3562       }
3563
3564     /* if this is a +/- operation with a rematerizable 
3565        then mark this as rematerializable as well */
3566     if ((ic->op == '+' || ic->op == '-') &&
3567         (IS_SYMOP (IC_LEFT (ic)) &&
3568          IS_ITEMP (IC_RESULT (ic)) &&
3569          OP_SYMBOL (IC_LEFT (ic))->remat &&
3570          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3571          IS_OP_LITERAL (IC_RIGHT (ic))))
3572       {
3573         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3574         //int i = 
3575         operandLitValue (IC_RIGHT (ic));
3576         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3577         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3578         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3579       }
3580
3581     /* mark the pointer usages */
3582     if (POINTER_SET (ic))
3583       {
3584         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3585         debugLog ("  marking as a pointer (set) =>");
3586         debugAopGet ("  result:", IC_RESULT (ic));
3587       }
3588     if (POINTER_GET (ic))
3589       {
3590         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3591         debugLog ("  marking as a pointer (get) =>");
3592         debugAopGet ("  left:", IC_LEFT (ic));
3593       }
3594
3595     if (!SKIP_IC2 (ic))
3596       {
3597         /* if we are using a symbol on the stack
3598            then we should say pic16_ptrRegReq */
3599         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3600           pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3601                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3602         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3603           pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3604                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3605         else
3606           {
3607             if (IS_SYMOP (IC_LEFT (ic)))
3608               pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3609                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3610             if (IS_SYMOP (IC_RIGHT (ic)))
3611               pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3612                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3613             if (IS_SYMOP (IC_RESULT (ic)))
3614               pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3615                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3616           }
3617
3618         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3619
3620       }
3621
3622     /* if the condition of an if instruction
3623        is defined in the previous instruction then
3624        mark the itemp as a conditional */
3625     if ((IS_CONDITIONAL (ic) ||
3626          ((ic->op == BITWISEAND ||
3627            ic->op == '|' ||
3628            ic->op == '^') &&
3629           isBitwiseOptimizable (ic))) &&
3630         ic->next && ic->next->op == IFX &&
3631         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3632         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3633       {
3634
3635         debugLog ("  %d\n", __LINE__);
3636         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3637         continue;
3638       }
3639
3640     /* reduce for support function calls */
3641     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3642       packRegsForSupport (ic, ebp);
3643
3644     /* if a parameter is passed, it's in W, so we may not
3645        need to place a copy in a register */
3646     if (ic->op == RECEIVE)
3647       packForReceive (ic, ebp);
3648
3649     /* some cases the redundant moves can
3650        can be eliminated for return statements */
3651     if ((ic->op == RETURN || ic->op == SEND) &&
3652         !isOperandInFarSpace (IC_LEFT (ic)) &&
3653         !options.model)
3654       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3655
3656     /* if pointer set & left has a size more than
3657        one and right is not in far space */
3658     if (POINTER_SET (ic) &&
3659         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3660         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3661         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3662         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3663
3664       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3665
3666     /* if pointer get */
3667     if (POINTER_GET (ic) &&
3668         !isOperandInFarSpace (IC_RESULT (ic)) &&
3669         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3670         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3671         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3672
3673       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3674
3675
3676     /* if this is cast for intergral promotion then
3677        check if only use of  the definition of the 
3678        operand being casted/ if yes then replace
3679        the result of that arithmetic operation with 
3680        this result and get rid of the cast */
3681     if (ic->op == CAST) {
3682         
3683       sym_link *fromType = operandType (IC_RIGHT (ic));
3684       sym_link *toType = operandType (IC_LEFT (ic));
3685
3686       debugLog ("  %d - casting\n", __LINE__);
3687
3688       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3689           getSize (fromType) != getSize (toType)) {
3690             
3691
3692         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3693         if (dic) {
3694                 
3695           if (IS_ARITHMETIC_OP (dic)) {
3696                     
3697             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3698             IC_RESULT (dic) = IC_RESULT (ic);
3699             remiCodeFromeBBlock (ebp, ic);
3700             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3701             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3702             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3703             ic = ic->prev;
3704           }  else
3705                 
3706             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3707         }
3708       } else {
3709
3710         /* if the type from and type to are the same
3711            then if this is the only use then packit */
3712         if (compareType (operandType (IC_RIGHT (ic)),
3713                          operandType (IC_LEFT (ic))) == 1) {
3714                 
3715           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3716           if (dic) {
3717                     
3718             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3719             IC_RESULT (dic) = IC_RESULT (ic);
3720             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3721             remiCodeFromeBBlock (ebp, ic);
3722             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3723             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3724             ic = ic->prev;
3725           }
3726         }
3727       }
3728     }
3729
3730     /* pack for PUSH 
3731        iTempNN := (some variable in farspace) V1
3732        push iTempNN ;
3733        -------------
3734        push V1
3735     */
3736     if (ic->op == IPUSH)
3737       {
3738         packForPush (ic, ebp);
3739       }
3740
3741
3742     /* pack registers for accumulator use, when the
3743        result of an arithmetic or bit wise operation
3744        has only one use, that use is immediately following
3745        the defintion and the using iCode has only one
3746        operand or has two operands but one is literal &
3747        the result of that operation is not on stack then
3748        we can leave the result of this operation in acc:b
3749        combination */
3750     if ((IS_ARITHMETIC_OP (ic)
3751
3752          || IS_BITWISE_OP (ic)
3753
3754          || ic->op == LEFT_OP || ic->op == RIGHT_OP
3755
3756          ) &&
3757         IS_ITEMP (IC_RESULT (ic)) &&
3758         getSize (operandType (IC_RESULT (ic))) <= 2)
3759
3760       packRegsForAccUse (ic);
3761
3762   }
3763 }
3764
3765 static void
3766 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3767 {
3768   int i;
3769
3770   if (!debug || !debugF)
3771     return;
3772
3773   for (i = 0; i < count; i++)
3774     {
3775       fprintf (debugF, "\n----------------------------------------------------------------\n");
3776       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3777                ebbs[i]->entryLabel->name,
3778                ebbs[i]->depth,
3779                ebbs[i]->noPath,
3780                ebbs[i]->isLastInLoop);
3781       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3782                ebbs[i]->dfnum,
3783                ebbs[i]->bbnum,
3784                ebbs[i]->fSeq,
3785                ebbs[i]->lSeq);
3786       fprintf (debugF, "visited %d : hasFcall = %d\n",
3787                ebbs[i]->visited,
3788                ebbs[i]->hasFcall);
3789
3790       fprintf (debugF, "\ndefines bitVector :");
3791       bitVectDebugOn (ebbs[i]->defSet, debugF);
3792       fprintf (debugF, "\nlocal defines bitVector :");
3793       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3794       fprintf (debugF, "\npointers Set bitvector :");
3795       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3796       fprintf (debugF, "\nin pointers Set bitvector :");
3797       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3798       fprintf (debugF, "\ninDefs Set bitvector :");
3799       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3800       fprintf (debugF, "\noutDefs Set bitvector :");
3801       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3802       fprintf (debugF, "\nusesDefs Set bitvector :");
3803       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3804       fprintf (debugF, "\n----------------------------------------------------------------\n");
3805       printiCChain (ebbs[i]->sch, debugF);
3806     }
3807 }
3808 /*-----------------------------------------------------------------*/
3809 /* pic16_assignRegisters - assigns registers to each live range as need  */
3810 /*-----------------------------------------------------------------*/
3811 void
3812 pic16_assignRegisters (eBBlock ** ebbs, int count)
3813 {
3814   iCode *ic;
3815   int i;
3816
3817   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3818   debugLog ("\nebbs before optimizing:\n");
3819   dumpEbbsToDebug (ebbs, count);
3820
3821   setToNull ((void *) &_G.funcrUsed);
3822   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3823
3824
3825   /* change assignments this will remove some
3826      live ranges reducing some register pressure */
3827   for (i = 0; i < count; i++)
3828     packRegisters (ebbs[i]);
3829
3830   {
3831     regs *reg;
3832     int hkey;
3833     int i=0;
3834
3835     debugLog("dir registers allocated so far:\n");
3836     reg = hTabFirstItem(dynDirectRegNames, &hkey);
3837
3838     while(reg) {
3839       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3840       reg = hTabNextItem(dynDirectRegNames, &hkey);
3841     }
3842
3843   }
3844
3845   if (options.dump_pack)
3846     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3847
3848   /* first determine for each live range the number of 
3849      registers & the type of registers required for each */
3850   regTypeNum ();
3851
3852   /* and serially allocate registers */
3853   serialRegAssign (ebbs, count);
3854
3855   /* if stack was extended then tell the user */
3856   if (_G.stackExtend)
3857     {
3858 /*      werror(W_TOOMANY_SPILS,"stack", */
3859 /*             _G.stackExtend,currFunc->name,""); */
3860       _G.stackExtend = 0;
3861     }
3862
3863   if (_G.dataExtend)
3864     {
3865 /*      werror(W_TOOMANY_SPILS,"data space", */
3866 /*             _G.dataExtend,currFunc->name,""); */
3867       _G.dataExtend = 0;
3868     }
3869
3870   /* after that create the register mask
3871      for each of the instruction */
3872   createRegMask (ebbs, count);
3873
3874   /* redo that offsets for stacked automatic variables */
3875   redoStackOffsets ();
3876
3877   if (options.dump_rassgn)
3878     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3879
3880   /* now get back the chain */
3881   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3882
3883   debugLog ("ebbs after optimizing:\n");
3884   dumpEbbsToDebug (ebbs, count);
3885
3886
3887   genpic16Code (ic);
3888
3889   /* free up any _G.stackSpil locations allocated */
3890   applyToSet (_G.stackSpil, deallocStackSpil);
3891   _G.slocNum = 0;
3892   setToNull ((void *) &_G.stackSpil);
3893   setToNull ((void *) &_G.spiltSet);
3894   /* mark all registers as free */
3895   //pic16_freeAllRegs ();
3896
3897   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3898   debugLogClose ();
3899   return;
3900 }