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