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