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