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