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