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