Added the pic16 port for Martin Dubuc.
[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 || !srcFileName)
108     return;
109
110
111   if (!debugF)
112     {
113       /* create the file name */
114       strcpy (buffer, srcFileName);
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
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 extern void pic16_assignFixedRegisters(set *regset);
949 extern void pic16_assignRelocatableRegisters(set *regset,int used);
950 extern void pic16_dump_map(void);
951 extern void pic16_dump_cblock(FILE *of);
952
953
954 static void packBits(set *bregs)
955 {
956   set *regset;
957   regs *breg;
958   regs *bitfield=NULL;
959   regs *relocbitfield=NULL;
960   int bit_no=0;
961   int byte_no=-1;
962   char buffer[20];
963
964
965   for (regset = bregs ; regset ;
966        regset = regset->next) {
967
968     breg = regset->item;
969     breg->isBitField = 1;
970     //fprintf(stderr,"bit reg: %s\n",breg->name);
971
972     if(breg->isFixed) {
973       //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
974
975       bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
976       breg->rIdx = breg->address & 7;
977       breg->address >>= 3;
978
979       if(!bitfield) {
980         sprintf (buffer, "fbitfield%02x", breg->address);
981         //fprintf(stderr,"new bit field\n");
982         bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
983         bitfield->isBitField = 1;
984         bitfield->isFixed = 1;
985         bitfield->address = breg->address;
986         addSet(&pic16_dynDirectRegs,bitfield);
987         //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
988       } else {
989         //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
990         ;
991       }
992       breg->reg_alias = bitfield;
993       bitfield = NULL;
994
995     } else {
996       if(!relocbitfield || bit_no >7) {
997         byte_no++;
998         bit_no=0;
999         sprintf (buffer, "bitfield%d", byte_no);
1000         //fprintf(stderr,"new relocatable bit field\n");
1001         relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1002         relocbitfield->isBitField = 1;
1003         addSet(&pic16_dynDirectRegs,relocbitfield);
1004         //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1005
1006       }
1007
1008       breg->reg_alias = relocbitfield;
1009       breg->address = rDirectIdx;   /* byte_no; */
1010       breg->rIdx = bit_no++;
1011     }
1012   }
1013       
1014 }
1015
1016
1017
1018 static void bitEQUs(FILE *of, set *bregs)
1019 {
1020   regs *breg,*bytereg;
1021   int bit_no=0;
1022
1023   //fprintf(stderr," %s\n",__FUNCTION__);
1024   for (breg = setFirstItem(bregs) ; breg ;
1025        breg = setNextItem(bregs)) {
1026
1027     //fprintf(stderr,"bit reg: %s\n",breg->name);
1028
1029     bytereg = breg->reg_alias;
1030     if(bytereg)
1031       fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1032                breg->name,
1033                bytereg->name,
1034                breg->rIdx & 0x0007);
1035
1036     else {
1037       fprintf(stderr, "bit field is not assigned to a register\n");
1038       fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1039                breg->name,
1040                bit_no>>3,
1041                bit_no & 0x0007);
1042
1043       bit_no++;
1044     }
1045   }
1046       
1047 }
1048
1049 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1050 {
1051   regs *reg;
1052
1053
1054   for (reg = setFirstItem(fregs) ; reg ;
1055        reg = setNextItem(fregs)) {
1056
1057     if(!reg->isEmitted && reg->wasUsed) {
1058       if(use_rIdx) {
1059         if (reg->type != REG_SFR) {
1060           fprintf (of, "%s\tEQU\t0x%03x\n",
1061                    reg->name,
1062                    reg->rIdx);
1063         }
1064       }
1065       else
1066         fprintf (of, "%s\tEQU\t0x%03x\n",
1067                  reg->name,
1068                  reg->address);
1069     }
1070   }
1071       
1072 }
1073
1074 void pic16_writeUsedRegs(FILE *of) 
1075 {
1076   packBits(pic16_dynDirectBitRegs);
1077
1078
1079   pic16_assignFixedRegisters(pic16_dynAllocRegs);
1080   pic16_assignFixedRegisters(pic16_dynStackRegs);
1081   pic16_assignFixedRegisters(pic16_dynDirectRegs);
1082
1083   pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1084   pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1085   pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1086   pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1087
1088   //pic16_dump_map();
1089
1090   pic16_dump_cblock(of);
1091   bitEQUs(of,pic16_dynDirectBitRegs);
1092   aliasEQUs(of,pic16_dynAllocRegs,0);
1093   aliasEQUs(of,pic16_dynDirectRegs,0);
1094   aliasEQUs(of,pic16_dynStackRegs,0);
1095   aliasEQUs(of,pic16_dynProcessorRegs,1);
1096
1097 }
1098
1099 #if 0
1100 /*-----------------------------------------------------------------*/
1101 /* allDefsOutOfRange - all definitions are out of a range          */
1102 /*-----------------------------------------------------------------*/
1103 static bool
1104 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1105 {
1106   int i;
1107
1108   debugLog ("%s\n", __FUNCTION__);
1109   if (!defs)
1110     return TRUE;
1111
1112   for (i = 0; i < defs->size; i++)
1113     {
1114       iCode *ic;
1115
1116       if (bitVectBitValue (defs, i) &&
1117           (ic = hTabItemWithKey (iCodehTab, i)) &&
1118           (ic->seq >= fseq && ic->seq <= toseq))
1119
1120         return FALSE;
1121
1122     }
1123
1124   return TRUE;
1125 }
1126 #endif
1127
1128 /*-----------------------------------------------------------------*/
1129 /* computeSpillable - given a point find the spillable live ranges */
1130 /*-----------------------------------------------------------------*/
1131 static bitVect *
1132 computeSpillable (iCode * ic)
1133 {
1134   bitVect *spillable;
1135
1136   debugLog ("%s\n", __FUNCTION__);
1137   /* spillable live ranges are those that are live at this 
1138      point . the following categories need to be subtracted
1139      from this set. 
1140      a) - those that are already spilt
1141      b) - if being used by this one
1142      c) - defined by this one */
1143
1144   spillable = bitVectCopy (ic->rlive);
1145   spillable =
1146     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
1147   spillable =
1148     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
1149   bitVectUnSetBit (spillable, ic->defKey);
1150   spillable = bitVectIntersect (spillable, _G.regAssigned);
1151   return spillable;
1152
1153 }
1154
1155 /*-----------------------------------------------------------------*/
1156 /* noSpilLoc - return true if a variable has no spil location      */
1157 /*-----------------------------------------------------------------*/
1158 static int
1159 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1160 {
1161   debugLog ("%s\n", __FUNCTION__);
1162   return (sym->usl.spillLoc ? 0 : 1);
1163 }
1164
1165 /*-----------------------------------------------------------------*/
1166 /* hasSpilLoc - will return 1 if the symbol has spil location      */
1167 /*-----------------------------------------------------------------*/
1168 static int
1169 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1170 {
1171   debugLog ("%s\n", __FUNCTION__);
1172   return (sym->usl.spillLoc ? 1 : 0);
1173 }
1174
1175 /*-----------------------------------------------------------------*/
1176 /* directSpilLoc - will return 1 if the splilocation is in direct  */
1177 /*-----------------------------------------------------------------*/
1178 static int
1179 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1180 {
1181   debugLog ("%s\n", __FUNCTION__);
1182   if (sym->usl.spillLoc &&
1183       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1184     return 1;
1185   else
1186     return 0;
1187 }
1188
1189 /*-----------------------------------------------------------------*/
1190 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1191 /*                    but is not used as a pointer                 */
1192 /*-----------------------------------------------------------------*/
1193 static int
1194 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1195 {
1196   debugLog ("%s\n", __FUNCTION__);
1197   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1198 }
1199
1200 /*-----------------------------------------------------------------*/
1201 /* rematable - will return 1 if the remat flag is set              */
1202 /*-----------------------------------------------------------------*/
1203 static int
1204 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1205 {
1206   debugLog ("%s\n", __FUNCTION__);
1207   return sym->remat;
1208 }
1209
1210 /*-----------------------------------------------------------------*/
1211 /* notUsedInRemaining - not used or defined in remain of the block */
1212 /*-----------------------------------------------------------------*/
1213 static int
1214 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1215 {
1216   debugLog ("%s\n", __FUNCTION__);
1217   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1218           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1219 }
1220
1221 /*-----------------------------------------------------------------*/
1222 /* allLRs - return true for all                                    */
1223 /*-----------------------------------------------------------------*/
1224 static int
1225 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1226 {
1227   debugLog ("%s\n", __FUNCTION__);
1228   return 1;
1229 }
1230
1231 /*-----------------------------------------------------------------*/
1232 /* liveRangesWith - applies function to a given set of live range  */
1233 /*-----------------------------------------------------------------*/
1234 static set *
1235 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1236                 eBBlock * ebp, iCode * ic)
1237 {
1238   set *rset = NULL;
1239   int i;
1240
1241   debugLog ("%s\n", __FUNCTION__);
1242   if (!lrs || !lrs->size)
1243     return NULL;
1244
1245   for (i = 1; i < lrs->size; i++)
1246     {
1247       symbol *sym;
1248       if (!bitVectBitValue (lrs, i))
1249         continue;
1250
1251       /* if we don't find it in the live range 
1252          hash table we are in serious trouble */
1253       if (!(sym = hTabItemWithKey (liveRanges, i)))
1254         {
1255           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1256                   "liveRangesWith could not find liveRange");
1257           exit (1);
1258         }
1259
1260       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1261         addSetHead (&rset, sym);
1262     }
1263
1264   return rset;
1265 }
1266
1267
1268 /*-----------------------------------------------------------------*/
1269 /* leastUsedLR - given a set determines which is the least used    */
1270 /*-----------------------------------------------------------------*/
1271 static symbol *
1272 leastUsedLR (set * sset)
1273 {
1274   symbol *sym = NULL, *lsym = NULL;
1275
1276   debugLog ("%s\n", __FUNCTION__);
1277   sym = lsym = setFirstItem (sset);
1278
1279   if (!lsym)
1280     return NULL;
1281
1282   for (; lsym; lsym = setNextItem (sset))
1283     {
1284
1285       /* if usage is the same then prefer
1286          the spill the smaller of the two */
1287       if (lsym->used == sym->used)
1288         if (getSize (lsym->type) < getSize (sym->type))
1289           sym = lsym;
1290
1291       /* if less usage */
1292       if (lsym->used < sym->used)
1293         sym = lsym;
1294
1295     }
1296
1297   setToNull ((void **) &sset);
1298   sym->blockSpil = 0;
1299   return sym;
1300 }
1301
1302 /*-----------------------------------------------------------------*/
1303 /* noOverLap - will iterate through the list looking for over lap  */
1304 /*-----------------------------------------------------------------*/
1305 static int
1306 noOverLap (set * itmpStack, symbol * fsym)
1307 {
1308   symbol *sym;
1309   debugLog ("%s\n", __FUNCTION__);
1310
1311
1312   for (sym = setFirstItem (itmpStack); sym;
1313        sym = setNextItem (itmpStack))
1314     {
1315       if (sym->liveTo > fsym->liveFrom)
1316         return 0;
1317
1318     }
1319
1320   return 1;
1321 }
1322
1323 /*-----------------------------------------------------------------*/
1324 /* isFree - will return 1 if the a free spil location is found     */
1325 /*-----------------------------------------------------------------*/
1326 static
1327 DEFSETFUNC (isFree)
1328 {
1329   symbol *sym = item;
1330   V_ARG (symbol **, sloc);
1331   V_ARG (symbol *, fsym);
1332
1333   debugLog ("%s\n", __FUNCTION__);
1334   /* if already found */
1335   if (*sloc)
1336     return 0;
1337
1338   /* if it is free && and the itmp assigned to
1339      this does not have any overlapping live ranges
1340      with the one currently being assigned and
1341      the size can be accomodated  */
1342   if (sym->isFree &&
1343       noOverLap (sym->usl.itmpStack, fsym) &&
1344       getSize (sym->type) >= getSize (fsym->type))
1345     {
1346       *sloc = sym;
1347       return 1;
1348     }
1349
1350   return 0;
1351 }
1352
1353 /*-----------------------------------------------------------------*/
1354 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
1355 /*-----------------------------------------------------------------*/
1356 static void
1357 spillLRWithPtrReg (symbol * forSym)
1358 {
1359   symbol *lrsym;
1360   regs *r0, *r1;
1361   int k;
1362
1363   debugLog ("%s\n", __FUNCTION__);
1364   if (!_G.regAssigned ||
1365       bitVectIsZero (_G.regAssigned))
1366     return;
1367
1368   r0 = pic16_regWithIdx (R0_IDX);
1369   r1 = pic16_regWithIdx (R1_IDX);
1370
1371   /* for all live ranges */
1372   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1373        lrsym = hTabNextItem (liveRanges, &k))
1374     {
1375       int j;
1376
1377       /* if no registers assigned to it or
1378          spilt */
1379       /* if it does not overlap with this then 
1380          not need to spill it */
1381
1382       if (lrsym->isspilt || !lrsym->nRegs ||
1383           (lrsym->liveTo < forSym->liveFrom))
1384         continue;
1385
1386       /* go thru the registers : if it is either
1387          r0 or r1 then spil it */
1388       for (j = 0; j < lrsym->nRegs; j++)
1389         if (lrsym->regs[j] == r0 ||
1390             lrsym->regs[j] == r1)
1391           {
1392             spillThis (lrsym);
1393             break;
1394           }
1395     }
1396
1397 }
1398
1399 /*-----------------------------------------------------------------*/
1400 /* createStackSpil - create a location on the stack to spil        */
1401 /*-----------------------------------------------------------------*/
1402 static symbol *
1403 createStackSpil (symbol * sym)
1404 {
1405   symbol *sloc = NULL;
1406   int useXstack, model, noOverlay;
1407
1408   char slocBuffer[30];
1409   debugLog ("%s\n", __FUNCTION__);
1410
1411   /* first go try and find a free one that is already 
1412      existing on the stack */
1413   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1414     {
1415       /* found a free one : just update & return */
1416       sym->usl.spillLoc = sloc;
1417       sym->stackSpil = 1;
1418       sloc->isFree = 0;
1419       addSetHead (&sloc->usl.itmpStack, sym);
1420       return sym;
1421     }
1422
1423   /* could not then have to create one , this is the hard part
1424      we need to allocate this on the stack : this is really a
1425      hack!! but cannot think of anything better at this time */
1426
1427   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1428     {
1429       fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1430                __FILE__, __LINE__);
1431       exit (1);
1432     }
1433
1434   sloc = newiTemp (slocBuffer);
1435
1436   /* set the type to the spilling symbol */
1437   sloc->type = copyLinkChain (sym->type);
1438   sloc->etype = getSpec (sloc->type);
1439   SPEC_SCLS (sloc->etype) = S_DATA;
1440   SPEC_EXTR (sloc->etype) = 0;
1441   SPEC_STAT (sloc->etype) = 0;
1442
1443   /* we don't allow it to be allocated`
1444      onto the external stack since : so we
1445      temporarily turn it off ; we also
1446      turn off memory model to prevent
1447      the spil from going to the external storage
1448      and turn off overlaying 
1449    */
1450
1451   useXstack = options.useXstack;
1452   model = options.model;
1453   noOverlay = options.noOverlay;
1454   options.noOverlay = 1;
1455   options.model = options.useXstack = 0;
1456
1457   allocLocal (sloc);
1458
1459   options.useXstack = useXstack;
1460   options.model = model;
1461   options.noOverlay = noOverlay;
1462   sloc->isref = 1;              /* to prevent compiler warning */
1463
1464   /* if it is on the stack then update the stack */
1465   if (IN_STACK (sloc->etype))
1466     {
1467       currFunc->stack += getSize (sloc->type);
1468       _G.stackExtend += getSize (sloc->type);
1469     }
1470   else
1471     _G.dataExtend += getSize (sloc->type);
1472
1473   /* add it to the _G.stackSpil set */
1474   addSetHead (&_G.stackSpil, sloc);
1475   sym->usl.spillLoc = sloc;
1476   sym->stackSpil = 1;
1477
1478   /* add it to the set of itempStack set 
1479      of the spill location */
1480   addSetHead (&sloc->usl.itmpStack, sym);
1481   return sym;
1482 }
1483
1484 /*-----------------------------------------------------------------*/
1485 /* isSpiltOnStack - returns true if the spil location is on stack  */
1486 /*-----------------------------------------------------------------*/
1487 static bool
1488 isSpiltOnStack (symbol * sym)
1489 {
1490   sym_link *etype;
1491
1492   debugLog ("%s\n", __FUNCTION__);
1493   if (!sym)
1494     return FALSE;
1495
1496   if (!sym->isspilt)
1497     return FALSE;
1498
1499 /*     if (sym->_G.stackSpil) */
1500 /*      return TRUE; */
1501
1502   if (!sym->usl.spillLoc)
1503     return FALSE;
1504
1505   etype = getSpec (sym->usl.spillLoc->type);
1506   if (IN_STACK (etype))
1507     return TRUE;
1508
1509   return FALSE;
1510 }
1511
1512 /*-----------------------------------------------------------------*/
1513 /* spillThis - spils a specific operand                            */
1514 /*-----------------------------------------------------------------*/
1515 static void
1516 spillThis (symbol * sym)
1517 {
1518   int i;
1519   debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1520
1521   /* if this is rematerializable or has a spillLocation
1522      we are okay, else we need to create a spillLocation
1523      for it */
1524   if (!(sym->remat || sym->usl.spillLoc))
1525     createStackSpil (sym);
1526
1527
1528   /* mark it has spilt & put it in the spilt set */
1529   sym->isspilt = 1;
1530   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1531
1532   bitVectUnSetBit (_G.regAssigned, sym->key);
1533
1534   for (i = 0; i < sym->nRegs; i++)
1535
1536     if (sym->regs[i])
1537       {
1538         freeReg (sym->regs[i]);
1539         sym->regs[i] = NULL;
1540       }
1541
1542   /* if spilt on stack then free up r0 & r1 
1543      if they could have been assigned to some
1544      LIVE ranges */
1545   if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1546     {
1547       pic16_ptrRegReq++;
1548       spillLRWithPtrReg (sym);
1549     }
1550
1551   if (sym->usl.spillLoc && !sym->remat)
1552     sym->usl.spillLoc->allocreq = 1;
1553   return;
1554 }
1555
1556 /*-----------------------------------------------------------------*/
1557 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1558 /*-----------------------------------------------------------------*/
1559 static symbol *
1560 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1561 {
1562   bitVect *lrcs = NULL;
1563   set *selectS;
1564   symbol *sym;
1565
1566   debugLog ("%s\n", __FUNCTION__);
1567   /* get the spillable live ranges */
1568   lrcs = computeSpillable (ic);
1569
1570   /* get all live ranges that are rematerizable */
1571   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1572     {
1573
1574       /* return the least used of these */
1575       return leastUsedLR (selectS);
1576     }
1577
1578   /* get live ranges with spillLocations in direct space */
1579   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1580     {
1581       sym = leastUsedLR (selectS);
1582       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1583                            sym->usl.spillLoc->rname :
1584                            sym->usl.spillLoc->name));
1585       sym->spildir = 1;
1586       /* mark it as allocation required */
1587       sym->usl.spillLoc->allocreq = 1;
1588       return sym;
1589     }
1590
1591   /* if the symbol is local to the block then */
1592   if (forSym->liveTo < ebp->lSeq)
1593     {
1594
1595       /* check if there are any live ranges allocated
1596          to registers that are not used in this block */
1597       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1598         {
1599           sym = leastUsedLR (selectS);
1600           /* if this is not rematerializable */
1601           if (!sym->remat)
1602             {
1603               _G.blockSpil++;
1604               sym->blockSpil = 1;
1605             }
1606           return sym;
1607         }
1608
1609       /* check if there are any live ranges that not
1610          used in the remainder of the block */
1611       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1612         {
1613           sym = leastUsedLR (selectS);
1614           if (!sym->remat)
1615             {
1616               sym->remainSpil = 1;
1617               _G.blockSpil++;
1618             }
1619           return sym;
1620         }
1621     }
1622
1623   /* find live ranges with spillocation && not used as pointers */
1624   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1625     {
1626
1627       sym = leastUsedLR (selectS);
1628       /* mark this as allocation required */
1629       sym->usl.spillLoc->allocreq = 1;
1630       return sym;
1631     }
1632
1633   /* find live ranges with spillocation */
1634   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1635     {
1636
1637       sym = leastUsedLR (selectS);
1638       sym->usl.spillLoc->allocreq = 1;
1639       return sym;
1640     }
1641
1642   /* couldn't find then we need to create a spil
1643      location on the stack , for which one? the least
1644      used ofcourse */
1645   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1646     {
1647
1648       /* return a created spil location */
1649       sym = createStackSpil (leastUsedLR (selectS));
1650       sym->usl.spillLoc->allocreq = 1;
1651       return sym;
1652     }
1653
1654   /* this is an extreme situation we will spill
1655      this one : happens very rarely but it does happen */
1656   spillThis (forSym);
1657   return forSym;
1658
1659 }
1660
1661 /*-----------------------------------------------------------------*/
1662 /* spilSomething - spil some variable & mark registers as free     */
1663 /*-----------------------------------------------------------------*/
1664 static bool
1665 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1666 {
1667   symbol *ssym;
1668   int i;
1669
1670   debugLog ("%s\n", __FUNCTION__);
1671   /* get something we can spil */
1672   ssym = selectSpil (ic, ebp, forSym);
1673
1674   /* mark it as spilt */
1675   ssym->isspilt = 1;
1676   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1677
1678   /* mark it as not register assigned &
1679      take it away from the set */
1680   bitVectUnSetBit (_G.regAssigned, ssym->key);
1681
1682   /* mark the registers as free */
1683   for (i = 0; i < ssym->nRegs; i++)
1684     if (ssym->regs[i])
1685       freeReg (ssym->regs[i]);
1686
1687   /* if spilt on stack then free up r0 & r1 
1688      if they could have been assigned to as gprs */
1689   if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1690     {
1691       pic16_ptrRegReq++;
1692       spillLRWithPtrReg (ssym);
1693     }
1694
1695   /* if this was a block level spil then insert push & pop 
1696      at the start & end of block respectively */
1697   if (ssym->blockSpil)
1698     {
1699       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1700       /* add push to the start of the block */
1701       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1702                                     ebp->sch->next : ebp->sch));
1703       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1704       /* add pop to the end of the block */
1705       addiCodeToeBBlock (ebp, nic, NULL);
1706     }
1707
1708   /* if spilt because not used in the remainder of the
1709      block then add a push before this instruction and
1710      a pop at the end of the block */
1711   if (ssym->remainSpil)
1712     {
1713
1714       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1715       /* add push just before this instruction */
1716       addiCodeToeBBlock (ebp, nic, ic);
1717
1718       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1719       /* add pop to the end of the block */
1720       addiCodeToeBBlock (ebp, nic, NULL);
1721     }
1722
1723   if (ssym == forSym)
1724     return FALSE;
1725   else
1726     return TRUE;
1727 }
1728
1729 /*-----------------------------------------------------------------*/
1730 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1731 /*-----------------------------------------------------------------*/
1732 static regs *
1733 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1734 {
1735   regs *reg;
1736
1737   debugLog ("%s\n", __FUNCTION__);
1738 tryAgain:
1739   /* try for a ptr type */
1740   if ((reg = allocReg (REG_PTR)))
1741     return reg;
1742
1743   /* try for gpr type */
1744   if ((reg = allocReg (REG_GPR)))
1745     return reg;
1746
1747   /* we have to spil */
1748   if (!spilSomething (ic, ebp, sym))
1749     return NULL;
1750
1751   /* this looks like an infinite loop but 
1752      in really selectSpil will abort  */
1753   goto tryAgain;
1754 }
1755
1756 /*-----------------------------------------------------------------*/
1757 /* getRegGpr - will try for GPR if not spil                        */
1758 /*-----------------------------------------------------------------*/
1759 static regs *
1760 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1761 {
1762   regs *reg;
1763
1764   debugLog ("%s\n", __FUNCTION__);
1765 tryAgain:
1766   /* try for gpr type */
1767   if ((reg = allocReg (REG_GPR)))
1768     return reg;
1769
1770   if (!pic16_ptrRegReq)
1771     if ((reg = allocReg (REG_PTR)))
1772       return reg;
1773
1774   /* we have to spil */
1775   if (!spilSomething (ic, ebp, sym))
1776     return NULL;
1777
1778   /* this looks like an infinite loop but 
1779      in really selectSpil will abort  */
1780   goto tryAgain;
1781 }
1782
1783 /*-----------------------------------------------------------------*/
1784 /* symHasReg - symbol has a given register                         */
1785 /*-----------------------------------------------------------------*/
1786 static bool
1787 symHasReg (symbol * sym, regs * reg)
1788 {
1789   int i;
1790
1791   debugLog ("%s\n", __FUNCTION__);
1792   for (i = 0; i < sym->nRegs; i++)
1793     if (sym->regs[i] == reg)
1794       return TRUE;
1795
1796   return FALSE;
1797 }
1798
1799 /*-----------------------------------------------------------------*/
1800 /* deassignLRs - check the live to and if they have registers & are */
1801 /*               not spilt then free up the registers              */
1802 /*-----------------------------------------------------------------*/
1803 static void
1804 deassignLRs (iCode * ic, eBBlock * ebp)
1805 {
1806   symbol *sym;
1807   int k;
1808   symbol *result;
1809
1810   debugLog ("%s\n", __FUNCTION__);
1811   for (sym = hTabFirstItem (liveRanges, &k); sym;
1812        sym = hTabNextItem (liveRanges, &k))
1813     {
1814
1815       symbol *psym = NULL;
1816       /* if it does not end here */
1817       if (sym->liveTo > ic->seq)
1818         continue;
1819
1820       /* if it was spilt on stack then we can 
1821          mark the stack spil location as free */
1822       if (sym->isspilt)
1823         {
1824           if (sym->stackSpil)
1825             {
1826               sym->usl.spillLoc->isFree = 1;
1827               sym->stackSpil = 0;
1828             }
1829           continue;
1830         }
1831
1832       if (!bitVectBitValue (_G.regAssigned, sym->key))
1833         continue;
1834
1835       /* special case check if this is an IFX &
1836          the privious one was a pop and the 
1837          previous one was not spilt then keep track
1838          of the symbol */
1839       if (ic->op == IFX && ic->prev &&
1840           ic->prev->op == IPOP &&
1841           !ic->prev->parmPush &&
1842           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1843         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1844
1845       if (sym->nRegs)
1846         {
1847           int i = 0;
1848
1849           bitVectUnSetBit (_G.regAssigned, sym->key);
1850
1851           /* if the result of this one needs registers
1852              and does not have it then assign it right
1853              away */
1854           if (IC_RESULT (ic) &&
1855               !(SKIP_IC2 (ic) ||        /* not a special icode */
1856                 ic->op == JUMPTABLE ||
1857                 ic->op == IFX ||
1858                 ic->op == IPUSH ||
1859                 ic->op == IPOP ||
1860                 ic->op == RETURN ||
1861                 POINTER_SET (ic)) &&
1862               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1863               result->liveTo > ic->seq &&       /* and will live beyond this */
1864               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1865               result->regType == sym->regType &&        /* same register types */
1866               result->nRegs &&  /* which needs registers */
1867               !result->isspilt &&       /* and does not already have them */
1868               !result->remat &&
1869               !bitVectBitValue (_G.regAssigned, result->key) &&
1870           /* the number of free regs + number of regs in this LR
1871              can accomodate the what result Needs */
1872               ((nfreeRegsType (result->regType) +
1873                 sym->nRegs) >= result->nRegs)
1874             )
1875             {
1876
1877               for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1878                 if (i < sym->nRegs)
1879                   result->regs[i] = sym->regs[i];
1880                 else
1881                   result->regs[i] = getRegGpr (ic, ebp, result);
1882
1883               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1884
1885             }
1886
1887           /* free the remaining */
1888           for (; i < sym->nRegs; i++)
1889             {
1890               if (psym)
1891                 {
1892                   if (!symHasReg (psym, sym->regs[i]))
1893                     freeReg (sym->regs[i]);
1894                 }
1895               else
1896                 freeReg (sym->regs[i]);
1897             }
1898         }
1899     }
1900 }
1901
1902
1903 /*-----------------------------------------------------------------*/
1904 /* reassignLR - reassign this to registers                         */
1905 /*-----------------------------------------------------------------*/
1906 static void
1907 reassignLR (operand * op)
1908 {
1909   symbol *sym = OP_SYMBOL (op);
1910   int i;
1911
1912   debugLog ("%s\n", __FUNCTION__);
1913   /* not spilt any more */
1914   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1915   bitVectUnSetBit (_G.spiltSet, sym->key);
1916
1917   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1918
1919   _G.blockSpil--;
1920
1921   for (i = 0; i < sym->nRegs; i++)
1922     sym->regs[i]->isFree = 0;
1923 }
1924
1925 /*-----------------------------------------------------------------*/
1926 /* willCauseSpill - determines if allocating will cause a spill    */
1927 /*-----------------------------------------------------------------*/
1928 static int
1929 willCauseSpill (int nr, int rt)
1930 {
1931   debugLog ("%s\n", __FUNCTION__);
1932   /* first check if there are any avlb registers
1933      of te type required */
1934   if (rt == REG_PTR)
1935     {
1936       /* special case for pointer type 
1937          if pointer type not avlb then 
1938          check for type gpr */
1939       if (nFreeRegs (rt) >= nr)
1940         return 0;
1941       if (nFreeRegs (REG_GPR) >= nr)
1942         return 0;
1943     }
1944   else
1945     {
1946       if (pic16_ptrRegReq)
1947         {
1948           if (nFreeRegs (rt) >= nr)
1949             return 0;
1950         }
1951       else
1952         {
1953           if (nFreeRegs (REG_PTR) +
1954               nFreeRegs (REG_GPR) >= nr)
1955             return 0;
1956         }
1957     }
1958
1959   debugLog (" ... yep it will (cause a spill)\n");
1960   /* it will cause a spil */
1961   return 1;
1962 }
1963
1964 /*-----------------------------------------------------------------*/
1965 /* positionRegs - the allocator can allocate same registers to res- */
1966 /* ult and operand, if this happens make sure they are in the same */
1967 /* position as the operand otherwise chaos results                 */
1968 /*-----------------------------------------------------------------*/
1969 static void
1970 positionRegs (symbol * result, symbol * opsym, int lineno)
1971 {
1972   int count = min (result->nRegs, opsym->nRegs);
1973   int i, j = 0, shared = 0;
1974
1975   debugLog ("%s\n", __FUNCTION__);
1976   /* if the result has been spilt then cannot share */
1977   if (opsym->isspilt)
1978     return;
1979 again:
1980   shared = 0;
1981   /* first make sure that they actually share */
1982   for (i = 0; i < count; i++)
1983     {
1984       for (j = 0; j < count; j++)
1985         {
1986           if (result->regs[i] == opsym->regs[j] && i != j)
1987             {
1988               shared = 1;
1989               goto xchgPositions;
1990             }
1991         }
1992     }
1993 xchgPositions:
1994   if (shared)
1995     {
1996       regs *tmp = result->regs[i];
1997       result->regs[i] = result->regs[j];
1998       result->regs[j] = tmp;
1999       goto again;
2000     }
2001 }
2002
2003 /*-----------------------------------------------------------------*/
2004 /* serialRegAssign - serially allocate registers to the variables  */
2005 /*-----------------------------------------------------------------*/
2006 static void
2007 serialRegAssign (eBBlock ** ebbs, int count)
2008 {
2009   int i;
2010
2011   debugLog ("%s\n", __FUNCTION__);
2012   /* for all blocks */
2013   for (i = 0; i < count; i++)
2014     {
2015
2016       iCode *ic;
2017
2018       if (ebbs[i]->noPath &&
2019           (ebbs[i]->entryLabel != entryLabel &&
2020            ebbs[i]->entryLabel != returnLabel))
2021         continue;
2022
2023       /* of all instructions do */
2024       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2025         {
2026
2027           debugLog ("  op: %s\n", decodeOp (ic->op));
2028
2029           /* if this is an ipop that means some live
2030              range will have to be assigned again */
2031           if (ic->op == IPOP)
2032             reassignLR (IC_LEFT (ic));
2033
2034           /* if result is present && is a true symbol */
2035           if (IC_RESULT (ic) && ic->op != IFX &&
2036               IS_TRUE_SYMOP (IC_RESULT (ic)))
2037             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2038
2039           /* take away registers from live
2040              ranges that end at this instruction */
2041           deassignLRs (ic, ebbs[i]);
2042
2043           /* some don't need registers */
2044           if (SKIP_IC2 (ic) ||
2045               ic->op == JUMPTABLE ||
2046               ic->op == IFX ||
2047               ic->op == IPUSH ||
2048               ic->op == IPOP ||
2049               (IC_RESULT (ic) && POINTER_SET (ic)))
2050             continue;
2051
2052           /* now we need to allocate registers
2053              only for the result */
2054           if (IC_RESULT (ic))
2055             {
2056               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2057               bitVect *spillable;
2058               int willCS;
2059               int j;
2060               int ptrRegSet = 0;
2061
2062               /* if it does not need or is spilt 
2063                  or is already assigned to registers
2064                  or will not live beyond this instructions */
2065               if (!sym->nRegs ||
2066                   sym->isspilt ||
2067                   bitVectBitValue (_G.regAssigned, sym->key) ||
2068                   sym->liveTo <= ic->seq)
2069                 continue;
2070
2071               /* if some liverange has been spilt at the block level
2072                  and this one live beyond this block then spil this
2073                  to be safe */
2074               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2075                 {
2076                   spillThis (sym);
2077                   continue;
2078                 }
2079               /* if trying to allocate this will cause
2080                  a spill and there is nothing to spill 
2081                  or this one is rematerializable then
2082                  spill this one */
2083               willCS = willCauseSpill (sym->nRegs, sym->regType);
2084               spillable = computeSpillable (ic);
2085               if (sym->remat ||
2086                   (willCS && bitVectIsZero (spillable)))
2087                 {
2088
2089                   spillThis (sym);
2090                   continue;
2091
2092                 }
2093
2094               /* if it has a spillocation & is used less than
2095                  all other live ranges then spill this */
2096                 if (willCS) {
2097                     if (sym->usl.spillLoc) {
2098                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2099                                                                          allLRs, ebbs[i], ic));
2100                         if (leastUsed && leastUsed->used > sym->used) {
2101                             spillThis (sym);
2102                             continue;
2103                         }
2104                     } else {
2105                         /* if none of the liveRanges have a spillLocation then better
2106                            to spill this one than anything else already assigned to registers */
2107                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2108                             /* if this is local to this block then we might find a block spil */
2109                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2110                                 spillThis (sym);
2111                                 continue;
2112                             }
2113                         }
2114                     }
2115                 }
2116
2117               if (ic->op == RECEIVE)
2118                 debugLog ("When I get clever, I'll optimize the receive logic\n");
2119
2120               /* if we need ptr regs for the right side
2121                  then mark it */
2122               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2123                   <= (unsigned) PTRSIZE)
2124                 {
2125                   pic16_ptrRegReq++;
2126                   ptrRegSet = 1;
2127                 }
2128               /* else we assign registers to it */
2129               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2130
2131               debugLog ("  %d - \n", __LINE__);
2132               if(debugF) 
2133                 bitVectDebugOn(_G.regAssigned, debugF);
2134
2135               for (j = 0; j < sym->nRegs; j++)
2136                 {
2137                   if (sym->regType == REG_PTR)
2138                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2139                   else
2140                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2141
2142                   /* if the allocation falied which means
2143                      this was spilt then break */
2144                   if (!sym->regs[j])
2145                     break;
2146                 }
2147               debugLog ("  %d - \n", __LINE__);
2148
2149               /* if it shares registers with operands make sure
2150                  that they are in the same position */
2151               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2152                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2153                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2154                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2155               /* do the same for the right operand */
2156               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2157                   OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2158                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2159                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2160
2161               debugLog ("  %d - \n", __LINE__);
2162               if (ptrRegSet)
2163                 {
2164                   debugLog ("  %d - \n", __LINE__);
2165                   pic16_ptrRegReq--;
2166                   ptrRegSet = 0;
2167                 }
2168
2169             }
2170         }
2171     }
2172 }
2173
2174 /*-----------------------------------------------------------------*/
2175 /* rUmaskForOp :- returns register mask for an operand             */
2176 /*-----------------------------------------------------------------*/
2177 static bitVect *
2178 rUmaskForOp (operand * op)
2179 {
2180   bitVect *rumask;
2181   symbol *sym;
2182   int j;
2183
2184   debugLog ("%s\n", __FUNCTION__);
2185   /* only temporaries are assigned registers */
2186   if (!IS_ITEMP (op))
2187     return NULL;
2188
2189   sym = OP_SYMBOL (op);
2190
2191   /* if spilt or no registers assigned to it
2192      then nothing */
2193   if (sym->isspilt || !sym->nRegs)
2194     return NULL;
2195
2196   rumask = newBitVect (pic16_nRegs);
2197
2198   for (j = 0; j < sym->nRegs; j++)
2199     {
2200       rumask = bitVectSetBit (rumask,
2201                               sym->regs[j]->rIdx);
2202     }
2203
2204   return rumask;
2205 }
2206
2207 /*-----------------------------------------------------------------*/
2208 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2209 /*-----------------------------------------------------------------*/
2210 static bitVect *
2211 regsUsedIniCode (iCode * ic)
2212 {
2213   bitVect *rmask = newBitVect (pic16_nRegs);
2214
2215   debugLog ("%s\n", __FUNCTION__);
2216   /* do the special cases first */
2217   if (ic->op == IFX)
2218     {
2219       rmask = bitVectUnion (rmask,
2220                             rUmaskForOp (IC_COND (ic)));
2221       goto ret;
2222     }
2223
2224   /* for the jumptable */
2225   if (ic->op == JUMPTABLE)
2226     {
2227       rmask = bitVectUnion (rmask,
2228                             rUmaskForOp (IC_JTCOND (ic)));
2229
2230       goto ret;
2231     }
2232
2233   /* of all other cases */
2234   if (IC_LEFT (ic))
2235     rmask = bitVectUnion (rmask,
2236                           rUmaskForOp (IC_LEFT (ic)));
2237
2238
2239   if (IC_RIGHT (ic))
2240     rmask = bitVectUnion (rmask,
2241                           rUmaskForOp (IC_RIGHT (ic)));
2242
2243   if (IC_RESULT (ic))
2244     rmask = bitVectUnion (rmask,
2245                           rUmaskForOp (IC_RESULT (ic)));
2246
2247 ret:
2248   return rmask;
2249 }
2250
2251 /*-----------------------------------------------------------------*/
2252 /* createRegMask - for each instruction will determine the regsUsed */
2253 /*-----------------------------------------------------------------*/
2254 static void
2255 createRegMask (eBBlock ** ebbs, int count)
2256 {
2257   int i;
2258
2259   debugLog ("%s\n", __FUNCTION__);
2260   /* for all blocks */
2261   for (i = 0; i < count; i++)
2262     {
2263       iCode *ic;
2264
2265       if (ebbs[i]->noPath &&
2266           (ebbs[i]->entryLabel != entryLabel &&
2267            ebbs[i]->entryLabel != returnLabel))
2268         continue;
2269
2270       /* for all instructions */
2271       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2272         {
2273
2274           int j;
2275
2276           if (SKIP_IC2 (ic) || !ic->rlive)
2277             continue;
2278
2279           /* first mark the registers used in this
2280              instruction */
2281           ic->rUsed = regsUsedIniCode (ic);
2282           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2283
2284           /* now create the register mask for those 
2285              registers that are in use : this is a
2286              super set of ic->rUsed */
2287           ic->rMask = newBitVect (pic16_nRegs + 1);
2288
2289           /* for all live Ranges alive at this point */
2290           for (j = 1; j < ic->rlive->size; j++)
2291             {
2292               symbol *sym;
2293               int k;
2294
2295               /* if not alive then continue */
2296               if (!bitVectBitValue (ic->rlive, j))
2297                 continue;
2298
2299               /* find the live range we are interested in */
2300               if (!(sym = hTabItemWithKey (liveRanges, j)))
2301                 {
2302                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2303                           "createRegMask cannot find live range");
2304                   exit (0);
2305                 }
2306
2307               /* if no register assigned to it */
2308               if (!sym->nRegs || sym->isspilt)
2309                 continue;
2310
2311               /* for all the registers allocated to it */
2312               for (k = 0; k < sym->nRegs; k++)
2313                 if (sym->regs[k])
2314                   ic->rMask =
2315                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2316             }
2317         }
2318     }
2319 }
2320
2321 /*-----------------------------------------------------------------*/
2322 /* rematStr - returns the rematerialized string for a remat var    */
2323 /*-----------------------------------------------------------------*/
2324 static symbol *
2325 rematStr (symbol * sym)
2326 {
2327   char *s = buffer;
2328   iCode *ic = sym->rematiCode;
2329   symbol *psym = NULL;
2330
2331   debugLog ("%s\n", __FUNCTION__);
2332
2333   //printf ("%s\n", s);
2334
2335   /* if plus or minus print the right hand side */
2336
2337   if (ic->op == '+' || ic->op == '-') {
2338         
2339     iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2340
2341     sprintf (s, "(%s %c 0x%04x)",
2342              OP_SYMBOL (IC_LEFT (ric))->rname,
2343              ic->op,
2344              (int) operandLitValue (IC_RIGHT (ic)));
2345
2346
2347     //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2348
2349     psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2350     psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2351
2352     return psym;
2353   }
2354
2355   sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2356   psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2357
2358   //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2359   return psym;
2360 }
2361
2362 #if 0
2363 /*-----------------------------------------------------------------*/
2364 /* rematStr - returns the rematerialized string for a remat var    */
2365 /*-----------------------------------------------------------------*/
2366 static char *
2367 rematStr (symbol * sym)
2368 {
2369   char *s = buffer;
2370   iCode *ic = sym->rematiCode;
2371
2372   debugLog ("%s\n", __FUNCTION__);
2373   while (1)
2374     {
2375
2376       printf ("%s\n", s);
2377       /* if plus or minus print the right hand side */
2378 /*
2379    if (ic->op == '+' || ic->op == '-') {
2380    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2381    ic->op );
2382    s += strlen(s);
2383    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2384    continue ;
2385    }
2386  */
2387       if (ic->op == '+' || ic->op == '-')
2388         {
2389           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2390           sprintf (s, "(%s %c 0x%04x)",
2391                    OP_SYMBOL (IC_LEFT (ric))->rname,
2392                    ic->op,
2393                    (int) operandLitValue (IC_RIGHT (ic)));
2394
2395           //s += strlen(s);
2396           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2397           //continue ;
2398           //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2399           return buffer;
2400         }
2401
2402       /* we reached the end */
2403       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2404       break;
2405     }
2406
2407   printf ("%s\n", buffer);
2408   return buffer;
2409 }
2410 #endif
2411
2412 /*-----------------------------------------------------------------*/
2413 /* regTypeNum - computes the type & number of registers required   */
2414 /*-----------------------------------------------------------------*/
2415 static void
2416 regTypeNum ()
2417 {
2418   symbol *sym;
2419   int k;
2420   iCode *ic;
2421
2422   debugLog ("%s\n", __FUNCTION__);
2423   /* for each live range do */
2424   for (sym = hTabFirstItem (liveRanges, &k); sym;
2425        sym = hTabNextItem (liveRanges, &k)) {
2426
2427     debugLog ("  %d - %s\n", __LINE__, sym->rname);
2428
2429     /* if used zero times then no registers needed */
2430     if ((sym->liveTo - sym->liveFrom) == 0)
2431       continue;
2432
2433
2434     /* if the live range is a temporary */
2435     if (sym->isitmp) {
2436
2437       debugLog ("  %d - itemp register\n", __LINE__);
2438
2439       /* if the type is marked as a conditional */
2440       if (sym->regType == REG_CND)
2441         continue;
2442
2443       /* if used in return only then we don't 
2444          need registers */
2445       if (sym->ruonly || sym->accuse) {
2446         if (IS_AGGREGATE (sym->type) || sym->isptr)
2447           sym->type = aggrToPtr (sym->type, FALSE);
2448         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
2449
2450         continue;
2451       }
2452
2453       /* if the symbol has only one definition &
2454          that definition is a get_pointer and the
2455          pointer we are getting is rematerializable and
2456          in "data" space */
2457
2458       if (bitVectnBitsOn (sym->defs) == 1 &&
2459           (ic = hTabItemWithKey (iCodehTab,
2460                                  bitVectFirstBit (sym->defs))) &&
2461           POINTER_GET (ic) &&
2462           !sym->noSpilLoc &&
2463           !IS_BITVAR (sym->etype)) {
2464         
2465
2466         debugLog ("  %d - \n", __LINE__);
2467
2468         /* if remat in data space */
2469         if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2470             DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2471
2472           /* create a psuedo symbol & force a spil */
2473           //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2474           symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2475           psym->type = sym->type;
2476           psym->etype = sym->etype;
2477           strcpy (psym->rname, psym->name);
2478           sym->isspilt = 1;
2479           sym->usl.spillLoc = psym;
2480           continue;
2481         }
2482
2483         /* if in data space or idata space then try to
2484            allocate pointer register */
2485
2486       }
2487
2488       /* if not then we require registers */
2489       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2490                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2491                     getSize (sym->type));
2492
2493
2494     if(IS_PTR_CONST (sym->type)) {
2495       debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2496       sym->nRegs = 2;
2497     }
2498
2499       if (sym->nRegs > 4) {
2500         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2501         printTypeChain (sym->type, stderr);
2502         fprintf (stderr, "\n");
2503       }
2504
2505       /* determine the type of register required */
2506       if (sym->nRegs == 1 &&
2507           IS_PTR (sym->type) &&
2508           sym->uptr)
2509         sym->regType = REG_PTR;
2510       else
2511         sym->regType = REG_GPR;
2512
2513
2514       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2515
2516     }
2517     else
2518       /* for the first run we don't provide */
2519       /* registers for true symbols we will */
2520       /* see how things go                  */
2521       sym->nRegs = 0;
2522   }
2523
2524 }
2525 static DEFSETFUNC (markRegFree)
2526 {
2527   ((regs *)item)->isFree = 1;
2528
2529   return 0;
2530 }
2531
2532 DEFSETFUNC (pic16_deallocReg)
2533 {
2534   fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2535   ((regs *)item)->isFree = 1;
2536   ((regs *)item)->wasUsed = 0;
2537
2538   return 0;
2539 }
2540 /*-----------------------------------------------------------------*/
2541 /* freeAllRegs - mark all registers as free                        */
2542 /*-----------------------------------------------------------------*/
2543 void
2544 pic16_freeAllRegs ()
2545 {
2546   //  int i;
2547
2548   debugLog ("%s\n", __FUNCTION__);
2549
2550   applyToSet(pic16_dynAllocRegs,markRegFree);
2551   applyToSet(pic16_dynStackRegs,markRegFree);
2552
2553 /*
2554   for (i = 0; i < pic16_nRegs; i++)
2555     regspic16[i].isFree = 1;
2556 */
2557 }
2558
2559 /*-----------------------------------------------------------------*/
2560 /*-----------------------------------------------------------------*/
2561 void
2562 pic16_deallocateAllRegs ()
2563 {
2564   //  int i;
2565
2566   debugLog ("%s\n", __FUNCTION__);
2567
2568   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2569
2570 /*
2571   for (i = 0; i < pic16_nRegs; i++) {
2572     if(regspic16[i].pc_type == PO_GPR_TEMP) {
2573       regspic16[i].isFree = 1;
2574       regspic16[i].wasUsed = 0;
2575     }
2576   }
2577 */
2578 }
2579
2580
2581 /*-----------------------------------------------------------------*/
2582 /* deallocStackSpil - this will set the stack pointer back         */
2583 /*-----------------------------------------------------------------*/
2584 static
2585 DEFSETFUNC (deallocStackSpil)
2586 {
2587   symbol *sym = item;
2588
2589   debugLog ("%s\n", __FUNCTION__);
2590   deallocLocal (sym);
2591   return 0;
2592 }
2593
2594 /*-----------------------------------------------------------------*/
2595 /* farSpacePackable - returns the packable icode for far variables */
2596 /*-----------------------------------------------------------------*/
2597 static iCode *
2598 farSpacePackable (iCode * ic)
2599 {
2600   iCode *dic;
2601
2602   debugLog ("%s\n", __FUNCTION__);
2603   /* go thru till we find a definition for the
2604      symbol on the right */
2605   for (dic = ic->prev; dic; dic = dic->prev)
2606     {
2607
2608       /* if the definition is a call then no */
2609       if ((dic->op == CALL || dic->op == PCALL) &&
2610           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2611         {
2612           return NULL;
2613         }
2614
2615       /* if shift by unknown amount then not */
2616       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2617           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2618         return NULL;
2619
2620       /* if pointer get and size > 1 */
2621       if (POINTER_GET (dic) &&
2622           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2623         return NULL;
2624
2625       if (POINTER_SET (dic) &&
2626           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2627         return NULL;
2628
2629       /* if any three is a true symbol in far space */
2630       if (IC_RESULT (dic) &&
2631           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2632           isOperandInFarSpace (IC_RESULT (dic)))
2633         return NULL;
2634
2635       if (IC_RIGHT (dic) &&
2636           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2637           isOperandInFarSpace (IC_RIGHT (dic)) &&
2638           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2639         return NULL;
2640
2641       if (IC_LEFT (dic) &&
2642           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2643           isOperandInFarSpace (IC_LEFT (dic)) &&
2644           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2645         return NULL;
2646
2647       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2648         {
2649           if ((dic->op == LEFT_OP ||
2650                dic->op == RIGHT_OP ||
2651                dic->op == '-') &&
2652               IS_OP_LITERAL (IC_RIGHT (dic)))
2653             return NULL;
2654           else
2655             return dic;
2656         }
2657     }
2658
2659   return NULL;
2660 }
2661
2662 /*-----------------------------------------------------------------*/
2663 /* packRegsForAssign - register reduction for assignment           */
2664 /*-----------------------------------------------------------------*/
2665 static int
2666 packRegsForAssign (iCode * ic, eBBlock * ebp)
2667 {
2668
2669   iCode *dic, *sic;
2670
2671   debugLog ("%s\n", __FUNCTION__);
2672
2673   debugAopGet ("  result:", IC_RESULT (ic));
2674   debugAopGet ("  left:", IC_LEFT (ic));
2675   debugAopGet ("  right:", IC_RIGHT (ic));
2676
2677   /* if this is at an absolute address, then get the address. */
2678   if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2679     if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2680       debugLog ("  %d - found config word declaration\n", __LINE__);
2681       if(IS_VALOP(IC_RIGHT(ic))) {
2682         debugLog ("  setting config word to %x\n", 
2683                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2684         pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2685                                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2686       }
2687
2688       /* remove the assignment from the iCode chain. */
2689
2690       remiCodeFromeBBlock (ebp, ic);
2691       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2692       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2693
2694       return 1;
2695
2696     }
2697   }
2698
2699   if (!IS_ITEMP (IC_RESULT (ic))) {
2700     pic16_allocDirReg(IC_RESULT (ic));
2701     debugLog ("  %d - result is not temp\n", __LINE__);
2702   }
2703 /*
2704   if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2705     debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2706     pic16_allocDirReg(IC_LEFT (ic));
2707   }
2708 */
2709
2710   if (!IS_ITEMP (IC_RIGHT (ic))) {
2711     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2712     pic16_allocDirReg(IC_RIGHT (ic));
2713     return 0;
2714   }
2715
2716   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2717       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2718     {
2719       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2720       return 0;
2721     }
2722
2723   /* if the true symbol is defined in far space or on stack
2724      then we should not since this will increase register pressure */
2725   if (isOperandInFarSpace (IC_RESULT (ic)))
2726     {
2727       if ((dic = farSpacePackable (ic)))
2728         goto pack;
2729       else
2730         return 0;
2731
2732     }
2733   /* find the definition of iTempNN scanning backwards if we find a 
2734      a use of the true symbol before we find the definition then 
2735      we cannot pack */
2736   for (dic = ic->prev; dic; dic = dic->prev)
2737     {
2738
2739       /* if there is a function call and this is
2740          a parameter & not my parameter then don't pack it */
2741       if ((dic->op == CALL || dic->op == PCALL) &&
2742           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2743            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2744         {
2745           debugLog ("  %d - \n", __LINE__);
2746           dic = NULL;
2747           break;
2748         }
2749
2750       if (SKIP_IC2 (dic))
2751         continue;
2752
2753       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2754           IS_OP_VOLATILE (IC_RESULT (dic)))
2755         {
2756           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2757           dic = NULL;
2758           break;
2759         }
2760
2761       if (IS_SYMOP (IC_RESULT (dic)) &&
2762           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2763         {
2764           /* A previous result was assigned to the same register - we'll our definition */
2765           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2766                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2767           if (POINTER_SET (dic))
2768             dic = NULL;
2769
2770           break;
2771         }
2772
2773       if (IS_SYMOP (IC_RIGHT (dic)) &&
2774           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2775            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2776         {
2777           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2778           dic = NULL;
2779           break;
2780         }
2781
2782       if (IS_SYMOP (IC_LEFT (dic)) &&
2783           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2784            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2785         {
2786           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2787           dic = NULL;
2788           break;
2789         }
2790
2791       if (POINTER_SET (dic) &&
2792           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2793         {
2794           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2795                     __LINE__);
2796           dic = NULL;
2797           break;
2798         }
2799     }
2800
2801   if (!dic)
2802     return 0;                   /* did not find */
2803
2804   /* if the result is on stack or iaccess then it must be
2805      the same atleast one of the operands */
2806   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2807       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2808     {
2809
2810       /* the operation has only one symbol
2811          operator then we can pack */
2812       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2813           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2814         goto pack;
2815
2816       if (!((IC_LEFT (dic) &&
2817              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2818             (IC_RIGHT (dic) &&
2819              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2820         return 0;
2821     }
2822 pack:
2823   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2824   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2825   /* found the definition */
2826   /* replace the result with the result of */
2827   /* this assignment and remove this assignment */
2828   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2829   IC_RESULT (dic) = IC_RESULT (ic);
2830
2831   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2832     {
2833       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2834     }
2835   /* delete from liverange table also 
2836      delete from all the points inbetween and the new
2837      one */
2838   for (sic = dic; sic != ic; sic = sic->next)
2839     {
2840       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2841       if (IS_ITEMP (IC_RESULT (dic)))
2842         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2843     }
2844
2845   remiCodeFromeBBlock (ebp, ic);
2846   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2847   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2848   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2849   return 1;
2850
2851
2852 }
2853
2854 /*-----------------------------------------------------------------*/
2855 /* findAssignToSym : scanning backwards looks for first assig found */
2856 /*-----------------------------------------------------------------*/
2857 static iCode *
2858 findAssignToSym (operand * op, iCode * ic)
2859 {
2860   iCode *dic;
2861
2862   debugLog ("%s\n", __FUNCTION__);
2863   for (dic = ic->prev; dic; dic = dic->prev)
2864     {
2865
2866       /* if definition by assignment */
2867       if (dic->op == '=' &&
2868           !POINTER_SET (dic) &&
2869           IC_RESULT (dic)->key == op->key
2870 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2871         )
2872         {
2873
2874           /* we are interested only if defined in far space */
2875           /* or in stack space in case of + & - */
2876
2877           /* if assigned to a non-symbol then return
2878              true */
2879           if (!IS_SYMOP (IC_RIGHT (dic)))
2880             break;
2881
2882           /* if the symbol is in far space then
2883              we should not */
2884           if (isOperandInFarSpace (IC_RIGHT (dic)))
2885             return NULL;
2886
2887           /* for + & - operations make sure that
2888              if it is on the stack it is the same
2889              as one of the three operands */
2890           if ((ic->op == '+' || ic->op == '-') &&
2891               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2892             {
2893
2894               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2895                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2896                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2897                 return NULL;
2898             }
2899
2900           break;
2901
2902         }
2903
2904       /* if we find an usage then we cannot delete it */
2905       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2906         return NULL;
2907
2908       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2909         return NULL;
2910
2911       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2912         return NULL;
2913     }
2914
2915   /* now make sure that the right side of dic
2916      is not defined between ic & dic */
2917   if (dic)
2918     {
2919       iCode *sic = dic->next;
2920
2921       for (; sic != ic; sic = sic->next)
2922         if (IC_RESULT (sic) &&
2923             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2924           return NULL;
2925     }
2926
2927   return dic;
2928
2929
2930 }
2931
2932 /*-----------------------------------------------------------------*/
2933 /* packRegsForSupport :- reduce some registers for support calls   */
2934 /*-----------------------------------------------------------------*/
2935 static int
2936 packRegsForSupport (iCode * ic, eBBlock * ebp)
2937 {
2938   int change = 0;
2939
2940   debugLog ("%s\n", __FUNCTION__);
2941   /* for the left & right operand :- look to see if the
2942      left was assigned a true symbol in far space in that
2943      case replace them */
2944   if (IS_ITEMP (IC_LEFT (ic)) &&
2945       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2946     {
2947       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2948       iCode *sic;
2949
2950       if (!dic)
2951         goto right;
2952
2953       debugAopGet ("removing left:", IC_LEFT (ic));
2954
2955       /* found it we need to remove it from the
2956          block */
2957       for (sic = dic; sic != ic; sic = sic->next)
2958         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2959
2960       IC_LEFT (ic)->operand.symOperand =
2961         IC_RIGHT (dic)->operand.symOperand;
2962       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2963       remiCodeFromeBBlock (ebp, dic);
2964       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2965       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2966       change++;
2967     }
2968
2969   /* do the same for the right operand */
2970 right:
2971   if (!change &&
2972       IS_ITEMP (IC_RIGHT (ic)) &&
2973       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2974     {
2975       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2976       iCode *sic;
2977
2978       if (!dic)
2979         return change;
2980
2981       /* if this is a subtraction & the result
2982          is a true symbol in far space then don't pack */
2983       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2984         {
2985           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2986           if (IN_FARSPACE (SPEC_OCLS (etype)))
2987             return change;
2988         }
2989
2990       debugAopGet ("removing right:", IC_RIGHT (ic));
2991
2992       /* found it we need to remove it from the
2993          block */
2994       for (sic = dic; sic != ic; sic = sic->next)
2995         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2996
2997       IC_RIGHT (ic)->operand.symOperand =
2998         IC_RIGHT (dic)->operand.symOperand;
2999       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3000
3001       remiCodeFromeBBlock (ebp, dic);
3002       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3003       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3004       change++;
3005     }
3006
3007   return change;
3008 }
3009
3010 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3011
3012
3013 /*-----------------------------------------------------------------*/
3014 /* packRegsForOneuse : - will reduce some registers for single Use */
3015 /*-----------------------------------------------------------------*/
3016 static iCode *
3017 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3018 {
3019   bitVect *uses;
3020   iCode *dic, *sic;
3021
3022   debugLog ("%s\n", __FUNCTION__);
3023   /* if returning a literal then do nothing */
3024   if (!IS_SYMOP (op))
3025     return NULL;
3026
3027   /* only upto 2 bytes since we cannot predict
3028      the usage of b, & acc */
3029   if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3030       ic->op != RETURN &&
3031       ic->op != SEND)
3032     return NULL;
3033
3034   /* this routine will mark the a symbol as used in one 
3035      instruction use only && if the definition is local 
3036      (ie. within the basic block) && has only one definition &&
3037      that definition is either a return value from a 
3038      function or does not contain any variables in
3039      far space */
3040   uses = bitVectCopy (OP_USES (op));
3041   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
3042   if (!bitVectIsZero (uses))    /* has other uses */
3043     return NULL;
3044
3045   /* if it has only one defintion */
3046   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3047     return NULL;                /* has more than one definition */
3048
3049   /* get that definition */
3050   if (!(dic =
3051         hTabItemWithKey (iCodehTab,
3052                          bitVectFirstBit (OP_DEFS (op)))))
3053     return NULL;
3054
3055   /* found the definition now check if it is local */
3056   if (dic->seq < ebp->fSeq ||
3057       dic->seq > ebp->lSeq)
3058     return NULL;                /* non-local */
3059
3060   /* now check if it is the return from
3061      a function call */
3062   if (dic->op == CALL || dic->op == PCALL)
3063     {
3064       if (ic->op != SEND && ic->op != RETURN &&
3065           !POINTER_SET(ic) && !POINTER_GET(ic))
3066         {
3067           OP_SYMBOL (op)->ruonly = 1;
3068           return dic;
3069         }
3070       dic = dic->next;
3071     }
3072
3073
3074   /* otherwise check that the definition does
3075      not contain any symbols in far space */
3076   if (isOperandInFarSpace (IC_LEFT (dic)) ||
3077       isOperandInFarSpace (IC_RIGHT (dic)) ||
3078       IS_OP_RUONLY (IC_LEFT (ic)) ||
3079       IS_OP_RUONLY (IC_RIGHT (ic)))
3080     {
3081       return NULL;
3082     }
3083
3084   /* if pointer set then make sure the pointer
3085      is one byte */
3086   if (POINTER_SET (dic) &&
3087       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3088     return NULL;
3089
3090   if (POINTER_GET (dic) &&
3091       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3092     return NULL;
3093
3094   sic = dic;
3095
3096   /* also make sure the intervenening instructions
3097      don't have any thing in far space */
3098   for (dic = dic->next; dic && dic != ic; dic = dic->next)
3099     {
3100
3101       /* if there is an intervening function call then no */
3102       if (dic->op == CALL || dic->op == PCALL)
3103         return NULL;
3104       /* if pointer set then make sure the pointer
3105          is one byte */
3106       if (POINTER_SET (dic) &&
3107           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3108         return NULL;
3109
3110       if (POINTER_GET (dic) &&
3111           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3112         return NULL;
3113
3114       /* if address of & the result is remat then okay */
3115       if (dic->op == ADDRESS_OF &&
3116           OP_SYMBOL (IC_RESULT (dic))->remat)
3117         continue;
3118
3119       /* if operand has size of three or more & this
3120          operation is a '*','/' or '%' then 'b' may
3121          cause a problem */
3122       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3123           getSize (operandType (op)) >= 3)
3124         return NULL;
3125
3126       /* if left or right or result is in far space */
3127       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3128           isOperandInFarSpace (IC_RIGHT (dic)) ||
3129           isOperandInFarSpace (IC_RESULT (dic)) ||
3130           IS_OP_RUONLY (IC_LEFT (dic)) ||
3131           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3132           IS_OP_RUONLY (IC_RESULT (dic)))
3133         {
3134           return NULL;
3135         }
3136     }
3137
3138   OP_SYMBOL (op)->ruonly = 1;
3139   return sic;
3140
3141 }
3142
3143 /*-----------------------------------------------------------------*/
3144 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3145 /*-----------------------------------------------------------------*/
3146 static bool
3147 isBitwiseOptimizable (iCode * ic)
3148 {
3149   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3150   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3151
3152   debugLog ("%s\n", __FUNCTION__);
3153   /* bitwise operations are considered optimizable
3154      under the following conditions (Jean-Louis VERN) 
3155
3156      x & lit
3157      bit & bit
3158      bit & x
3159      bit ^ bit
3160      bit ^ x
3161      x   ^ lit
3162      x   | lit
3163      bit | bit
3164      bit | x
3165    */
3166   if (IS_LITERAL (rtype) ||
3167       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3168     return TRUE;
3169   else
3170     return FALSE;
3171 }
3172
3173 /*-----------------------------------------------------------------*/
3174 /* packRegsForAccUse - pack registers for acc use                  */
3175 /*-----------------------------------------------------------------*/
3176 static void
3177 packRegsForAccUse (iCode * ic)
3178 {
3179   iCode *uic;
3180
3181   debugLog ("%s\n", __FUNCTION__);
3182
3183   /* if this is an aggregate, e.g. a one byte char array */
3184   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3185     return;
3186   }
3187   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3188
3189   /* if + or - then it has to be one byte result */
3190   if ((ic->op == '+' || ic->op == '-')
3191       && getSize (operandType (IC_RESULT (ic))) > 1)
3192     return;
3193
3194   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3195   /* if shift operation make sure right side is not a literal */
3196   if (ic->op == RIGHT_OP &&
3197       (isOperandLiteral (IC_RIGHT (ic)) ||
3198        getSize (operandType (IC_RESULT (ic))) > 1))
3199     return;
3200
3201   if (ic->op == LEFT_OP &&
3202       (isOperandLiteral (IC_RIGHT (ic)) ||
3203        getSize (operandType (IC_RESULT (ic))) > 1))
3204     return;
3205
3206   if (IS_BITWISE_OP (ic) &&
3207       getSize (operandType (IC_RESULT (ic))) > 1)
3208     return;
3209
3210
3211   /* has only one definition */
3212   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3213     return;
3214
3215   /* has only one use */
3216   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3217     return;
3218
3219   /* and the usage immediately follows this iCode */
3220   if (!(uic = hTabItemWithKey (iCodehTab,
3221                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3222     return;
3223
3224   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3225   if (ic->next != uic)
3226     return;
3227
3228   /* if it is a conditional branch then we definitely can */
3229   if (uic->op == IFX)
3230     goto accuse;
3231
3232   if (uic->op == JUMPTABLE)
3233     return;
3234
3235   /* if the usage is not is an assignment
3236      or an arithmetic / bitwise / shift operation then not */
3237   if (POINTER_SET (uic) &&
3238       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3239     return;
3240
3241   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3242   if (uic->op != '=' &&
3243       !IS_ARITHMETIC_OP (uic) &&
3244       !IS_BITWISE_OP (uic) &&
3245       uic->op != LEFT_OP &&
3246       uic->op != RIGHT_OP)
3247     return;
3248
3249   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3250   /* if used in ^ operation then make sure right is not a 
3251      literl */
3252   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3253     return;
3254
3255   /* if shift operation make sure right side is not a literal */
3256   if (uic->op == RIGHT_OP &&
3257       (isOperandLiteral (IC_RIGHT (uic)) ||
3258        getSize (operandType (IC_RESULT (uic))) > 1))
3259     return;
3260
3261   if (uic->op == LEFT_OP &&
3262       (isOperandLiteral (IC_RIGHT (uic)) ||
3263        getSize (operandType (IC_RESULT (uic))) > 1))
3264     return;
3265
3266   /* make sure that the result of this icode is not on the
3267      stack, since acc is used to compute stack offset */
3268   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3269       OP_SYMBOL (IC_RESULT (uic))->onStack)
3270     return;
3271
3272   /* if either one of them in far space then we cannot */
3273   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3274        isOperandInFarSpace (IC_LEFT (uic))) ||
3275       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3276        isOperandInFarSpace (IC_RIGHT (uic))))
3277     return;
3278
3279   /* if the usage has only one operand then we can */
3280   if (IC_LEFT (uic) == NULL ||
3281       IC_RIGHT (uic) == NULL)
3282     goto accuse;
3283
3284   /* make sure this is on the left side if not
3285      a '+' since '+' is commutative */
3286   if (ic->op != '+' &&
3287       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3288     return;
3289
3290   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3291   /* if one of them is a literal then we can */
3292   if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3293         (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3294        (getSize (operandType (IC_RESULT (uic))) <= 1))
3295     {
3296       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3297       return;
3298     }
3299
3300   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3301   /* if the other one is not on stack then we can */
3302   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3303       (IS_ITEMP (IC_RIGHT (uic)) ||
3304        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3305         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3306     goto accuse;
3307
3308   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3309       (IS_ITEMP (IC_LEFT (uic)) ||
3310        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3311         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3312     goto accuse;
3313
3314   return;
3315
3316 accuse:
3317   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3318   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3319
3320
3321 }
3322
3323 /*-----------------------------------------------------------------*/
3324 /* packForPush - hueristics to reduce iCode for pushing            */
3325 /*-----------------------------------------------------------------*/
3326 static void
3327 packForReceive (iCode * ic, eBBlock * ebp)
3328 {
3329   iCode *dic;
3330
3331   debugLog ("%s\n", __FUNCTION__);
3332   debugAopGet ("  result:", IC_RESULT (ic));
3333   debugAopGet ("  left:", IC_LEFT (ic));
3334   debugAopGet ("  right:", IC_RIGHT (ic));
3335
3336   if (!ic->next)
3337     return;
3338
3339   for (dic = ic->next; dic; dic = dic->next)
3340     {
3341
3342
3343
3344       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3345         debugLog ("    used on left\n");
3346       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3347         debugLog ("    used on right\n");
3348       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3349         debugLog ("    used on result\n");
3350
3351       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3352           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3353         return;
3354
3355     }
3356
3357   debugLog ("  hey we can remove this unnecessary assign\n");
3358 }
3359 /*-----------------------------------------------------------------*/
3360 /* packForPush - hueristics to reduce iCode for pushing            */
3361 /*-----------------------------------------------------------------*/
3362 static void
3363 packForPush (iCode * ic, eBBlock * ebp)
3364 {
3365   iCode *dic;
3366
3367   debugLog ("%s\n", __FUNCTION__);
3368   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3369     return;
3370
3371   /* must have only definition & one usage */
3372   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3373       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3374     return;
3375
3376   /* find the definition */
3377   if (!(dic = hTabItemWithKey (iCodehTab,
3378                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3379     return;
3380
3381   if (dic->op != '=' || POINTER_SET (dic))
3382     return;
3383
3384   /* we now we know that it has one & only one def & use
3385      and the that the definition is an assignment */
3386   IC_LEFT (ic) = IC_RIGHT (dic);
3387
3388   remiCodeFromeBBlock (ebp, dic);
3389   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3390   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3391 }
3392
3393 static void printSymType(char * str, sym_link *sl)
3394 {
3395   debugLog ("    %s Symbol type: ",str);
3396   printTypeChain( sl, debugF);
3397   debugLog ("\n");
3398
3399 }
3400
3401 /*-----------------------------------------------------------------*/
3402 /* some debug code to print the symbol S_TYPE. Note that
3403  * the function checkSClass in src/SDCCsymt.c dinks with
3404  * the S_TYPE in ways the PIC port doesn't fully like...*/
3405 /*-----------------------------------------------------------------*/
3406 static void isData(sym_link *sl)
3407 {
3408   FILE *of = stderr;
3409
3410   if(!sl)
3411     return;
3412
3413   if(debugF)
3414     of = debugF;
3415
3416   for ( ; sl; sl=sl->next) {
3417     if(!IS_DECL(sl) ) {
3418       switch (SPEC_SCLS(sl)) {
3419         
3420       case S_DATA: fprintf (of, "data "); break;
3421       case S_XDATA: fprintf (of, "xdata "); break;
3422       case S_SFR: fprintf (of, "sfr "); break;
3423       case S_SBIT: fprintf (of, "sbit "); break;
3424       case S_CODE: fprintf (of, "code "); break;
3425       case S_IDATA: fprintf (of, "idata "); break;
3426       case S_PDATA: fprintf (of, "pdata "); break;
3427       case S_LITERAL: fprintf (of, "literal "); break;
3428       case S_STACK: fprintf (of, "stack "); break;
3429       case S_XSTACK: fprintf (of, "xstack "); break;
3430       case S_BIT: fprintf (of, "bit "); break;
3431       case S_EEPROM: fprintf (of, "eeprom "); break;
3432       default: break;
3433       }
3434
3435     }
3436
3437   }
3438     
3439 }
3440 /*-----------------------------------------------------------------*/
3441 /* packRegisters - does some transformations to reduce register    */
3442 /*                   pressure                                      */
3443 /*-----------------------------------------------------------------*/
3444 static void
3445 packRegisters (eBBlock * ebp)
3446 {
3447   iCode *ic;
3448   int change = 0;
3449
3450   debugLog ("%s\n", __FUNCTION__);
3451
3452   while (1) {
3453
3454     change = 0;
3455
3456     /* look for assignments of the form */
3457     /* iTempNN = TRueSym (someoperation) SomeOperand */
3458     /*       ....                       */
3459     /* TrueSym := iTempNN:1             */
3460     for (ic = ebp->sch; ic; ic = ic->next)
3461       {
3462
3463         /* find assignment of the form TrueSym := iTempNN:1 */
3464         if (ic->op == '=' && !POINTER_SET (ic))
3465           change += packRegsForAssign (ic, ebp);
3466         /* debug stuff */
3467         if (ic->op == '=')
3468           {
3469             if (POINTER_SET (ic))
3470               debugLog ("pointer is set\n");
3471             debugAopGet ("  result:", IC_RESULT (ic));
3472             debugAopGet ("  left:", IC_LEFT (ic));
3473             debugAopGet ("  right:", IC_RIGHT (ic));
3474           }
3475
3476       }
3477
3478     if (!change)
3479       break;
3480   }
3481
3482   for (ic = ebp->sch; ic; ic = ic->next) {
3483
3484     if(IS_SYMOP ( IC_LEFT(ic))) {
3485       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3486
3487       debugAopGet ("  left:", IC_LEFT (ic));
3488       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3489         debugLog ("    is a pointer\n");
3490
3491       if(IS_OP_VOLATILE(IC_LEFT(ic)))
3492         debugLog ("    is volatile\n");
3493
3494       isData(etype);
3495
3496       printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3497     }
3498
3499     if(IS_SYMOP ( IC_RIGHT(ic))) {
3500       debugAopGet ("  right:", IC_RIGHT (ic));
3501       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3502     }
3503
3504     if(IS_SYMOP ( IC_RESULT(ic))) {
3505       debugAopGet ("  result:", IC_RESULT (ic));
3506       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3507     }
3508
3509     if (POINTER_SET (ic))
3510         debugLog ("  %d - Pointer set\n", __LINE__);
3511
3512
3513     /* if this is an itemp & result of a address of a true sym 
3514        then mark this as rematerialisable   */
3515     if (ic->op == ADDRESS_OF &&
3516         IS_ITEMP (IC_RESULT (ic)) &&
3517         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3518         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3519         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3520       {
3521
3522         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3523
3524         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3525         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3526         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3527
3528       }
3529
3530     /* if straight assignment then carry remat flag if
3531        this is the only definition */
3532     if (ic->op == '=' &&
3533         !POINTER_SET (ic) &&
3534         IS_SYMOP (IC_RIGHT (ic)) &&
3535         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3536         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3537       {
3538         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3539
3540         OP_SYMBOL (IC_RESULT (ic))->remat =
3541           OP_SYMBOL (IC_RIGHT (ic))->remat;
3542         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3543           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3544       }
3545
3546     /* if this is a +/- operation with a rematerizable 
3547        then mark this as rematerializable as well */
3548     if ((ic->op == '+' || ic->op == '-') &&
3549         (IS_SYMOP (IC_LEFT (ic)) &&
3550          IS_ITEMP (IC_RESULT (ic)) &&
3551          OP_SYMBOL (IC_LEFT (ic))->remat &&
3552          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3553          IS_OP_LITERAL (IC_RIGHT (ic))))
3554       {
3555         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3556         //int i = 
3557         operandLitValue (IC_RIGHT (ic));
3558         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3559         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3560         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3561       }
3562
3563     /* mark the pointer usages */
3564     if (POINTER_SET (ic))
3565       {
3566         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3567         debugLog ("  marking as a pointer (set) =>");
3568         debugAopGet ("  result:", IC_RESULT (ic));
3569       }
3570     if (POINTER_GET (ic))
3571       {
3572         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3573         debugLog ("  marking as a pointer (get) =>");
3574         debugAopGet ("  left:", IC_LEFT (ic));
3575       }
3576
3577     if (!SKIP_IC2 (ic))
3578       {
3579         /* if we are using a symbol on the stack
3580            then we should say pic16_ptrRegReq */
3581         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3582           pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3583                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3584         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3585           pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3586                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3587         else
3588           {
3589             if (IS_SYMOP (IC_LEFT (ic)))
3590               pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3591                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3592             if (IS_SYMOP (IC_RIGHT (ic)))
3593               pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3594                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3595             if (IS_SYMOP (IC_RESULT (ic)))
3596               pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3597                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3598           }
3599
3600         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3601
3602       }
3603
3604     /* if the condition of an if instruction
3605        is defined in the previous instruction then
3606        mark the itemp as a conditional */
3607     if ((IS_CONDITIONAL (ic) ||
3608          ((ic->op == BITWISEAND ||
3609            ic->op == '|' ||
3610            ic->op == '^') &&
3611           isBitwiseOptimizable (ic))) &&
3612         ic->next && ic->next->op == IFX &&
3613         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3614         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3615       {
3616
3617         debugLog ("  %d\n", __LINE__);
3618         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3619         continue;
3620       }
3621
3622     /* reduce for support function calls */
3623     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3624       packRegsForSupport (ic, ebp);
3625
3626     /* if a parameter is passed, it's in W, so we may not
3627        need to place a copy in a register */
3628     if (ic->op == RECEIVE)
3629       packForReceive (ic, ebp);
3630
3631     /* some cases the redundant moves can
3632        can be eliminated for return statements */
3633     if ((ic->op == RETURN || ic->op == SEND) &&
3634         !isOperandInFarSpace (IC_LEFT (ic)) &&
3635         !options.model)
3636       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3637
3638     /* if pointer set & left has a size more than
3639        one and right is not in far space */
3640     if (POINTER_SET (ic) &&
3641         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3642         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3643         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3644         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3645
3646       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3647
3648     /* if pointer get */
3649     if (POINTER_GET (ic) &&
3650         !isOperandInFarSpace (IC_RESULT (ic)) &&
3651         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3652         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3653         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3654
3655       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3656
3657
3658     /* if this is cast for intergral promotion then
3659        check if only use of  the definition of the 
3660        operand being casted/ if yes then replace
3661        the result of that arithmetic operation with 
3662        this result and get rid of the cast */
3663     if (ic->op == CAST) {
3664         
3665       sym_link *fromType = operandType (IC_RIGHT (ic));
3666       sym_link *toType = operandType (IC_LEFT (ic));
3667
3668       debugLog ("  %d - casting\n", __LINE__);
3669
3670       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3671           getSize (fromType) != getSize (toType)) {
3672             
3673
3674         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3675         if (dic) {
3676                 
3677           if (IS_ARITHMETIC_OP (dic)) {
3678                     
3679             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3680             IC_RESULT (dic) = IC_RESULT (ic);
3681             remiCodeFromeBBlock (ebp, ic);
3682             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3683             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3684             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3685             ic = ic->prev;
3686           }  else
3687                 
3688             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3689         }
3690       } else {
3691
3692         /* if the type from and type to are the same
3693            then if this is the only use then packit */
3694         if (compareType (operandType (IC_RIGHT (ic)),
3695                          operandType (IC_LEFT (ic))) == 1) {
3696                 
3697           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3698           if (dic) {
3699                     
3700             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3701             IC_RESULT (dic) = IC_RESULT (ic);
3702             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3703             remiCodeFromeBBlock (ebp, ic);
3704             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3705             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3706             ic = ic->prev;
3707           }
3708         }
3709       }
3710     }
3711
3712     /* pack for PUSH 
3713        iTempNN := (some variable in farspace) V1
3714        push iTempNN ;
3715        -------------
3716        push V1
3717     */
3718     if (ic->op == IPUSH)
3719       {
3720         packForPush (ic, ebp);
3721       }
3722
3723
3724     /* pack registers for accumulator use, when the
3725        result of an arithmetic or bit wise operation
3726        has only one use, that use is immediately following
3727        the defintion and the using iCode has only one
3728        operand or has two operands but one is literal &
3729        the result of that operation is not on stack then
3730        we can leave the result of this operation in acc:b
3731        combination */
3732     if ((IS_ARITHMETIC_OP (ic)
3733
3734          || IS_BITWISE_OP (ic)
3735
3736          || ic->op == LEFT_OP || ic->op == RIGHT_OP
3737
3738          ) &&
3739         IS_ITEMP (IC_RESULT (ic)) &&
3740         getSize (operandType (IC_RESULT (ic))) <= 2)
3741
3742       packRegsForAccUse (ic);
3743
3744   }
3745 }
3746
3747 static void
3748 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3749 {
3750   int i;
3751
3752   if (!debug || !debugF)
3753     return;
3754
3755   for (i = 0; i < count; i++)
3756     {
3757       fprintf (debugF, "\n----------------------------------------------------------------\n");
3758       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3759                ebbs[i]->entryLabel->name,
3760                ebbs[i]->depth,
3761                ebbs[i]->noPath,
3762                ebbs[i]->isLastInLoop);
3763       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3764                ebbs[i]->dfnum,
3765                ebbs[i]->bbnum,
3766                ebbs[i]->fSeq,
3767                ebbs[i]->lSeq);
3768       fprintf (debugF, "visited %d : hasFcall = %d\n",
3769                ebbs[i]->visited,
3770                ebbs[i]->hasFcall);
3771
3772       fprintf (debugF, "\ndefines bitVector :");
3773       bitVectDebugOn (ebbs[i]->defSet, debugF);
3774       fprintf (debugF, "\nlocal defines bitVector :");
3775       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3776       fprintf (debugF, "\npointers Set bitvector :");
3777       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3778       fprintf (debugF, "\nin pointers Set bitvector :");
3779       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3780       fprintf (debugF, "\ninDefs Set bitvector :");
3781       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3782       fprintf (debugF, "\noutDefs Set bitvector :");
3783       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3784       fprintf (debugF, "\nusesDefs Set bitvector :");
3785       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3786       fprintf (debugF, "\n----------------------------------------------------------------\n");
3787       printiCChain (ebbs[i]->sch, debugF);
3788     }
3789 }
3790 /*-----------------------------------------------------------------*/
3791 /* pic16_assignRegisters - assigns registers to each live range as need  */
3792 /*-----------------------------------------------------------------*/
3793 void
3794 pic16_assignRegisters (eBBlock ** ebbs, int count)
3795 {
3796   iCode *ic;
3797   int i;
3798
3799   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3800   debugLog ("\nebbs before optimizing:\n");
3801   dumpEbbsToDebug (ebbs, count);
3802
3803   setToNull ((void *) &_G.funcrUsed);
3804   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3805
3806
3807   /* change assignments this will remove some
3808      live ranges reducing some register pressure */
3809   for (i = 0; i < count; i++)
3810     packRegisters (ebbs[i]);
3811
3812   {
3813     regs *reg;
3814     int hkey;
3815     int i=0;
3816
3817     debugLog("dir registers allocated so far:\n");
3818     reg = hTabFirstItem(dynDirectRegNames, &hkey);
3819
3820     while(reg) {
3821       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3822       reg = hTabNextItem(dynDirectRegNames, &hkey);
3823     }
3824
3825   }
3826
3827   if (options.dump_pack)
3828     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3829
3830   /* first determine for each live range the number of 
3831      registers & the type of registers required for each */
3832   regTypeNum ();
3833
3834   /* and serially allocate registers */
3835   serialRegAssign (ebbs, count);
3836
3837   /* if stack was extended then tell the user */
3838   if (_G.stackExtend)
3839     {
3840 /*      werror(W_TOOMANY_SPILS,"stack", */
3841 /*             _G.stackExtend,currFunc->name,""); */
3842       _G.stackExtend = 0;
3843     }
3844
3845   if (_G.dataExtend)
3846     {
3847 /*      werror(W_TOOMANY_SPILS,"data space", */
3848 /*             _G.dataExtend,currFunc->name,""); */
3849       _G.dataExtend = 0;
3850     }
3851
3852   /* after that create the register mask
3853      for each of the instruction */
3854   createRegMask (ebbs, count);
3855
3856   /* redo that offsets for stacked automatic variables */
3857   redoStackOffsets ();
3858
3859   if (options.dump_rassgn)
3860     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3861
3862   /* now get back the chain */
3863   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3864
3865   debugLog ("ebbs after optimizing:\n");
3866   dumpEbbsToDebug (ebbs, count);
3867
3868
3869   genpic16Code (ic);
3870
3871   /* free up any _G.stackSpil locations allocated */
3872   applyToSet (_G.stackSpil, deallocStackSpil);
3873   _G.slocNum = 0;
3874   setToNull ((void **) &_G.stackSpil);
3875   setToNull ((void **) &_G.spiltSet);
3876   /* mark all registers as free */
3877   //pic16_freeAllRegs ();
3878
3879   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3880   debugLogClose ();
3881   return;
3882 }