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