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