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