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