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