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