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